Macro expansion scope ranges are in terms of characters, so the end of the
insertion range is one past the last character of the insertion range. If
the last character in the insertion range is also the last character in
the enclosing scope, we would build the scope tree incorrectly.
Adjust the position for scope creation to the last character in the
insertion range, not one past it. Fixes rdar://120559184.
Both `try?` and `try!` are catch nodes, because they catch an error
thrown in their subexpression and handle it. Introduce an ASTScope for
all `try/try?/try1` expressions so we can find them, and model them as
catch nodes.
Fixes rdar://119216455.
The ASTScope class hierarchy rooted at ASTScopeImpl is relying entirely
on overridden virtual functions and, in some cases, string comparisons
on the class name, to provide customization for the various classes.
Introduce proper LLVM dynamic casting support to this class hierarchy,
eliminating the string comparisons and the manually-specified
implementations of `getClassName` (which is now used only for printing).
We've been meaning to do this for years, but today I got angry enough.
Preamble macros introduce code at the beginning of a function body.
Allow them to introduce declarations as well, so long as the macro
declaration properly declares the names it introduces. This allows all
sorts of exciting macros that introduce (e.g.) new local variables
that one can use.
Implement type checking support for preamble macros, which expands the
preamble macros and introduces them at the beginning of the function
body prior to type checking. Ensure that the resulting function bodies
type-check properly, including when composing multiple preamble macros
and with a preamble macro applied to the body of a function that
itself came from a body macro.
Function body macros allow one to introduce a function body for a
particular function, either providing a body for a function that
doesn't have one, or wholesale replacing the body of a function that
was written with a new one.
These allow multi-statement `if`/`switch` expression
branches that can produce a value at the end by
saying `then <expr>`. This is gated behind
`-enable-experimental-feature ThenStatements`
pending evolution discussion.
Addresses recently discovered performance regression.
`findChildContaining` has to handle macros and for that
it needs a parent module, looking it up every time is
expensive because it involves walking up back to a source
file scope.
Resolves: rdar://114667408
Resolves: rdar://114667496
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".
I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
so that it can represent the scope for any custom attribute and its arguments.
This commit is NFC, but CustomAttributeScope is now applicable to attached macros.
Previously we could miss the scopes present in
if/switch expressions if they were nested in
another expression, such as an AssignExpr. Fix
the logic such that we properly walk over a given
expression looking for if/switch scopes, the same
as what we do for closures.
rdar://109192116
SE-390 concluded with choosing the keyword discard rather than forget for
the statement that disables the deinit of a noncopyable type. This commit
adds parsing support for `discard self` and adds a deprecation warning for
`_forget self`.
rdar://108859077
Peer macro produce declarations that are semantically alongside the
declaration to which the macro is attached. However, the source
location used for constructing the scope tree was based on the
attribute itself, which meant it was inside the scope of the
declaration to which the macro was attached. This lead to incorrect
unqualified name lookup; in the example that's now a test case, this
meant that the `Self` of the protocol to which the macro was attached
was visible from within the peer declaration. Hilarity (in the form of
a type checker crash) ensued.
Fix the location used for constructing the scope tree of peer macros to
be right after the attached declaration. Fixes rdar://107228586.
Teach ASTScope to create child nodes for each of the arguments of a
macro expansion declaration, so that we can perform name lookup into
them. Otherwise, we cannot have nontrivial closures in arguments to a
macro expansion declaration.
Fixes rdar://107388151.
Currently, this is staged in as `_forget`,
as part of SE-390. It can only be used on
`self` for a move-only type within a consuming
method or accessor. There are other rules, see
Sema for the details.
A `forget self` really just consumes self and
performs memberwise destruction of its data.
Thus, the current expansion of this statement
just reuses what we inject into the end of a
deinit.
Parsing of `forget` is "contextual".
By contextual I mean that we do lookahead to
the next token and see if it's identifier-like.
If so, then we parse it as the `forget` statement.
Otherwise, we parse it as though "forget" is an
identifier as part of some expression.
This way, we won't introduce a source break for
people who wrote code that calls a forget
function.
This should make it seamless to change it from
`_forget` to `forget` in the future.
resolves rdar://105795731
Provide ASTWalker with a customization point to specify whether to
check macro arguments (which are type checked but never emitted), the
macro expansion (which is the result of applying the macro and is
actually emitted into the source), or both. Provide answers for the
~115 different ASTWalker visitors throughout the code base.
Fixes rdar://104042945, which concerns checking of effects in
macro arguments---which we shouldn't do.
Introduce SingleValueStmtExpr, which allows the
embedding of a statement in an expression context.
This then allows us to parse and type-check `if`
and `switch` statements as expressions, gated
behind the `IfSwitchExpression` experimental
feature for now. In the future,
SingleValueStmtExpr could also be used for e.g
`do` expressions.
For now, only single expression branches are
supported for producing a value from an
`if`/`switch` expression, and each branch is
type-checked independently. A multi-statement
branch may only appear if it ends with a `throw`,
and it may not `break`, `continue`, or `return`.
The placement of `if`/`switch` expressions is also
currently limited by a syntactic use diagnostic.
Currently they're only allowed in bindings,
assignments, throws, and returns. But this could
be lifted in the future if desired.
Once an accessor macro has produced accessors, parse them and wire them
into the AST so the rest of the compiler will see them. First
end-to-end test case!
Establish the relationship for generated sources, whether for macro
expansions or (via a small stretch) replacing function bodies with
other bodies, in the source manager itself. This makes the information
available for diagnostic rendering, and unifies a little bit of the
representation, although it isn't used for much yet.
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`
The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.
rdar://102362022
getPotentiallyOpaqueGenericParams has a redundant call to check if
declarations contain any opaque type representations. We don't need
to check this here. Instead we can simply collect the result type
representaions without the additional checks.
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.
Teach ASTScope how to reason about macro expansions. When we create an
ASTScope for a source file that represents a macro expansion, its
parent scope node is the macro expansion itself. When performing
unqualified lookup (of any form), find the starting source file based
on the location, not on the source file provided---this ensures that
we start lookups within the macro expansion (for example).
The effect of this is to enable macro expansions to work in nested
contexts, where they refer to names in the scope in which the macro is
expanded.
This is decidedly unhiegenic, but it fits with our syntactic model.
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 `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`.
Replace the use of bool and pointer returns for
`walkToXXXPre`/`walkToXXXPost`, and instead use
explicit actions such as `Action::Continue(E)`,
`Action::SkipChildren(E)`, and `Action::Stop()`.
There are also conditional variants, e.g
`Action::SkipChildrenIf`, `Action::VisitChildrenIf`,
and `Action::StopIf`.
There is still more work that can be done here, in
particular:
- SourceEntityWalker still needs to be migrated.
- Some uses of `return false` in pre-visitation
methods can likely now be replaced by
`Action::Stop`.
- We still use bool and pointer returns internally
within the ASTWalker traversal, which could likely
be improved.
But I'm leaving those as future work for now as
this patch is already large enough.