In the Swift grammar, the top-level of a source file is a mix of three
different kinds of "items": declarations, statements, and expressions.
However, the existing parser forces all of these into declarations at
parse time, wrapping statements and expressions in TopLevelCodeDecls,
so the primary API for getting the top-level entities in source files
is based on getting declarations.
Start generalizing the representation by storing ASTNode instances at
the top level, rather than declaration pointers, updating many (but
not all!) uses of this API. The walk over declarations is a (cached)
filter to pick out all of the declarations. Existing parsed files are
unaffected (the parser still creates top-level code declarations), but
the new "macro expansion" source file kind skips creating top-level
code declarations so we get the pure parse tree. Additionally, some
generalized clients (like ASTScope lookup) will now look at the list
of items, so they'll be able to walk into statements and expressions
without the intervening TopLevelCodeDecl.
Over time, I'd like to phase out `getTopLevelDecls()` entirely,
relying on the new `getTopLevelItems()` for parsed content. We can
introduce TopLevelCodeDecls more lazily for semantic walks.
Introduce a new source file kind to describe source files for macro
expansions, and include the macro expression that they expand. This
establishes a "parent" relationship
Also track every kind of auxiliary source file---whether for macro
expansions or other reasons---that is introduced into a module, adding
an operation that allows us to find the source file that contains a
given source location.
Allow user-defined macros to be loaded from dynamic libraries and evaluated.
- Introduce a _CompilerPluginSupport module installed into the toolchain. Its `_CompilerPlugin` protocol acts as a stable interface between the compiler and user-defined macros.
- Introduce a `-load-plugin-library <path>` attribute which allows users to specify dynamic libraries to be loaded into the compiler.
A macro library must declare a public top-level computed property `public var allMacros: [Any.Type]` and be compiled to a dynamic library. The compiler will call the getter of this property to obtain and register all macros.
Known issues:
- We current do not have a way to strip out unnecessary symbols from the plugin dylib, i.e. produce a plugin library that does not contain SwiftSyntax symbols that will collide with the compiler itself.
- `MacroExpansionExpr`'s type is hard-coded as `(Int, String)`. It should instead be specified by the macro via protocol requirements such as `signature` and `genericSignature`. We need more protocol requirements in `_CompilerPlugin` to handle this.
- `dlopen` is not secure and is only for prototyping use here.
Friend PR: apple/swift-syntax#1022
Introduce an experimental option `BuiltinMacros` that takes the magic
literals (`#file`, `#line`, `#function`, etc.) after type checking and
processes the original source for the expression using the build
syntactic macro system in the swift-syntax library. At present, the
result of expansion is printed to standard output, but it's enough to
verify that we're able to find the corresponding syntax node based on
the C++ AST.
Rework the ASTGen interface to split apart parsing a source file,
turning the top-level declarations from that source file into C++ AST
nodes, and then deallocating that source file. Hold on to the source
file in the C++ SourceFile abstraction so we can query it later if we
need to.
And we will need to.
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`.
When the experimental flag `ParserASTGen` is enabled, the compiler has
ASTGen built, we're not performing code completion, and we're not
parsing SIL... go through the new parser and ASTGen to build the
abstract syntax tree.
Refactors `parseSingleAttrOption()` to create a helper that can parse a single arbitrary `Identifier`. This simplifies the handling of `SwiftNativeObjCRuntimeBaseAttr`, `ObjCRuntimeNameAttr`, and `ProjectedValuePropertyAttr`.
* [SILOptimizer] Add prespecialization for arbitray reference types
* Fix benchmark Package.swift
* Move SimpleArray to utils
* Fix multiple indirect result case
* Remove leftover code from previous attempt
* Fix test after rebase
* Move code to compute type replacements to SpecializedFunction
* Fix ownership when OSSA is enabled
* Fixes after rebase
* Changes after rebasing
* Add feature flag for layout pre-specialization
* Fix pre_specialize-macos.swift
* Add compiler flag to benchmark build
* Fix benchmark SwiftPM flags
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.
This was never the correct way to model this because it drops
the commas in the list. Instead just take the optional trailing
identifier element if we have one.
The old syntax was
@opened("UUID") constraintType
Where constraintType was the right hand side of a conformance requirement.
This would always create an archetype where the interface type was `Self`,
so it couldn't cope with member types of opened existential types.
Member types of opened existential types is now a thing with SE-0309, so
this lack of support prevented writing SIL test cases using this feature.
The new syntax is
@opened("UUID", constraintType) interfaceType
The interfaceType is a type parameter rooted in an implicit `Self`
generic parameter, which is understood to be the underlying type of the
existential.
Fixes rdar://problem/93771238.
Introduce support for parsing declaration attributes that occur within
example:
#if hasAttribute(frozen)
@frozen
#endif
public struct X { ... }
will apply to "frozen" attribute to the struct `X`, but only when the
compiler supports the "frozen" attribute.
Correctly determining whether a particular `#if` block contains
attributes to be associated with the following declaration vs.
starting a new declaration requires arbitrary lookahead. The parser
will ensure that at least one of the branches of the `#if` contains an
attribute, and that none of the branches contains something that does
not fit the attribute grammar, before committing to parsing the `#if`
clause as part of the declaration attributes. This lookahead does
occur at the top level (e.g., in the parsing of top-level declarations
and code), but should only need to scan past the first `#if` line to
the following token in the common case.
Unlike other `#if` when used to wrap statements or declarations, we
make no attempt to record the `#if` not taken anywhere in the AST.
This reflects a change in attitude in the design of the AST, because
we have found that trying to represent this information there (e.g.,
via `IfConfigDecl`) complicates clients while providing little value.
This information is best kept in the syntax tree, only.
[Distributed] generic and inner test; without one edge case
[Distributed] fix distributed_thunk test; unsure about those extra hops, could remove later
[Distributed] Remove type pretending in getSILFunctionType; it is not needed
It seems our constant replacement in the earlier phases is enough, and
we don't need this trick at all.
[Distributed] Use thunk when calling cross-actor on DA protocols
Fix a crash that could occur when performing
completion at the start of an accessor body.
Previously we assumed `CodeCompletion` would never
be null due to function body skipping in the first
pass of code completion. However with the
introduction of the ability to avoid skipping in
certain cases, it might be now be null if we need
to avoid skipping. Found by the stress tester.
rdar://95772803
While skipping, if we encounter a token that looks
like it could be the start of a `/.../` regex
literal, fall back to parsing the function or type
body normally, as such a token could become a
regex literal. As such, it could treat `{` and
`}` as literal, or otherwise have contents that
would be lexically invalid Swift.
To avoid falling back in too many cases, we apply
the existing regex literal heuristics. Cases that
pass the heuristic fall back to regular parsing.
Cases that fail the heuristic are further checked
to make sure they wouldn't contain an unbalanced
`{` or `}`, but otherwise are allowed to be
skipped. This allows us to continue skipping for
most occurrences of infix and prefix `/`.
This is meant as a lower risk workaround to fix the
the issue, we ought to go back to handling regex
literals in the lexer.
Resolves rdar://95354010
Experimental features can only be enabled in non-production (+Asserts)
builds. They can be detected with `hasFeature` in the same manner as
"future" features.
The `-enable-experimental-feature X` flag will also look for future
features by that name, so that when an experimental feature becomes an
accepted future feature, it will still be enabled in the same manner.
Switch variadic generics over to this approach, eliminating the
specific LangOption for it.