The verifier now asserts that Throws, ThrowsLoc and isBodyThrowing()
match up.
Also, add /*Label=*/ comments where necessary to make the long argument
lists easier to read, and cleaned up some inconsistent naming conventions.
I caught a case where ClangImporter where we were passing in a loc as
StaticLoc instead of FuncLoc, but probably this didn't affect anything.
...with a better message than the generic "older version of the
compiler" one, when we know it's actually a different version of
Swift proper.
This still uses the same internal module version numbers to check
if the module is compatible; the presentation of language versions
is a diagnostic thing only.
Speaking of module version numbers, this deliberately does NOT
increment VERSION_MINOR; it's implemented in a backwards-compatible
way.
This will only work going forwards, of course; all existing modules
don't have a short version string, and I don't feel comfortable
assuming all older modules we might encounter are "Swift 2.2".
rdar://problem/25680392
This made call sites confusing to read because it doesn't actually
check if the function already exists.
Also fix some minor formatting issues. This came up while I was working
on a fix for a bug that turned out to not be a bug.
It it now possible to check if a function with a given name and a given linkage exists in one of the modules,
even if the current module contains a function with this name but a difference linkage.
This is useful e.g. for performing a lookup of pre-specializations.
We want to distinguish the special case of a library built with
-sil-serialize-all, from a SIL function that is [fragile] because
of an explicitly @_transparent or @inline(__always).
For now, NFC.
Also, mark witness thunks for [fragile] witnesses as [fragile].
This allows us to serialize the witness table, as well as any thunks
for witnesses declared @_transparent and @inline(__always).
If a thunk is referenced from two different functions, the thunk inherits
the fragile attribute from the first function that forced it to be emitted.
This is wrong, in case the first function might not be fragile, while
the second one is. Copying the fragile attribute to an existing thunk when
checking if it has already been emitted is also wrong, because the thunk
might reference another thunk, and so on.
The correct fix is to have SIL serialization serialize the transitive
closure of all fragile functions and thunks referenced from fragile
functions. Re-work SIL function serialization to use a worklist so that
we can do this.
Part of https://bugs.swift.org/browse/SR-267.
This was mistakenly reverted in an attempt to fix buildbots.
Unfortunately it's now smashed into one commit.
---
Introduce @_specialize(<type list>) internal attribute.
This attribute can be attached to generic functions. The attribute's
arguments must be a list of concrete types to be substituted in the
function's generic signature. Any number of specializations may be
associated with a generic function.
This attribute provides a hint to the compiler. At -O, the compiler
will generate the specified specializations and emit calls to the
specialized code in the original generic function guarded by type
checks.
The current attribute is designed to be an internal tool for
performance experimentation. It does not affect the language or
API. This work may be extended in the future to add user-visible
attributes that do provide API guarantees and/or direct dispatch to
specialized code.
This attribute works on any generic function: a freestanding function
with generic type parameters, a nongeneric method declared in a
generic class, a generic method in a nongeneric class or a generic
method in a generic class. A function's generic signature is a
concatenation of the generic context and the function's own generic
type parameters.
e.g.
struct S<T> {
var x: T
@_specialize(Int, Float)
mutating func exchangeSecond<U>(u: U, _ t: T) -> (U, T) {
x = t
return (u, x)
}
}
// Substitutes: <T, U> with <Int, Float> producing:
// S<Int>::exchangeSecond<Float>(u: Float, t: Int) -> (Float, Int)
---
[SILOptimizer] Introduce an eager-specializer pass.
This pass finds generic functions with @_specialized attributes and
generates specialized code for the attribute's concrete types. It
inserts type checks and guarded dispatch at the beginning of the
generic function for each specialization. Since we don't currently
expose this attribute as API and don't specialize vtables and witness
tables yet, the only way to reach the specialized code is by calling
the generic function which performs the guarded dispatch.
In the future, we can build on this work in several ways:
- cross module dispatch directly to specialized code
- dynamic dispatch directly to specialized code
- automated specialization based on less specific hints
- partial specialization
- and so on...
I reorganized and refactored the optimizer's generic utilities to
support direct function specialization as opposed to apply
specialization.
Temporarily reverting @_specialize because stdlib unit tests are
failing on an internal branch during deserialization.
This reverts commit e2c43cfe14, reversing
changes made to 9078011f93.
This attribute can be attached to generic functions. The attribute's
arguments must be a list of concrete types to be substituted in the
function's generic signature. Any number of specializations may be
associated with a generic function.
This attribute provides a hint to the compiler. At -O, the compiler
will generate the specified specializations and emit calls to the
specialized code in the original generic function guarded by type
checks.
The current attribute is designed to be an internal tool for
performance experimentation. It does not affect the language or
API. This work may be extended in the future to add user-visible
attributes that do provide API guarantees and/or direct dispatch to
specialized code.
This attribute works on any generic function: a freestanding function
with generic type parameters, a nongeneric method declared in a
generic class, a generic method in a nongeneric class or a generic
method in a generic class. A function's generic signature is a
concatenation of the generic context and the function's own generic
type parameters.
e.g.
struct S<T> {
var x: T
@_specialize(Int, Float)
mutating func exchangeSecond<U>(u: U, _ t: T) -> (U, T) {
x = t
return (u, x)
}
}
// Substitutes: <T, U> with <Int, Float> producing:
// S<Int>::exchangeSecond<Float>(u: Float, t: Int) -> (Float, Int)
Let's say I am a good citizen and document my private symbols:
/** My TOP SECRET DOCUMENTATION */
private class Foo {
}
When I go to distribute the compiled binary, I find out my private
documentation is distributed as well:
$ swiftc test.swift -emit-module -module-name "test"
$ strings test.swiftdoc
My TOP SECRET DOCUMENTATION
/** My TOP SECRET DOCUMENTATION */
If a client can't use a symbol (e.g. it's private [or internal and not
-enable-testing]) don't emit the documentation for a symbol in the
swiftdoc.
Fixes: SR-762, rdar://21453624
The test coverage implements this truth table:
| visibility | -enable-testing | documentation? |
|------------|-----------------|----------------|
| private | no | ❌ |
| internal | no | ❌ |
| public | no | ✅ |
| private | yes | ❌ |
| internal | yes | ✅ |
| public | yes | ✅ |
Modified the existing comments test coverage to expect non-public
documentation not to be emitted.
Don't rely on existing comment structure
Refuse to emit comments if the decl cannot actually have one. To
accomplish this, we move `canHaveComment` into the Decl instance. It
must also be marked `const`, since one of its existing usages operates
on a const pointer.
Perform fewer checks when serializing the standard library.
It appears we were only using this to see if an associated type was
derived or defaulted. This code didn't mesh well with the other stuff
I was doing for default implementations, so I'd rather rip it out and
just rely on calling 'isImplicit' to check for derived associated
types instead.
Note that there's a small change of behavior -- if an associated type
is derived for one conformance, and then used as a witness in another,
we were previously only marking it as defaulted in the first one,
but now it is marked as defaulted in both. I do not believe this has
any meaningful consequences.
We did not serialize them because getting USR for extensions is tricky (USRs are
usually for value decls). This commit starts to make up an USR for an extension by combining
the extended nominal's USR with the USR of the first value member of the extension. We use
this made-up USR to associate doc comments when (de)serializing them.
There's an immediate need for this in the core libs, and we have most of the necessary pieces on hand to make it easy to implement. This is an unpolished initial implementation, with the following limitations, among others:
- It doesn't support bridging error conventions,
- It relies on ObjC interop,
- It doesn't check for symbol name collisions,
- It has an underscored name with required symbol name `@cdecl("symbol_name")`, awaiting official bikeshed painting.
This instruction creates a "virtual" address to represent a property with a behavior that supports definite initialization. The instruction holds references to functions that perform the initialization and 'set' logic for the property. It will be DI's job to rewrite assignments into this virtual address into calls to the initializer or setter based on the initialization state of the property at the time of assignment.
Only declarations of whitelisted pre-specializations from with public linkage need
to be serialized as they will be used by UsePrespecializations pass during -Onone
compilations to check for availability of concrete pre-specializations.
The bodies of these functions are not required as they cannot be used anyways,
because they may refer to symbols with non-public linkage.