Skip to content

Commit 15a45e2

Browse files
committed
[Macros] Improve visitation of auxiliary decls
Use the same pattern as 'getAllMembers()'. This supports nested macro expansion: ``` std::function<void(Decl *)> visit; visit = [&](Decl *d) { doIt(d); d->visitAuxiliaryDecls(visit); }; for (auto *d : decls) visit(d); ``` Don't visit auxiliary decls in `PrintAST::visit(Decl *)` this function is only intended for single decl printing. The caller should visit them separately. For that, add `ModuleDecl::getTopLevelDeclsWithAuxiliaryDecls()` (cherry picked from commit 03bf349)
1 parent 7492b74 commit 15a45e2

File tree

5 files changed

+33
-21
lines changed

5 files changed

+33
-21
lines changed

include/swift/AST/Module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,10 @@ class ModuleDecl
959959
/// The order of the results is not guaranteed to be meaningful.
960960
void getTopLevelDecls(SmallVectorImpl<Decl*> &Results) const;
961961

962+
/// Finds all top-level decls of this module including auxiliary decls.
963+
void
964+
getTopLevelDeclsWithAuxiliaryDecls(SmallVectorImpl<Decl *> &Results) const;
965+
962966
void getExportedPrespecializations(SmallVectorImpl<Decl *> &results) const;
963967

964968
/// Finds top-level decls of this module filtered by their attributes.

lib/AST/ASTPrinter.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,12 +1024,6 @@ class PrintAST : public ASTVisitor<PrintAST> {
10241024
Options.TransformContext->isPrintingSynthesizedExtension() &&
10251025
isa<ExtensionDecl>(D);
10261026

1027-
SWIFT_DEFER {
1028-
D->visitAuxiliaryDecls([&](Decl *auxDecl) {
1029-
visit(auxDecl);
1030-
});
1031-
};
1032-
10331027
if (!shouldPrint(D, true) && !Synthesize)
10341028
return false;
10351029

@@ -4389,13 +4383,20 @@ bool PrintAST::printASTNodes(const ArrayRef<ASTNode> &Elements,
43894383
bool NeedIndent) {
43904384
IndentRAII IndentMore(*this, NeedIndent);
43914385
bool PrintedSomething = false;
4386+
4387+
std::function<void(Decl *)> printDecl;
4388+
printDecl = [&](Decl *d) {
4389+
if (d->shouldPrintInContext(Options))
4390+
visit(d);
4391+
d->visitAuxiliaryDecls(printDecl);
4392+
};
4393+
43924394
for (auto element : Elements) {
43934395
PrintedSomething = true;
43944396
Printer.printNewline();
43954397
indent();
43964398
if (auto decl = element.dyn_cast<Decl*>()) {
4397-
if (decl->shouldPrintInContext(Options))
4398-
visit(decl);
4399+
printDecl(decl);
43994400
} else if (auto stmt = element.dyn_cast<Stmt*>()) {
44004401
visit(stmt);
44014402
} else {

lib/AST/Module.cpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,11 @@ void ModuleDecl::getTopLevelDecls(SmallVectorImpl<Decl*> &Results) const {
13311331
FORWARD(getTopLevelDecls, (Results));
13321332
}
13331333

1334+
void ModuleDecl::getTopLevelDeclsWithAuxiliaryDecls(
1335+
SmallVectorImpl<Decl *> &Results) const {
1336+
FORWARD(getTopLevelDeclsWithAuxiliaryDecls, (Results));
1337+
}
1338+
13341339
void ModuleDecl::dumpDisplayDecls() const {
13351340
SmallVector<Decl *, 32> Decls;
13361341
getDisplayDecls(Decls);
@@ -3060,7 +3065,9 @@ void SourceFile::print(raw_ostream &OS, const PrintOptions &PO) {
30603065
void SourceFile::print(ASTPrinter &Printer, const PrintOptions &PO) {
30613066
std::set<DeclKind> MajorDeclKinds = {DeclKind::Class, DeclKind::Enum,
30623067
DeclKind::Extension, DeclKind::Protocol, DeclKind::Struct};
3063-
for (auto decl : getTopLevelDecls()) {
3068+
SmallVector<Decl *> topLevelDecls;
3069+
getTopLevelDeclsWithAuxiliaryDecls(topLevelDecls);
3070+
for (auto decl : topLevelDecls) {
30643071
if (!decl->shouldPrintInContext(PO))
30653072
continue;
30663073
// For a major decl, we print an empty line before it.
@@ -4137,14 +4144,18 @@ void FileUnit::getTopLevelDeclsWhereAttributesMatch(
41374144

41384145
void FileUnit::getTopLevelDeclsWithAuxiliaryDecls(
41394146
SmallVectorImpl<Decl*> &results) const {
4147+
4148+
std::function<void(Decl *)> addResult;
4149+
addResult = [&](Decl *decl) {
4150+
results.push_back(decl);
4151+
decl->visitAuxiliaryDecls(addResult);
4152+
};
4153+
41404154
SmallVector<Decl *, 32> nonExpandedDecls;
41414155
nonExpandedDecls.reserve(results.capacity());
41424156
getTopLevelDecls(nonExpandedDecls);
41434157
for (auto *decl : nonExpandedDecls) {
4144-
decl->visitAuxiliaryDecls([&](Decl *auxDecl) {
4145-
results.push_back(auxDecl);
4146-
});
4147-
results.push_back(decl);
4158+
addResult(decl);
41484159
}
41494160
}
41504161

lib/AST/NameLookup.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4004,16 +4004,12 @@ void FindLocalVal::visitBraceStmt(BraceStmt *S, bool isTopLevelCode) {
40044004
}
40054005
}
40064006

4007-
auto visitDecl = [&](Decl *D) {
4007+
std::function<void(Decl *)> visitDecl;
4008+
visitDecl = [&](Decl *D) {
40084009
if (auto *VD = dyn_cast<ValueDecl>(D))
40094010
checkValueDecl(VD, DeclVisibilityKind::LocalVariable);
4010-
D->visitAuxiliaryDecls([&](Decl *D) {
4011-
if (auto *VD = dyn_cast<ValueDecl>(D))
4012-
checkValueDecl(VD, DeclVisibilityKind::LocalVariable);
4013-
// FIXME: Recursively call `visitDecl` to handle nested macros.
4014-
});
4011+
D->visitAuxiliaryDecls(visitDecl);
40154012
};
4016-
40174013
for (auto elem : S->getElements()) {
40184014
if (auto *E = elem.dyn_cast<Expr *>()) {
40194015
// 'MacroExpansionExpr' at code-item position may introduce value decls.

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ bool swift::emitSwiftInterface(raw_ostream &out,
837837
InheritedProtocolCollector::PerTypeMap inheritedProtocolMap;
838838

839839
SmallVector<Decl *, 16> topLevelDecls;
840-
M->getTopLevelDecls(topLevelDecls);
840+
M->getTopLevelDeclsWithAuxiliaryDecls(topLevelDecls);
841841
for (const Decl *D : topLevelDecls) {
842842
InheritedProtocolCollector::collectProtocols(inheritedProtocolMap, D);
843843

0 commit comments

Comments
 (0)