Commit Graph

128 Commits

Author SHA1 Message Date
Hamish Knight
84befd43ab [AST] Make case body variables for CaseStmt non-optional
We don't really care about the distinction between empty and nil here.
2025-09-09 13:48:40 +01:00
Hamish Knight
b8ab2c048b [ASTScope] Match parent scopes in lookupCatchNode for brace stmts
Rather than looking for a given BraceStmtScope child for a particular
catch node, check whether the given catch node is the parent of the
innermost BraceStmtScope we've found, looking through an intermediate
source file if needed. This ensures it works correctly when the
BraceStmtScope is in a macro expansion.

rdar://149036108
2025-04-19 21:11:22 +01:00
Becca Royal-Gordon
08e2a4ddae Type check ABI decls
Sema now type-checks the alternate ABI-providing decls inside of @abi attributes.

Making this work—particularly, making redeclaration checking work—required making name lookup aware of ABI decls. Name lookup now evaluates both API-providing and ABI-providing declarations. In most cases, it will filter ABI-only decls out unless a specific flag is passed, in which case it will filter API-only decls out instead. Calls that simply retrieve a list of declarations, like `IterableDeclContext::getMembers()` and friends, typically only return API-providing decls; you have to access the ABI-providing ones through those.

As part of that work, I have also added some basic compiler interfaces for working with the API-providing and ABI-providing variants. `ABIRole` encodes whether a declaration provides only API, only ABI, or both, and `ABIRoleInfo` combines that with a pointer to the counterpart providing the other role (for a declaration that provides both, that’ll just be a pointer to `this`).

Decl checking of behavior specific to @abi will come in a future commit.

Note that this probably doesn’t properly exercise some of the new code (ASTScope::lookupEnclosingABIAttributeScope(), for instance); I expect that to happen only once we can rename types using an @abi attribute, since that will create distinguishable behavior differences when resolving TypeReprs in other @abi attributes.
2024-12-19 15:49:34 -08:00
Doug Gregor
11ed132614 [Clang importer + macros] Handle name lookup and type checking for expanded macros
Introduce a number of fixes to allow us to fully use declarations that
are produced by applying a peer macro to an imported declarations.
These changes include:
* Ensuring that we have the right set of imports in the source file
containing the macro expansion, because it depends only on the module
it comes from
* Ensuring that name lookup looks in that file even when the
DeclContext hierarchy doesn't contain the source file (because it's
based on the Clang module structure)

Expand testing to be sure that we're getting the right calls,
diagnostics, and generated IR symbols.
2024-11-13 21:21:56 -08:00
Slava Pestov
e026700ea0 AST: Refactor unqualified lookup a little bit 2024-03-16 08:34:42 -04:00
Hamish Knight
47f7a31095 [AST] Tighten up type of InitContext
Switch from promising a DeclContext to a
PatternBindingInitializer.

This has a couple of benefits:
- It eliminates a few places where we were force
`cast`'ing to PatternBindingInitializer.
- It improves the clarity of what's being stored,
it's not whatever the parent context of the
initializer is, it's specifically the
PatternBindingInitializer context if it exists.
2024-01-17 16:02:33 +00:00
Doug Gregor
8912d4aa71 [SE-0413] Adopt typed throws in withoutActuallyEscaping(_:do:)
There is a small bug fix here in the identification of the catch node,
where the leading `{` of a closure was considered to be "inside" the
closure for code like

    { ... }()

causing us to assume that the call to the closure would catch the error
within the closure.

