Skip to content

Commit c612f4f

Browse files
committed
[Scope map] Add support for querying the immediate and nearest enclosing DeclContexts of a scope.
1 parent 8e39f3e commit c612f4f

File tree

4 files changed

+124
-1
lines changed

4 files changed

+124
-1
lines changed

include/swift/AST/ASTScope.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,21 @@ class ASTScope {
502502
/// Find the innermost enclosing scope that contains this source location.
503503
const ASTScope *findInnermostEnclosingScope(SourceLoc loc) const;
504504

505+
/// Retrieve the declaration context directly associated with this scope, or
506+
/// NULL if there is no such declaration context.
507+
///
508+
/// \seealso getInnermostEnclosingDeclContext().
509+
DeclContext *getDeclContext() const;
510+
511+
/// Retrieve the innermost enclosing declaration context in which this
512+
/// scope
513+
///
514+
/// This is semantically equivalent to calling \c getDeclContext() on this
515+
/// node and each of its parents until we get a non-null result.
516+
///
517+
/// \seealso getDeclContext().
518+
DeclContext *getInnermostEnclosingDeclContext() const;
519+
505520
/// Expand the entire scope map.
506521
///
507522
/// Normally, the scope map will be expanded only as needed by its queries,

lib/AST/ASTScope.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/ASTContext.h"
1919
#include "swift/AST/ASTWalker.h"
2020
#include "swift/AST/Decl.h"
21+
#include "swift/AST/Initializer.h"
2122
#include "swift/AST/Module.h"
2223
#include "swift/AST/ParameterList.h"
2324
#include "swift/AST/Pattern.h"
@@ -1539,6 +1540,71 @@ const ASTScope *ASTScope::findInnermostEnclosingScope(SourceLoc loc) const {
15391540
};
15401541
}
15411542

