Skip to content

Commit a2aed2a

Browse files
committed
[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.
1 parent 1e20686 commit a2aed2a

File tree

4 files changed

+145
-75
lines changed

4 files changed

+145
-75
lines changed

include/swift/AST/ASTScope.h

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -236,22 +236,16 @@ class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {
236236

237237
virtual NullablePtr<AbstractClosureExpr> getClosureIfClosureScope() const;
238238
virtual NullablePtr<const BraceStmtScope> getAsBraceStmtScope() const;
239-
virtual ASTContext &getASTContext() const;
240-
virtual NullablePtr<Decl> getDeclIfAny() const { return nullptr; };
241-
virtual NullablePtr<Stmt> getStmtIfAny() const { return nullptr; };
242-
virtual NullablePtr<Expr> getExprIfAny() const { return nullptr; };
243-
virtual NullablePtr<DeclAttribute> getDeclAttributeIfAny() const {
244-
return nullptr;
245-
}
246-
247-
virtual NullablePtr<MacroExpansionDecl> getFreestandingMacro() const {
248-
return nullptr;
249-
}
239+
ASTContext &getASTContext() const;
240+
NullablePtr<Decl> getDeclIfAny() const;
241+
NullablePtr<Stmt> getStmtIfAny() const;
242+
NullablePtr<Expr> getExprIfAny() const;
243+
NullablePtr<DeclAttribute> getDeclAttributeIfAny() const;
250244

251245
#pragma mark - debugging and printing
252246

253247
public:
254-
virtual const SourceFile *getSourceFile() const;
248+
const SourceFile *getSourceFile() const;
255249
StringRef getClassName() const;
256250

257251
/// Print out this scope for debugging/reporting purposes.
@@ -453,10 +447,8 @@ class ASTSourceFileScope final : public ASTScopeImpl {
453447

454448
void expandFunctionBody(AbstractFunctionDecl *AFD);
455449

456-
const SourceFile *getSourceFile() const override;
457450
NullablePtr<const void> addressForPrinting() const override { return SF; }
458451

459-
ASTContext &getASTContext() const override;
460452
bool ignoreInDebugInfo() const override { return true; }
461453

462454
protected:
@@ -592,7 +584,6 @@ class GenericTypeOrExtensionScope : public ASTScopeImpl {
592584
virtual void expandBody(ScopeCreator &);
593585

594586
virtual Decl *getDecl() const = 0;
595-
NullablePtr<Decl> getDeclIfAny() const override { return getDecl(); }
596587

597588
private:
598589
AnnotatedInsertionPoint
@@ -825,7 +816,6 @@ class AbstractFunctionDeclScope final : public ASTScopeImpl {
825816
void printSpecifics(llvm::raw_ostream &out) const override;
826817

827818
public:
828-
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
829819
Decl *getDecl() const { return decl; }
830820

831821
protected:
@@ -889,7 +879,6 @@ class FunctionBodyScope : public ASTScopeImpl {
889879
public:
890880
SourceRange
891881
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
892-
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
893882
Decl *getDecl() const { return decl; }
894883
bool ignoreInDebugInfo() const override { return true; }
895884

@@ -921,7 +910,6 @@ class DefaultArgumentInitializerScope final : public ASTScopeImpl {
921910
void expandAScopeThatDoesNotCreateANewInsertionPoint(ScopeCreator &);
922911
SourceRange
923912
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
924-
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
925913
Decl *getDecl() const { return decl; }
926914
bool ignoreInDebugInfo() const override { return true; }
927915

@@ -953,9 +941,6 @@ class CustomAttributeScope final : public ASTScopeImpl {
953941
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
954942
NullablePtr<const void> addressForPrinting() const override { return decl; }
955943

956-
NullablePtr<DeclAttribute> getDeclAttributeIfAny() const override {
957-
return attr;
958-
}
959944
bool ignoreInDebugInfo() const override { return true; }
960945

961946
private:
@@ -1003,7 +988,6 @@ class AbstractPatternEntryScope : public ASTScopeImpl {
1003988
void printSpecifics(llvm::raw_ostream &out) const override;
1004989

1005990
public:
1006-
NullablePtr<Decl> getDeclIfAny() const override { return decl; }
1007991
Decl *getDecl() const { return decl; }
1008992
};
1009993

@@ -1151,7 +1135,6 @@ class CaptureListScope final : public ASTScopeImpl {
11511135
public:
11521136
SourceRange
11531137
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
1154-
NullablePtr<Expr> getExprIfAny() const override { return expr; }
11551138
Expr *getExpr() const { return expr; }
11561139
bool lookupLocalsOrMembers(DeclConsumer) const override;
11571140

@@ -1177,7 +1160,6 @@ class ClosureParametersScope final : public ASTScopeImpl {
11771160
}
11781161
std::pair<CatchNode, const BraceStmtScope *> getCatchNodeBody() const override;
11791162

1180-
NullablePtr<Expr> getExprIfAny() const override { return closureExpr; }
11811163
Expr *getExpr() const { return closureExpr; }
11821164
bool ignoreInDebugInfo() const override { return true; }
11831165

@@ -1215,7 +1197,6 @@ class TopLevelCodeScope final : public ASTScopeImpl {
12151197
public:
12161198
SourceRange
12171199
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
1218-
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
12191200
Decl *getDecl() const { return decl; }
12201201

12211202
static bool classof(const ASTScopeImpl *scope) {
@@ -1242,7 +1223,7 @@ class SpecializeAttributeScope final : public ASTScopeImpl {
12421223
return specializeAttr;
12431224
}
12441225

1245-
NullablePtr<DeclAttribute> getDeclAttributeIfAny() const override {
1226+
DeclAttribute *getDeclAttr() const {
12461227
return specializeAttr;
12471228
}
12481229

@@ -1276,7 +1257,7 @@ class DifferentiableAttributeScope final : public ASTScopeImpl {
12761257
return differentiableAttr;
12771258
}
12781259

1279-
NullablePtr<DeclAttribute> getDeclAttributeIfAny() const override {
1260+
DeclAttribute *getDeclAttr() const {
12801261
return differentiableAttr;
12811262
}
12821263

@@ -1313,7 +1294,6 @@ class SubscriptDeclScope final : public ASTScopeImpl {
13131294
void printSpecifics(llvm::raw_ostream &out) const override;
13141295

13151296
public:
1316-
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
13171297
Decl *getDecl() const { return decl; }
13181298

13191299
protected:
@@ -1336,7 +1316,6 @@ class EnumElementScope : public ASTScopeImpl {
13361316
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
13371317

13381318
ASTScopeImpl *expandSpecifically(ScopeCreator &) override;
1339-
NullablePtr<Decl> getDeclIfAny() const override { return decl; }
13401319
Decl *getDecl() const { return decl; }
13411320

13421321
private:
@@ -1369,7 +1348,6 @@ class MacroDeclScope final : public ASTScopeImpl {
13691348
void printSpecifics(llvm::raw_ostream &out) const override;
13701349

13711350
public:
1372-
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
13731351
Decl *getDecl() const { return decl; }
13741352

13751353
protected:
@@ -1424,15 +1402,10 @@ class MacroExpansionDeclScope final : public ASTScopeImpl {
14241402
SourceRange
14251403
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
14261404

1427-
NullablePtr<MacroExpansionDecl> getFreestandingMacro() const override {
1428-
return decl;
1429-
}
1430-
14311405
protected:
14321406
void printSpecifics(llvm::raw_ostream &out) const override;
14331407

14341408
public:
1435-
virtual NullablePtr<Decl> getDeclIfAny() const override { return decl; }
14361409
Decl *getDecl() const { return decl; }
14371410

14381411
static bool classof(const ASTScopeImpl *scope) {
@@ -1448,7 +1421,6 @@ class AbstractStmtScope : public ASTScopeImpl {
14481421
SourceRange
14491422
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
14501423
virtual Stmt *getStmt() const = 0;
1451-
NullablePtr<Stmt> getStmtIfAny() const override { return getStmt(); }
14521424

14531425
protected:
14541426
bool isLabeledStmtLookupTerminator() const override;

include/swift/AST/ASTScopeNodes.def

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,54 +10,87 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
13-
// This file defines all of the kinds of ASTScope nodes.
13+
// This file defines all of the kinds of ASTScope nodes.
1414
//
15+
// The primary macro to define before including this file is SCOPE_NODE(Name),
16+
// which provides the name of the scope node (without the "Scope" suffix).
17+
// There are several more specific macros that can be defined to get more
18+
// specific information about certain kinds of nodes:
19+
//
20+
// DECL_SCOPE_NODE(Name) - A scope node associated with a declaration.
21+
// STMT_SCOPE_NODE(Name) - A scope node associated with a statement.
22+
// EXPR_SCOPE_NODE(Name) - A scope node associated with an expression.
23+
// DECL_ATTRIBUTE_SCOPE_NODE(Name) - A scope node associated with a
24+
// declaration attribute.
25+
//
26+
// For each of these that is not defined on inclusion of this file, a
27+
// definition in terms of SCOPE_NODE will be provided, allowing clients to
28+
// define only SCOPE_NODE to deal with all scope nodes.
1529
//===----------------------------------------------------------------------===//
1630

1731
#ifndef SCOPE_NODE
1832
# error "define SCOPE_NODE(Name) when enumerating ASTScope nodes
1933
# define SCOPE_NODE(Name)
2034
#endif
2135

36+
#ifndef DECL_SCOPE_NODE
37+
# define DECL_SCOPE_NODE(Name) SCOPE_NODE(Name)
38+
#endif
39+
40+
#ifndef STMT_SCOPE_NODE
41+
# define STMT_SCOPE_NODE(Name) SCOPE_NODE(Name)
42+
#endif
43+
44+
#ifndef EXPR_SCOPE_NODE
45+
# define EXPR_SCOPE_NODE(Name) SCOPE_NODE(Name)
46+
#endif
47+
48+
#ifndef DECL_ATTRIBUTE_SCOPE_NODE
49+
# define DECL_ATTRIBUTE_SCOPE_NODE(Name) SCOPE_NODE(Name)
50+
#endif
51+
2252
SCOPE_NODE(ASTSourceFile)
23-
SCOPE_NODE(NominalType)
24-
SCOPE_NODE(Extension)
25-
SCOPE_NODE(TypeAlias)
26-
SCOPE_NODE(OpaqueType)
53+
DECL_SCOPE_NODE(NominalType)
54+
DECL_SCOPE_NODE(Extension)
55+
DECL_SCOPE_NODE(TypeAlias)
56+
DECL_SCOPE_NODE(OpaqueType)
2757
SCOPE_NODE(GenericParam)
28-
SCOPE_NODE(AbstractFunctionDecl)
58+
DECL_SCOPE_NODE(AbstractFunctionDecl)
2959
SCOPE_NODE(ParameterList)
30-
SCOPE_NODE(FunctionBody)
31-
SCOPE_NODE(DefaultArgumentInitializer)
60+
DECL_SCOPE_NODE(FunctionBody)
61+
DECL_SCOPE_NODE(DefaultArgumentInitializer)
3262
SCOPE_NODE(CustomAttribute)
33-
SCOPE_NODE(PatternEntryDecl)
34-
SCOPE_NODE(PatternEntryInitializer)
63+
DECL_SCOPE_NODE(PatternEntryDecl)
64+
DECL_SCOPE_NODE(PatternEntryInitializer)
3565
SCOPE_NODE(ConditionalClausePatternUse)
3666
SCOPE_NODE(ConditionalClauseInitializer)
37-
SCOPE_NODE(CaptureList)
38-
SCOPE_NODE(ClosureParameters)
39-
SCOPE_NODE(TopLevelCode)
40-
SCOPE_NODE(SpecializeAttribute)
41-
SCOPE_NODE(DifferentiableAttribute)
42-
SCOPE_NODE(SubscriptDecl)
43-
SCOPE_NODE(EnumElement)
44-
SCOPE_NODE(MacroDecl)
67+
EXPR_SCOPE_NODE(CaptureList)
68+
EXPR_SCOPE_NODE(ClosureParameters)
69+
DECL_SCOPE_NODE(TopLevelCode)
70+
DECL_ATTRIBUTE_SCOPE_NODE(SpecializeAttribute)
71+
DECL_ATTRIBUTE_SCOPE_NODE(DifferentiableAttribute)
72+
DECL_SCOPE_NODE(SubscriptDecl)
73+
DECL_SCOPE_NODE(EnumElement)
74+
DECL_SCOPE_NODE(MacroDecl)
4575
SCOPE_NODE(MacroDefinition)
46-
SCOPE_NODE(MacroExpansionDecl)
47-
SCOPE_NODE(IfStmt)
48-
SCOPE_NODE(WhileStmt)
49-
SCOPE_NODE(GuardStmt)
76+
DECL_SCOPE_NODE(MacroExpansionDecl)
77+
STMT_SCOPE_NODE(IfStmt)
78+
STMT_SCOPE_NODE(WhileStmt)
79+
STMT_SCOPE_NODE(GuardStmt)
5080
SCOPE_NODE(GuardStmtBody)
51-
SCOPE_NODE(RepeatWhile)
52-
SCOPE_NODE(DoStmt)
53-
SCOPE_NODE(DoCatchStmt)
54-
SCOPE_NODE(SwitchStmt)
55-
SCOPE_NODE(ForEachStmt)
81+
STMT_SCOPE_NODE(RepeatWhile)
82+
STMT_SCOPE_NODE(DoStmt)
83+
STMT_SCOPE_NODE(DoCatchStmt)
84+
STMT_SCOPE_NODE(SwitchStmt)
85+
STMT_SCOPE_NODE(ForEachStmt)
5686
SCOPE_NODE(ForEachPattern)
57-
SCOPE_NODE(CaseStmt)
87+
STMT_SCOPE_NODE(CaseStmt)
5888
SCOPE_NODE(CaseLabelItem)
5989
SCOPE_NODE(CaseStmtBody)
60-
SCOPE_NODE(BraceStmt)
61-
SCOPE_NODE(IterableType)
90+
STMT_SCOPE_NODE(BraceStmt)
6291

92+
#undef DECL_ATTRIBUTE_SCOPE_NODE
93+
#undef EXPR_SCOPE_NODE
94+
#undef STMT_SCOPE_NODE
95+
#undef DECL_SCOPE_NODE
6396
#undef SCOPE_NODE

lib/AST/ASTScope.cpp

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,70 @@ StringRef ASTScopeImpl::getClassName() const {
167167
}
168168
}
169169

170+
NullablePtr<Decl> ASTScopeImpl::getDeclIfAny() const {
171+
switch (getKind()) {
172+
// Declaration scope nodes extract the decl directly.
173+
#define DECL_SCOPE_NODE(Name) \
174+
case ScopeKind::Name: return cast<Name##Scope>(this)->getDecl();
175+
#define SCOPE_NODE(Name)
176+
#include "swift/AST/ASTScopeNodes.def"
177+
178+
// Everything else returns nullptr.
179+
#define DECL_SCOPE_NODE(Name)
180+
#define SCOPE_NODE(Name) case ScopeKind::Name:
181+
#include "swift/AST/ASTScopeNodes.def"
182+
return nullptr;
183+
}
184+
}
185+
186+
NullablePtr<Stmt> ASTScopeImpl::getStmtIfAny() const {
187+
switch (getKind()) {
188+
// Statement scope nodes extract the statement directly.
189+
#define STMT_SCOPE_NODE(Name) \
190+
case ScopeKind::Name: return cast<Name##Scope>(this)->getStmt();
191+
#define SCOPE_NODE(Name)
192+
#include "swift/AST/ASTScopeNodes.def"
193+
194+
// Everything else returns nullptr.
195+
#define STMT_SCOPE_NODE(Name)
196+
#define SCOPE_NODE(Name) case ScopeKind::Name:
197+
#include "swift/AST/ASTScopeNodes.def"
198+
return nullptr;
199+
}
200+
}
201+
202+
NullablePtr<Expr> ASTScopeImpl::getExprIfAny() const {
203+
switch (getKind()) {
204+
// Expression scope nodes extract the statement directly.
205+
#define EXPR_SCOPE_NODE(Name) \
206+
case ScopeKind::Name: return cast<Name##Scope>(this)->getExpr();
207+
#define SCOPE_NODE(Name)
208+
#include "swift/AST/ASTScopeNodes.def"
209+
210+
// Everything else returns nullptr.
211+
#define EXPR_SCOPE_NODE(Name)
212+
#define SCOPE_NODE(Name) case ScopeKind::Name:
213+
#include "swift/AST/ASTScopeNodes.def"
214+
return nullptr;
215+
}
216+
}
217+
218+
NullablePtr<DeclAttribute> ASTScopeImpl::getDeclAttributeIfAny() const {
219+
switch (getKind()) {
220+
// Statement scope nodes extract the statement directly.
221+
#define DECL_ATTRIBUTE_SCOPE_NODE(Name) \
222+
case ScopeKind::Name: return cast<Name##Scope>(this)->getDeclAttr();
223+
#define SCOPE_NODE(Name)
224+
#include "swift/AST/ASTScopeNodes.def"
225+
226+
// Everything else returns nullptr.
227+
#define DECL_ATTRIBUTE_SCOPE_NODE(Name)
228+
#define SCOPE_NODE(Name) case ScopeKind::Name:
229+
#include "swift/AST/ASTScopeNodes.def"
230+
return nullptr;
231+
}
232+
}
233+
170234
SourceManager &ASTScopeImpl::getSourceManager() const {
171235
return getASTContext().SourceMgr;
172236
}
@@ -192,19 +256,18 @@ LabeledConditionalStmt *GuardStmtScope::getLabeledConditionalStmt() const {
192256
ASTContext &ASTScopeImpl::getASTContext() const {
193257
if (auto d = getDeclIfAny())
194258
return d.get()->getASTContext();
259+
if (auto sfScope = dyn_cast<ASTSourceFileScope>(this))
260+
return sfScope->SF->getASTContext();
195261
return getParent().get()->getASTContext();
196262
}
197263

198264
#pragma mark getSourceFile
199265

200266
const SourceFile *ASTScopeImpl::getSourceFile() const {
201-
return getParent().get()->getSourceFile();
202-
}
267+
if (auto sourceFileScope = dyn_cast<ASTSourceFileScope>(this))
268+
return sourceFileScope->SF;
203269

204-
const SourceFile *ASTSourceFileScope::getSourceFile() const { return SF; }
205-
206-
ASTContext &ASTSourceFileScope::getASTContext() const {
207-
return SF->getASTContext();
270+
return getParent().get()->getSourceFile();
208271
}
209272

210273
SourceRange ExtensionScope::getBraces() const { return decl->getBraces(); }

0 commit comments

Comments
 (0)