Other than that, introduce the thrown error type into the type checker's
modeling of `withoutActuallyEscaping(_:do:)`, and mirror that in the
library declaration.
2024-01-13 21:57:24 -08:00
Doug Gregor
05a4a822ba Tighten CatchNode from an AbstractClosureExpr to a ClosureExpr.
Only real closures can have thrown error types, so we can use the
tighter bound for closures and simplify various CatchNode operations.
2023-12-12 22:30:18 -08:00
Doug Gregor
49b05cec84 [Typed throws] Make try? and try! into catch nodes
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.
2023-12-06 15:00:58 -08:00
Doug Gregor
ab90d09f7b [ASTScope] Eliminate getDeclAttributeIfAny().
We only used this in one place, and then immediately filtered down
to a `CustomAttr`. Just use `dyn_cast` in the obvious way and remove
this function.
2023-12-06 13:26:34 -08:00
Doug Gregor
5c2171ca18 [ASTScope] Eliminate ASTScopeImpl::getCatchNodeBody() and centralize
The implementation of "lookup the catch node" is scattered throughout
various `ASTScopeImpl` subclasses. Remove that, and instead centralize
the code to find the innermost catch scope.
2023-12-06 13:14:52 -08:00
Doug Gregor
a2aed2af7b [ASTScope] Replace six virtual functions + overrides with switches
Replace a number of virtual query functions like `getDeclIfAny`, which had
to be overridden at various points in the hierarchy, with simpler
implementations based on the scope kind and `dyn_cast`.
Macro-metaprogram whether each scope node is associated with a
particular declaration/statement/expression/attribute so these
implementations can be efficiently macro-metaprogrammed.
2023-12-06 10:24:11 -08:00
Doug Gregor
1e20686d12 [ASTScope] Introduce isa/cast/dyn_cast support to ASTScope hierarchy
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.
2023-12-06 09:43:21 -08:00
Doug Gregor
79e31a87b3 Re-implement ASTScope's child-insertion assertions
ASTScope assertions that a new child node inserted into its parent list
is after all other child nodes in the source, which included some bespoke
code for dealing with macro expansions. Replace this bespoke code with
uses of the newer SourceManager operations that check ordering of
source locations in a manner that respects macro expansions.
2023-11-30 10:54:42 -08:00
Doug Gregor
37ed49e0bd Implement ordering of source locations that accounts for macro expansion
SourceManager's `isBeforeInBuffer` in buffer takes two source locations
that are assumed to be within the same source buffer and determines
whether the first precedes the second. However, due to macro
expansion, there can be source locations in different source buffers
that are nonetheless conceptually part of the same source file. For
such cases, `isBeforeInBuffer` will silently produce wrong results.

Extend `SourceManager` with a new `isBefore` operation that determines
whether one source location precedes another in the same conceptual
source file, even if they are in different source buffers that (e.g.)
represent macro expansions within that source file. Also introduce
`isAtOrBefore` to cover the case where the source locations might be
equivalent, which was previously handled via a separate equality check
on the source locations that won't work with macro expansions.

Add caching for the list of accessors of a buffer, so we aren't doing
a full walk up the source-buffer chain ever time we do a comparison of
source locations. LCA is still linear-time, but this eliminates
extraneous hash table lookups along the way.

Over time, we should both move more clients over to these new variants
and introduce more assertions into the old (in-buffer) versions to
catch improper uses of them.
2023-11-30 09:55:56 -08:00
Doug Gregor
c060a90fe0 Generalize the LCA implementation in ASTScope for arbitrary macro nesting
The prior Least Common Ancestor (LCA) implementation in ASTScope, which
is used to search child scopes to find a particular location, assumed
that the source range it was given was contained within a single
buffer and was specific to the child-scope search task. Generalize
this to a more fundamental "is before" operation on source locations
that respects macro expansions, simplifying the code in the process.
2023-11-30 08:28:44 -08:00
Doug Gregor
3dd4df2351 [Typed throws] Location based lookup for the thrown error type
Introduce a new API to find the AST node that catches or rethrows an
error thrown from the given source location. Use it to determine the
thrown error type to use for type checking a `throw` statement, which
begins as `any Error` within a `do..catch` and is later refined.
2023-10-15 22:59:48 -07:00
Karl Wagner
ab4f80ed95 [SE-0404] Allow protocols to be nested in non-generic contexts 2023-10-06 21:04:03 +02:00
Pavel Yaskevich
955e1166d3 [AST] ASTScope: Pass parent module to all search methods
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
2023-08-31 10:08:23 -07:00
Holly Borla
393b4ceb95 [NameLookup] Move macro-related name lookup operations into the namelookup
namespace.

This moves the `isInMacroArgument` predicate and `lookupMacros` into `namelookup`.
ASTScope still encapsulates the scope tree and contains the operation to lookup
the enclosing macro scope, which then invokes a callback to determine whether a
potential macro scope is indeed a macro, because answering this question requires
name lookup.
2023-06-11 23:10:43 -07:00
Holly Borla
0b91f63349 [ASTScope] Don't consider freestanding macro expansions as being part of a
macro argument.
2023-06-11 23:10:43 -07:00
Holly Borla
cd79cf97d6 [ASTScope] Add APIs for determining whether a given source location is inside
a macro argument.
2023-06-11 23:09:47 -07:00
Adrian Prantl
158772c2ab Rebase SILScope generation on top of ASTScope.
This patch replaces the stateful generation of SILScope information in
SILGenFunction with data derived from the ASTScope hierarchy, which should be
100% in sync with the scopes needed for local variables. The goal is to
eliminate the surprising effects that the stack of cleanup operations can have
on the current state of SILBuilder leading to a fully deterministic (in the
sense of: predictible by a human) association of SILDebugScopes with
SILInstructions. The patch also eliminates the need to many workarounds. There
are still some accomodations for several Sema transformation passes such as
ResultBuilders, which don't correctly update the source locations when moving
around nodes. If these were implemented as macros, this problem would disappear.