1543+
DeclContext *ASTScope::getDeclContext() const {
1544+
switch (getKind()) {
1545+
case ASTScopeKind::SourceFile:
1546+
return sourceFile.file;
1547+
1548+
case ASTScopeKind::TypeOrExtensionBody:
1549+
if (auto nominal = dyn_cast<NominalTypeDecl>(iterableDeclContext))
1550+
return nominal;
1551+
1552+
return cast<ExtensionDecl>(iterableDeclContext);
1553+
1554+
case ASTScopeKind::AbstractFunctionDecl:
1555+
return abstractFunction;
1556+
1557+
case ASTScopeKind::DefaultArgument:
1558+
return parameter->getDefaultArgumentInitContext();
1559+
1560+
case ASTScopeKind::PatternInitializer:
1561+
return patternBinding.decl->getPatternList()[patternBinding.entry]
1562+
.getInitContext();
1563+
1564+
case ASTScopeKind::Closure:
1565+
return closure;
1566+
1567+
case ASTScopeKind::Accessors:
1568+
// FIXME: Somewhat odd modeling because Subscripts don't have their
1569+
// own nodes. Maybe that should.
1570+
if (auto subscript = dyn_cast<SubscriptDecl>(abstractStorageDecl))
1571+
return subscript;
1572+
1573+
return nullptr;
1574+
1575+
case ASTScopeKind::TopLevelCode:
1576+
return topLevelCode;
1577+
1578+
case ASTScopeKind::GenericParams:
1579+
case ASTScopeKind::AbstractFunctionParams:
1580+
case ASTScopeKind::PatternBinding:
1581+
case ASTScopeKind::AfterPatternBinding:
1582+
case ASTScopeKind::Preexpanded:
1583+
case ASTScopeKind::BraceStmt:
1584+
case ASTScopeKind::IfStmt:
1585+
case ASTScopeKind::ConditionalClause:
1586+
case ASTScopeKind::GuardStmt:
1587+
case ASTScopeKind::RepeatWhileStmt:
1588+
case ASTScopeKind::ForEachStmt:
1589+
case ASTScopeKind::ForEachPattern:
1590+
case ASTScopeKind::DoCatchStmt:
1591+
case ASTScopeKind::CatchStmt:
1592+
case ASTScopeKind::SwitchStmt:
1593+
case ASTScopeKind::CaseStmt:
1594+
case ASTScopeKind::ForStmt:
1595+
case ASTScopeKind::ForStmtInitializer:
1596+
case ASTScopeKind::LocalDeclaration:
1597+
return nullptr;
1598+
}
1599+
}
1600+
1601+
DeclContext *ASTScope::getInnermostEnclosingDeclContext() const {
1602+
for (const ASTScope *scope = this; ; scope = scope->getParent()) {
1603+
if (auto dc = scope->getDeclContext()) return dc;
1604+
}
1605+
llvm_unreachable("Top-most scope is a declaration context");
1606+
}
1607+
15421608
void ASTScope::expandAll() const {
15431609
if (!isExpanded())
15441610
expand();

lib/FrontendTool/FrontendTool.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,11 @@ static bool performCompile(CompilerInstance &Instance,
809809
<< lineColumn.second << "***\n";
810810
auto locScope = scope.findInnermostEnclosingScope(loc);
811811
locScope->print(llvm::errs(), 0, false, false);
812+
813+
// Dump the AST context, too.
814+
if (auto dc = locScope->getDeclContext()) {
815+
dc->printContext(llvm::errs());
816+
}
812817
}
813818

814819
llvm::errs() << "***Complete scope map***\n";

test/NameBinding/scope_map.swift

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,11 @@ func defaultArguments(i: Int = 1,
174174
{ $0 }(a)
175175
}
176176

177+
struct PatternInitializers {
178+
var (a, b) = (1, 2),
179+
(c, d) = (1.5, 2.5)
180+
}
181+
177182
// RUN: not %target-swift-frontend -dump-scope-maps expanded %s 2> %t.expanded
178183
// RUN: %FileCheck -check-prefix CHECK-EXPANDED %s < %t.expanded
179184

@@ -365,15 +370,40 @@ func defaultArguments(i: Int = 1,
365370
// CHECK-EXPANDED-NEXT: {{^}} `-BraceStmt {{.*}} [167:32 - 167:42] expanded
366371
// CHECK-EXPANDED-NEXT: {{^}} `-AbstractFunctionParams {{.*}} defaultArguments(i:j:) param 0:1 [167:48 - 175:1] expanded
367372

368-
// RUN: not %target-swift-frontend -dump-scope-maps 70:8,26:20 %s 2> %t.searches
373+
// RUN: not %target-swift-frontend -dump-scope-maps 70:8,26:20,5:18,166:32,179:18 %s 2> %t.searches
369374
// RUN: %FileCheck -check-prefix CHECK-SEARCHES %s < %t.searches
370375

371376
// CHECK-SEARCHES-LABEL: ***Scope at 70:8***
372377
// CHECK-SEARCHES-NEXT: AfterPatternBinding {{.*}} entry 0 [69:13 - 71:3] expanded
378+
373379
// CHECK-SEARCHES-LABEL: ***Scope at 26:20***
374380
// CHECK-SEARCHES-NEXT: AbstractFunctionParams {{.*}} init(t:u:) param 1:0 [26:17 - 27:3] expanded
381+
382+
// CHECK-SEARCHES-LABEL: ***Scope at 5:18***
383+
// CHECK-SEARCHES-NEXT: TypeOrExtensionBody {{.*}} 'InnerC0' [5:17 - 5:19] expanded
384+
// CHECK-SEARCHES-NEXT: Module name=scope_map
385+
// CHECK-SEARCHES-NEXT: FileUnit file="{{.*}}scope_map.swift"
386+
// CHECK-SEARCHES-NEXT: StructDecl name=S0
387+
// CHECK-SEARCHES-NEXT: ClassDecl name=InnerC0
388+
389+
// CHECK-SEARCHES-LABEL: ***Scope at 166:32***
390+
// CHECK-SEARCHES-NEXT: DefaultArgument {{.*}} [166:32 - 166:32] expanded
391+
// CHECK-SEARCHES-NEXT: Module name=scope_map
392+
// CHECK-SEARCHES-NEXT: FileUnit file="{{.*}}scope_map.swift"
393+
// CHECK-SEARCHES-NEXT: AbstractFunctionDecl name=defaultArguments : (Int, Int) -> ()
394+
// CHECK-SEARCHES-NEXT: {{.*}} Initializer DefaultArgument index=0
395+
396+
// CHECK-SEARCHES-LABEL: ***Scope at 179:18***
397+
// CHECK-SEARCHES-NEXT: PatternInitializer {{.*}} entry 1 [179:16 - 179:25] expanded
398+
// CHECK-SEARCHES-NEXT: {{.*}} Module name=scope_map
399+
// CHECK-SEARCHES-NEXT: {{.*}} FileUnit file="{{.*}}scope_map.swift"
400+
// CHECK-SEARCHES-NEXT: {{.*}} StructDecl name=PatternInitializers
401+
// CHECK-SEARCHES-NEXT: {{.*}} Initializer PatternBinding {{.*}} #1
402+
375403
// CHECK-SEARCHES-LABEL: ***Complete scope map***
376404
// CHECK-SEARCHES-NEXT: SourceFile {{.*}} '{{.*}}scope_map.swift' [1:1 - {{.*}}:1] expanded
405+
// CHECK-SEARCHES: TypeOrExtensionBody {{.*}} 'S0' [4:11 - 6:1] expanded
406+
// CHECK-SEARCHES: -TypeOrExtensionBody {{.*}} 'InnerC0' [5:17 - 5:19] expanded
377407
// CHECK-SEARCHES-NOT: {{ expanded}}
378408
// CHECK-SEARCHES: |-TypeOrExtensionBody {{.*}} 'ContainsGenerics0' [25:25 - 31:1] expanded
379409
// CHECK-SEARCHES-NEXT: |-AbstractFunctionDecl {{.*}} init(t:u:) [26:3 - 27:3] expanded
@@ -386,4 +416,11 @@ func defaultArguments(i: Int = 1,
386416
// CHECK-SEARCHES: |-AbstractFunctionDecl {{.*}} functionBodies1(a:b:) [41:1 - 100:1] expanded
387417
// CHECK-SEARCHES: `-AbstractFunctionParams {{.*}} functionBodies1(a:b:) param 0:0 [41:25 - 100:1] expanded
388418
// CHECK-SEARCHES: |-AbstractFunctionDecl {{.*}} throwing() [102:1 - 102:26] unexpanded
419+
// CHECK-SEARCHES: -AbstractFunctionDecl {{.*}} defaultArguments(i:j:) [166:1 - 175:1] expanded
420+
// CHECK-SEARCHES: DefaultArgument {{.*}} [166:32 - 166:32] expanded
421+
// CHECK-SEARCHES-NOT: {{ expanded}}
422+
// CHECK-SEARCHES: -TypeOrExtensionBody {{.*}} 'PatternInitializers' [177:28 - 180:1] expanded
423+
// CHECK-SEARCHES: |-PatternBinding {{.*}} entry 0 [178:7 - 178:21] unexpanded
424+
// CHECK-SEARCHES: `-PatternBinding {{.*}} entry 1 [179:7 - 179:25] expanded
425+
// CHECK-SEARCHES: `-PatternInitializer {{.*}} entry 1 [179:16 - 179:25] expanded
389426
// CHECK-SEARCHES-NOT: {{ expanded}}

0 commit comments

Comments
 (0)