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)) {

0 commit comments

Comments
 (0)