This necessary rewrite of the macro scope handling included in this patch also
adds proper support nested macro expansions.

This fixes

rdar://88274783

and either fixes or at least partially addresses the following:

rdar://89252827
rdar://105186946
rdar://105757810
rdar://105997826
rdar://105102288
2023-04-04 15:20:11 -07:00
Doug Gregor
40b332189f [Macros] Fix name lookup of macro parameters in the definition.
This enables macros to be defined in terms of other macros.
2023-03-29 16:32:31 -07:00
Doug Gregor
7ea0e3f096 Switch GeneratedSourceInfo ranges over to CharSourceRange.
Macro expansion buffers, along with other generated source buffers,
need more precise "original source ranges" that can be had with the
token-based `SourceRange`. Switch over to `CharSourceRange` and provide
more thoughtfully-determined original source ranges.
2023-02-11 11:23:26 -08:00
Hamish Knight
a40f1abaff Introduce if/switch expressions
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.
2023-02-01 15:30:18 +00:00
Holly Borla
07319d0fdd [ASTScope] Teach ASTScope lookup to find source locations inside macro-expanded
scopes.

ASTScope lookup can no longer assume that all scopes are within the same source
file. Scope trees can now contain scopes that are in macro expansion buffers, which
live in different source files with independent source ranges from the root of a
given scope tree. To handle this when searching for a scope containing a given source
location, ASTScope lookup needs to walk up the chain of macro expansion buffers to find
the lowest common buffer in which to compare source locations.

This fixes a number of issues with unqualified lookup into and from within macro-expanded
code.
2023-01-25 23:19:33 -08:00
Doug Gregor
b29fcb4e58 [Macros] Parse macro declarations fully, and treat them as normal declarations 2022-11-28 18:32:43 -08:00
Angela Laar
c3d4b3d985 [AST] Namelookup should only look at parsed generic parameters
We want to make sure not to cause a circular reference
by fetching the full generic parameter list when we are
creating opaque paramters and result types.
2022-09-20 15:25:09 -07:00
Doug Gregor
55067ba028 Support named opaque result types for properties.
Add lookup scopes for the generic parameters of a named opaque result
type and clean up the code that finds the opaque substitutions.
2022-01-04 21:14:39 -08:00
Rintaro Ishizaki
7c92a8e555 [SourceKit] Add a request to generate object files in SourceKit
Add 'request.compile'
2021-12-21 14:35:38 -08:00
Robert Widmann
c23a617da2 [NFC] Clean Up Unused Fields in Unqualified Lookup
* Drop some unused fields
* const-qualify a consumption method that is logically const - though it
  isn't physically const given the mutating use in
  ASTScopeDeclConsumerForUnqualifiedLookup::lookInMembers
* Privatize some internal fields
2021-11-05 11:25:15 -07:00
Hamish Knight
c1b1feb8e7 [AST] Clean up CaptureListEntry
Don't store a VarDecl separately, expose a `getVar`
accessor that forwards onto `getSingleVar`, and
rename `Init` to `PBD`.
2021-06-08 22:56:06 +01:00
Slava Pestov
0fa84c14a0 ASTScope: Remove the ExpandASTScopeRequest
This doesn't really fit the request evaluator model since the
result of evaluating the request is the new insertion point,
but we don't have a way to get the insertion point of an
already-expanded scope.

Instead, let's change the callers of the now-removed
expandAndBeCurrentDetectingRecursion() to instead call
expandAndBeCurrent(), while checking first if the scope was
already expanded.

Also, set the expanded flag before calling expandSpecifically()
from inside expandAndBeCurrent(), to ensure that re-entrant
calls to expandAndBeCurrent() are flagged by the existing
assertion there.

Finally, replace a couple of existing counters, and the
now-gone request counter with a single ASTScopeExpansions
counter to track expansions.
2020-12-18 15:43:33 -05:00
Slava Pestov
996100cfd1 ASTScope: Remove old SourceRange machinery 2020-10-07 12:33:58 -04:00
Slava Pestov
e52413f913 ASTScope: Use CharSourceRanges for lookup 2020-10-07 12:33:58 -04:00
Slava Pestov
2e67c135fd ASTScope: Rework ConditionalClauseScopes
The top-level scope for a conditional clause with a pattern is now
ConditionalClausePatternUseScope, which introduces the pattern's
bindings.

