Previously, the location used for functions corresponding to @main was
just RegularLocation::getModuleLocation(). Make that more specific by
using the annotated type's location instead.
rdar://79508092
Allow freestanding macros to be used at top-level.
- Parse top-level `#…` as `MacroExpansionDecl` when we are not in scripting mode.
- Add macro expansion decls to the source lookup cache with name-driven lazy expansion. Not supporting arbitrary name yet.
- Experimental support for script mode and brace-level declaration macro expansions: When type-checking a `MacroExpansionExpr`, assign it a substitute `MacroExpansionDecl` if the macro reference resolves to a declaration macro. This doesn’t work quite fully yet and will be enabled in a future fix.
Always use `Decl::visitAuxiliaryDecls` to visit decls produced by macros, including peer macros and declaration macros. Use name-driven expansion for peer macros. Remove `MacroExpansionDecl::getRewritten()`.
Also make `ExpandMacroExpansionDeclRequest` cache the buffer ID (similar to other macros) instead of an array of decls.
Previously, typechecking and SILGen would treat a function body as fragile as long as the declaration had a `@backDeployed` attribute, regardless of the platform specified by the attribute. This was overly conservative since back deployed functions are only emitted into the client on specific platforms. Now a `@backDeployed` function can reference non-`public` declarations on the platforms it is resilient on:
```
@backDeployed(before: iOS 15)
public func foo() {
#if os(iOS)
// Fragile; this code may be emitted into the client.
#else
// Resilient; this code won't ever be exposed to clients.
#endif
}
```
Resolves rdar://105298520
Global peer macro expansions are not injected into the AST. Instead, they
are visited as "auxiliary declarations" when needed, such as in the decl
checker and during SILGen. This is the same mechanism used for local property
wrappers and local lazy variables.
Add support for freestanding declaration macros.
- Parse `@declaration` attribute.
- Type check and expand `MacroExpansionDecl`.
Known issues:
- Generic macros are not yet handled.
- Expansion does not work when the parent decl context is `BraceStmt`. Need to parse freestanding declaration macro expansions in `BraceStmt` as `MacroExpansionDecl`, and add expanded decls to name lookup.
Single expression is not going to cut it in this case because attribute
and attached declaration could have different availability, so we need
to use `if #available` to guard attribute instantiation and return `nil`
in cases where types are not available.
A new `RuntimeAttributeGenerator` is used to reference runtime
attribute generator functions synthesized by SILGen.
`#function` magic literal points to the declaration that declaration
attribute is attached to.
Each entry relates an attribute declaration to a list of all
declarations it's associated with together with a generator
function to acquire instance of the attribute value.
This attribute indicates that the given SILFunction has to be
added to "accessible functions" section and could be looked up
at runtime using a special API.
If the emission of a function is delayed via `emitOrDelayFunction()`, then the function is recorded on a list of delayed functions. If the delayed function is later referenced, then the function moves from the delayed list to the "forced" list which will cause it to actually be emitted later. The implementation of `emitOrDelayFunction()` had a bug when called twice for the same delayable function - it would emit that function prematurely if the function moved to the forced list between the two invocations. Later, during forced function emission a multiple definitions of symbol diagnostic would be emitted since the function was not empty.
This issue could be triggered by `@_backDeploy` functions that have auxilary delayable helper functions (e.g. defer blocks). SILGen visits `@_backDeploy` functions twice (once for the copy of the function emitted into the client and once for the resilient copy of the function) so `emitOrDelayFunction()` is called twice for each of the helper functions and the helper functions could become referenced between the two calls.
The fix is to check for an existing entry in the forced functions list before delaying or emitting a delayable function.
Resolves rdar://102909684
Although the declaration of macros doesn't appear in Swift source code
that uses macros, they still operate as declarations within the
language. Rework `Macro` as `MacroDecl`, a generic value declaration,
which appropriate models its place in the language.
The vast majority of this change is in extending all of the various
switches on declaration kinds to account for macros.
Introduce `MacroExpansionExpr` and `MacroExpansionDecl` and plumb it through. Parse them in roughly the same way we parse `ObjectLiteralExpr`.
The syntax is gated under `-enable-experimental-feature Macros`.
Instead of creating and destroying a SILProfiler
per TopLevelCodeDecl, setup a single profiler
for the top-level entry point function, and visit
all the TopLevelCodeDecls when mapping regions.
Use a main entry-point instead of a null
SILDeclRef. Eventually we'll want to unify the
emission here such that we visit all the
TopLevelDecls in one shot (and just use a single
profiler), but for now we can just hand the
SILProfiler the expected SILDeclRef.
Previously we would delay the emission of
lazy variable getters and stored property
initializers for property wrapper backing storage.
This could lead to their definitions being dropped
if unused, meaning that we wouldn't run the
mandatory diagnostics passes over them.
Fix the logic such that we consider such cases as
having user-written code, and account for a couple
of cases where we can delay emission where we
didn't previously. There are more cases we can
handle here, but I'm leaving that as future work
for now, as `emitOrDelayFunction` is currently
only used for a handful of SILDeclRef kinds.
This is a source breaking change, but only for
invalid (albeit unused) code.
rdar://99962285
Previously we were creating a SILProfiler for
such functions, but weren't actually emitting the
increment, leading to missed coverage.
Part of the fix for rdar://99931619
Specifically, we get an additional table like thing called sil_moveonlydeinit. It looks as follows:
sil_moveonlydeinit TYPE {
@FUNC_NAME
}
It always has a single entry.
Even though with this change we emit the deinit, it isn't used yet since we
still need to implement the move only deinit table/teach the checker how to call
these/teach IRGen how to call this from the destroying value witness.
Stop profiling the deallocating deinitializer
function for non-ObjC classes, and instead profile
the destructor, which is where we emit the user's
code written in a `deinit`.
rdar://54443107
We had two notions of canonical types, one is the structural property
where it doesn't contain sugared types, the other one where it does
not contain reducible type parameters with respect to a generic
signature.
Rename the second one to a 'reduced type'.
This strategy is used to dispatch accesses to 'distributed' computed
property to distributed thunk accessor instead of a regular getter
when access happen outside actor isolation context.
The function prologue of async funclets inherits its source location
from the hop_to_executor instruction. This makes it easier to produce
logical backtraces, since the PC in logical frames will always point
to the start if the function.
rdar://89776340
TypeConverter doesn't know by itself what SILModule it's currently lowering on
behalf of, so the existing code forming the TypeExpansionContext for opaque types
incorrectly set the isWholeModule flag to always false. This created a miscompile
when a public API contained a closure that captured a value involving private types
from another file in the same module because of mismatched type expansion contexts
inside and outside the closure. Fixes rdar://93821679