Skip to content

Commit bd35cdb

Browse files
authored
Merge pull request #63985 from DougGregor/expression-macros-effects
2 parents 9e3c89d + 45a0979 commit bd35cdb

File tree

72 files changed

+674
-36
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+674
-36
lines changed

include/swift/AST/ASTWalker.h

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ enum class LazyInitializerWalking {
7979
InAccessor
8080
};
8181

82+
/// Specifies the behavior for walking a macro expansion, whether we want to
83+
/// see the macro arguments, the expansion, or both.
84+
enum class MacroWalking {
85+
/// Walk into the expansion of the macro, to see the semantic effect of
86+
/// the macro expansion.
87+
Expansion,
88+
89+
/// Walk into the arguments of the macro as written in the source code.
90+
///
91+
/// The actual arguments walked may not make it into the program itself,
92+
/// because they can be translated by the macro in arbitrary ways.
93+
Arguments,
94+
95+
/// Walk into both the arguments of the macro as written in the source code
96+
/// and also the macro expansion.
97+
ArgumentsAndExpansion
98+
};
99+
82100
/// An abstract class used to traverse an AST.
83101
class ASTWalker {
84102
public:
@@ -504,6 +522,26 @@ class ASTWalker {
504522
return LazyInitializerWalking::InPatternBinding;
505523
}
506524

525+
/// This method configures how the walker should walk into uses of macros.
526+
virtual MacroWalking getMacroWalkingBehavior() const {
527+
return MacroWalking::ArgumentsAndExpansion;
528+
}
529+
530+
/// Determine whether we should walk macro arguments (as they appear in
531+
/// source) and the expansion (which is semantically part of the program).
532+
std::pair<bool, bool> shouldWalkMacroArgumentsAndExpansion() const {
533+
switch (getMacroWalkingBehavior()) {
534+
case MacroWalking::Expansion:
535+
return std::make_pair(false, true);
536+
537+
case MacroWalking::Arguments:
538+
return std::make_pair(true, false);
539+
540+
case MacroWalking::ArgumentsAndExpansion:
541+
return std::make_pair(true, true);
542+
}
543+
}
544+
507545
/// This method configures whether the walker should visit the body of a
508546
/// closure that was checked separately from its enclosing expression.
509547
///
@@ -541,10 +579,6 @@ class ASTWalker {
541579
/// TODO: Consider changing this to false by default.
542580
virtual bool shouldWalkSerializedTopLevelInternalDecls() { return true; }
543581

544-
/// Whether we should walk into expanded macros, whether it be from a
545-
/// \c MacroExpansionExpr or declarations created by attached macros.
546-
virtual bool shouldWalkMacroExpansions() { return true; }
547-
548582
/// walkToParameterListPre - This method is called when first visiting a
549583
/// ParameterList, before walking into its parameters.
550584
///

include/swift/AST/TypeDeclFinder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ class TypeReprIdentFinder : public ASTWalker {
6767
/// The function to call when a \c IdentTypeRepr is seen.
6868
llvm::function_ref<bool(const IdentTypeRepr *)> Callback;
6969

70+
MacroWalking getMacroWalkingBehavior() const override {
71+
return MacroWalking::Arguments;
72+
}
73+
7074
PostWalkAction walkToTypeReprPost(TypeRepr *TR) override;
7175

7276
public:

include/swift/IDE/SourceEntityWalker.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,10 @@ class SourceEntityWalker {
201201

202202
virtual bool shouldWalkIntoGenericParams() { return true; }
203203

204-
/// Whether we should walk into expanded macros, whether it be from a
205-
/// \c MacroExpansionExpr or declarations created by attached macros.
206-
virtual bool shouldWalkMacroExpansions() { return false; }
204+
/// Only walk the arguments of a macro, to represent the source as written.
205+
virtual MacroWalking getMacroWalkingBehavior() const {
206+
return MacroWalking::Arguments;
207+
}
207208

208209
protected:
209210
SourceEntityWalker() = default;

include/swift/IDE/Utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,10 @@ class NameMatcher: public ASTWalker {
368368
bool handleCustomAttrs(Decl *D);
369369
ArgumentList *getApplicableArgsFor(Expr* E);
370370

371+
MacroWalking getMacroWalkingBehavior() const override {
372+
return MacroWalking::Arguments;
373+
}
374+
371375
PreWalkResult<Expr *> walkToExprPre(Expr *E) override;
372376
PostWalkResult<Expr *> walkToExprPost(Expr *E) override;
373377
PreWalkAction walkToDeclPre(Decl *D) override;

include/swift/Sema/CompletionContextFinder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ class CompletionContextFinder : public ASTWalker {
4949
DeclContext *InitialDC;
5050

5151
public:
52+
MacroWalking getMacroWalkingBehavior() const override {
53+
return MacroWalking::Arguments;
54+
}
55+
5256
/// Finder for completion contexts within the provided initial expression.
5357
CompletionContextFinder(ASTNode initialNode, DeclContext *DC)
5458
: InitialExpr(initialNode.dyn_cast<Expr *>()), InitialDC(DC) {

include/swift/Sema/ConstraintSystem.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,6 +3376,11 @@ class ConstraintSystem {
33763376
CacheExprTypes(Expr *expr, ConstraintSystem &cs, bool excludeRoot)
33773377
: RootExpr(expr), CS(cs), ExcludeRoot(excludeRoot) {}
33783378

3379+
/// Walk everything in a macro
3380+
MacroWalking getMacroWalkingBehavior() const override {
3381+
return MacroWalking::ArgumentsAndExpansion;
3382+
}
3383+
33793384
PostWalkResult<Expr *> walkToExprPost(Expr *expr) override {
33803385
if (ExcludeRoot && expr == RootExpr) {
33813386
assert(!expr->getType() && "Unexpected type in root of expression!");
@@ -6954,6 +6959,10 @@ class OverloadSetCounter : public ASTWalker {
69546959
: NumOverloads(overloads)
69556960
{}
69566961

6962+
MacroWalking getMacroWalkingBehavior() const override {
6963+
return MacroWalking::Arguments;
6964+
}
6965+
69576966
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
69586967
if (auto applyExpr = dyn_cast<ApplyExpr>(expr)) {
69596968
// If we've found function application and it's

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,6 +2405,11 @@ class ConstExtractor: public ASTWalker {
24052405
}
24062406
return false;
24072407
}
2408+
2409+
MacroWalking getMacroWalkingBehavior() const override {
2410+
return MacroWalking::ArgumentsAndExpansion;
2411+
}
2412+
24082413
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
24092414
if (E->isSemanticallyConstExpr()) {
24102415
record(E, E);

lib/AST/ASTScopeCreation.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ class ScopeCreator final : public ASTAllocated<ScopeCreator> {
141141
PreWalkAction walkToParameterListPre(ParameterList *PL) override {
142142
return Action::SkipChildren();
143143
}
144+
145+
MacroWalking getMacroWalkingBehavior() const override {
146+
return MacroWalking::ArgumentsAndExpansion;
147+
}
144148
};
145149

146150
expr->walk(ClosureFinder(*this, parent));

lib/AST/ASTVerifier.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,10 @@ class Verifier : public ASTWalker {
271271
return Verifier(topDC->getParentModule(), DC);
272272
}
273273

274+
MacroWalking getMacroWalkingBehavior() const override {
275+
return MacroWalking::Expansion;
276+
}
277+
274278
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
275279
switch (E->getKind()) {
276280
#define DISPATCH(ID) return dispatchVisitPreExpr(static_cast<ID##Expr*>(E))

lib/AST/ASTWalker.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,13 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
430430
}
431431

432432
bool visitMacroExpansionDecl(MacroExpansionDecl *MED) {
433-
if (MED->getArgs() && doIt(MED->getArgs()))
433+
bool shouldWalkArguments, shouldWalkExpansion;
434+
std::tie(shouldWalkArguments, shouldWalkExpansion) =
435+
Walker.shouldWalkMacroArgumentsAndExpansion();
436+
if (shouldWalkArguments && MED->getArgs() && doIt(MED->getArgs()))
434437
return true;
435-
if (Walker.shouldWalkMacroExpansions()) {
438+
439+
if (shouldWalkExpansion) {
436440
for (auto *decl : MED->getRewritten())
437441
if (doIt(decl))
438442
return true;
@@ -1297,20 +1301,24 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
12971301
}
12981302

12991303
Expr *visitMacroExpansionExpr(MacroExpansionExpr *E) {
1300-
ArgumentList *args = nullptr;
1301-
if (E->getArgs()) {
1302-
args = doIt(E->getArgs());
1304+
bool shouldWalkArguments, shouldWalkExpansion;
1305+
std::tie(shouldWalkArguments, shouldWalkExpansion) =
1306+
Walker.shouldWalkMacroArgumentsAndExpansion();
1307+
1308+
if (shouldWalkArguments && E->getArgs()) {
1309+
ArgumentList *args = doIt(E->getArgs());
13031310
if (!args) return nullptr;
1311+
E->setArgs(args);
13041312
}
1305-
if (Walker.shouldWalkMacroExpansions()) {
1313+
1314+
if (shouldWalkExpansion) {
13061315
Expr *rewritten = nullptr;
13071316
if (E->getRewritten()) {
13081317
rewritten = doIt(E->getRewritten());
13091318
if (!rewritten) return nullptr;
13101319
}
13111320
E->setRewritten(rewritten);
13121321
}
1313-
E->setArgs(args);
13141322
return E;
13151323
}
13161324

@@ -1425,7 +1433,8 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
14251433
}
14261434

14271435
bool shouldSkip(Decl *D) {
1428-
if (!Walker.shouldWalkMacroExpansions() && D->isInGeneratedBuffer())
1436+
if (!Walker.shouldWalkMacroArgumentsAndExpansion().second &&
1437+
D->isInGeneratedBuffer())
14291438
return true;
14301439

14311440
if (auto *VD = dyn_cast<VarDecl>(D)) {

lib/AST/Decl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7681,6 +7681,11 @@ swift::findWrappedValuePlaceholder(Expr *init) {
76817681
public:
76827682
PropertyWrapperValuePlaceholderExpr *placeholder = nullptr;
76837683

7684+
/// Only walk the arguments of a macro, to represent the source as written.
7685+
MacroWalking getMacroWalkingBehavior() const override {
7686+
return MacroWalking::Arguments;
7687+
}
7688+
76847689
virtual PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
76857690
if (placeholder)
76867691
return Action::SkipChildren(E);
@@ -8376,6 +8381,11 @@ AbstractFunctionDecl::getBodyFingerprintIncludingLocalTypeMembers() const {
83768381
public:
83778382
HashCombiner(StableHasher &hasher) : hasher(hasher) {}
83788383

8384+
/// Only walk the arguments of a macro, to represent the source as written.
8385+
MacroWalking getMacroWalkingBehavior() const override {
8386+
return MacroWalking::Arguments;
8387+
}
8388+
83798389
PreWalkAction walkToDeclPre(Decl *D) override {
83808390
if (D->isImplicit())
83818391
return Action::SkipChildren();

lib/AST/Expr.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,12 @@ forEachImmediateChildExpr(llvm::function_ref<Expr *(Expr *)> callback) {
488488
struct ChildWalker : ASTWalker {
489489
llvm::function_ref<Expr *(Expr *)> callback;
490490
Expr *ThisNode;
491-
491+
492+
/// Only walk the arguments of a macro, to represent the source as written.
493+
MacroWalking getMacroWalkingBehavior() const override {
494+
return MacroWalking::Arguments;
495+
}
496+
492497
ChildWalker(llvm::function_ref<Expr *(Expr *)> callback, Expr *ThisNode)
493498
: callback(callback), ThisNode(ThisNode) {}
494499

@@ -533,6 +538,11 @@ void Expr::forEachChildExpr(llvm::function_ref<Expr *(Expr *)> callback) {
533538
struct ChildWalker : ASTWalker {
534539
llvm::function_ref<Expr *(Expr *)> callback;
535540

541+
/// Only walk the arguments of a macro, to represent the source as written.
542+
MacroWalking getMacroWalkingBehavior() const override {
543+
return MacroWalking::Arguments;
544+
}
545+
536546
ChildWalker(llvm::function_ref<Expr *(Expr *)> callback)
537547
: callback(callback) {}
538548

@@ -853,6 +863,11 @@ llvm::DenseMap<Expr *, Expr *> Expr::getParentMap() {
853863
public:
854864
llvm::DenseMap<Expr *, Expr *> &ParentMap;
855865

866+
/// Walk everything that's available.
867+
MacroWalking getMacroWalkingBehavior() const override {
868+
return MacroWalking::ArgumentsAndExpansion;
869+
}
870+
856871
explicit RecordingTraversal(llvm::DenseMap<Expr *, Expr *> &parentMap)
857872
: ParentMap(parentMap) { }
858873

@@ -1265,6 +1280,11 @@ void PackExpansionExpr::getExpandedPacks(SmallVectorImpl<ASTNode> &packs) {
12651280
struct PackCollector : public ASTWalker {
12661281
llvm::SmallVector<ASTNode, 2> packs;
12671282

1283+
/// Walk everything that's available.
1284+
MacroWalking getMacroWalkingBehavior() const override {
1285+
return MacroWalking::ArgumentsAndExpansion;
1286+
}
1287+
12681288
virtual PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
12691289
// Don't walk into nested pack expansions
12701290
if (isa<PackExpansionExpr>(E)) {

lib/AST/InlinableText.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ class IsFeatureCheck : public ASTWalker {
4949
public:
5050
bool foundFeature = false;
5151

52+
/// Walk everything that's available.
53+
MacroWalking getMacroWalkingBehavior() const override {
54+
return MacroWalking::ArgumentsAndExpansion;
55+
}
56+
5257
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
5358
if (auto unresolved = dyn_cast<UnresolvedDeclRefExpr>(expr)) {
5459
if (unresolved->getName().getBaseName().userFacingName().startswith("$"))
@@ -110,6 +115,11 @@ struct ExtractInactiveRanges : public ASTWalker {
110115
SmallVector<CharSourceRange, 4> ranges;
111116
SourceManager &sourceMgr;
112117

118+
/// Walk everything that's available.
119+
MacroWalking getMacroWalkingBehavior() const override {
120+
return MacroWalking::ArgumentsAndExpansion;
121+
}
122+
113123
explicit ExtractInactiveRanges(SourceManager &sourceMgr)
114124
: sourceMgr(sourceMgr) {}
115125

lib/AST/NameLookup.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2918,6 +2918,11 @@ CollectedOpaqueReprs swift::collectOpaqueReturnTypeReprs(TypeRepr *r, ASTContext
29182918
public:
29192919
explicit Walker(CollectedOpaqueReprs &reprs, ASTContext &ctx, DeclContext *d) : Reprs(reprs), Ctx(ctx), dc(d) {}
29202920

2921+
/// Walk everything that's available.
2922+
MacroWalking getMacroWalkingBehavior() const override {
2923+
return MacroWalking::ArgumentsAndExpansion;
2924+
}
2925+
29212926
PreWalkAction walkToTypeReprPre(TypeRepr *repr) override {
29222927

29232928
// Don't allow variadic opaque parameter or return types.

lib/AST/Pattern.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ namespace {
167167
WalkToVarDecls(const std::function<void(VarDecl*)> &fn)
168168
: fn(fn) {}
169169

170+
/// Walk everything that's available; there shouldn't be macro expansions
171+
/// that matter anyway.
172+
MacroWalking getMacroWalkingBehavior() const override {
173+
return MacroWalking::ArgumentsAndExpansion;
174+
}
175+
170176
PostWalkResult<Pattern *> walkToPatternPost(Pattern *P) override {
171177
// Handle vars.
172178
if (auto *Named = dyn_cast<NamedPattern>(P))

lib/AST/Stmt.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,11 @@ ASTNode BraceStmt::findAsyncNode() {
245245
class FindInnerAsync : public ASTWalker {
246246
ASTNode AsyncNode;
247247

248+
/// Walk only the macro arguments.
249+
MacroWalking getMacroWalkingBehavior() const override {
250+
return MacroWalking::Arguments;
251+
}
252+
248253
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
249254
// If we've found an 'await', record it and terminate the traversal.
250255
if (isa<AwaitExpr>(expr)) {

lib/AST/TypeRepr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ bool TypeRepr::findIf(llvm::function_ref<bool(TypeRepr *)> pred) {
8383
explicit Walker(llvm::function_ref<bool(TypeRepr *)> pred)
8484
: Pred(pred), FoundIt(false) {}
8585

86+
/// Walk everything in a macro
87+
MacroWalking getMacroWalkingBehavior() const override {
88+
return MacroWalking::ArgumentsAndExpansion;
89+
}
90+
8691
PreWalkAction walkToTypeReprPre(TypeRepr *ty) override {
8792
if (Pred(ty)) {
8893
FoundIt = true;

lib/ConstExtract/ConstExtract.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class NominalTypeConformanceCollector : public ASTWalker {
4747
std::vector<NominalTypeDecl *> &ConformanceDecls)
4848
: Protocols(Protocols), ConformanceTypeDecls(ConformanceDecls) {}
4949

50+
MacroWalking getMacroWalkingBehavior() const override {
51+
return MacroWalking::ArgumentsAndExpansion;
52+
}
53+
5054
PreWalkAction walkToDeclPre(Decl *D) override {
5155
if (auto *NTD = llvm::dyn_cast<NominalTypeDecl>(D))
5256
if (!isa<ProtocolDecl>(NTD))

0 commit comments

Comments
 (0)