Since the patterns are not visible in their own initializer, a new
ConditionalClauseInitializerScope is used for the initializer.
While it is nested inside of the ConditionalClausePatternUseScope,
it's lookup parent skips one level, giving us the desired behavior.
2020-10-07 12:33:29 -04:00
Slava Pestov
3ec4ced57d ASTScope: Don't handle top-level bindings in a SourceFile for now 2020-10-01 23:50:16 -04:00
Slava Pestov
f738a57040 ASTScope: Remove DeclVisibilityKind parameter from AbstractASTScopeDeclConsumer::consume()
It wasn't used for anything, and it was always set based on whether
the declaration in question was a GenericTypeParamDecl, a ParamDecl,
or something else.
2020-10-01 23:50:16 -04:00
Slava Pestov
28388384f2 AST: UnqualifiedLookup only finds forward references to outer local bindings when IncludeOuterResults is set
The old behavior was that ASTScope would introduce all VarDecls
defined in a BraceStmt at the beginning of the BraceStmt.

I recently enabled the use of PatternEntryDeclScopes, which
introduce the binding at its actual source location instead of
at the beginning of the parent statement.

This patch now makes use of the new information by having
UnqualifiedLookupFlags::IncludeOuterResults toggle between
the two behaviors. When searching for outer results, we also
consider all VarDecls in a BraceStmt, not just those in scope.

This is implemented by giving AbstractASTScopeDeclConsumer a
new entry point, consumePossiblyNotInScope(). When looking up
into a BraceStmt, all VarDecls are passed in to this entry
point.

The default implementation does nothing, which means that
ASTScope::lookupSingleLocalDecl() now respects source locations
when searching for bindings, just like parse-time lookup.

However, Sema's preCheckExpression() pass, which sets
Flags::IgnoreOuterResults, will continue to find
forward-referenced VarDecls, just as it did with the old
context-based DeclContext lookup.
2020-10-01 23:46:26 -04:00
Slava Pestov
01c434ca13 Merge pull request #34125 from slavapestov/local-redeclaration-checking
Implement re-declaration checking for declarations in local context
2020-10-01 17:07:39 -04:00
Slava Pestov
c56ab07c77 ASTScope: Add finishLookupInBraceStmt parameter to ASTScope::lookupLocalDecls()
This will be used to implement re-declaration checking for local
declarations. Currently this is handled by parse-time lookup.

To make it work with ASTScope, we need to perform lookups that
look into the innermost local scope only; for example, this is
an invalid redeclaration:

do {
  let x = 321
  let x = 123
}

But the following is fine, even though both VarDecls are in the same
*DeclContext*:

do {
  let x = 321
  do {
    let x = 123
  }
}
2020-09-29 23:38:24 -04:00
Slava Pestov
445d747622 AST: Move GenericParamList and friends to GenericParamList.{h,cpp} 2020-09-29 19:51:03 -04:00
Slava Pestov
f8fb071f0f ASTScope: Remove ASTScopeImpl::getDeclContext() 2020-09-25 02:40:13 -04:00
Slava Pestov
bbd79a2db2 ASTScope: unqualifiedLookup() entry point does not need the name
If we're searching for a declaration with a given name, the name
should be entirely encapsulated inside the DeclConsumer.

Otherwise, there might not be a specific name at all, if we're
performing code completion for example (once LookupVisibleDecls
starts to use ASTScope, anyway).
2020-09-25 02:40:13 -04:00
Slava Pestov
cecbf212d3 ASTScope: PatternEntryInitializerScope needs a custom lookup parent
Bindings are not visible from inside their own initializer, eg this
is invalid:

  var (x, y) = (y, x)

The PatternEntryDeclScope which starts after the 'var' introduces x
and y, and it contains the PatternEntryInitializerScope which starts
after the '='.

To model this properly in ASTScope, the PatternEntryInitializerScope
overrides getLookupParent() to skip the PatternEntryDeclScope that
contains it.

I believe this is simpler than having PatternEntryDeclScope begin
at the source location following the initializer, because it is hard
to compute this source location in a way that works with invalid
code, for example the 'var' might be nested inside of a BraceStmt
with the closing '}' missing.
2020-09-23 22:28:01 -04:00
Slava Pestov
81fc342852 ASTScope: Ignore PatternEntryDeclScope when searching for statement labels 2020-09-23 22:28:01 -04:00
Slava Pestov
87593fc0be ASTScope: Fold AbstractFunctionBodyScope into FunctionBodyScope 2020-09-23 13:09:00 -04:00
Slava Pestov
b7bd4fb8b3 ASTScope: Remove 'history' vector 2020-09-22 13:42:48 -04:00
Slava Pestov
c662c10d1e ASTScope: Use visitParsedAccessors() instead of getAllAccessors() 2020-09-22 02:06:32 -04:00