Skip to content

Commit 9e40280

Browse files
authored
Merge pull request swiftlang#63738 from bnbarham/macros-everywhere
[AST] Allow ignoring macro expansions
2 parents 89fec21 + 0c3f538 commit 9e40280

20 files changed

+186
-51
lines changed

include/swift/AST/ASTWalker.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,10 @@ class ASTWalker {
541541
/// TODO: Consider changing this to false by default.
542542
virtual bool shouldWalkSerializedTopLevelInternalDecls() { return true; }
543543

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+
544548
/// walkToParameterListPre - This method is called when first visiting a
545549
/// ParameterList, before walking into its parameters.
546550
///

include/swift/AST/Attr.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class ClassDecl;
5858
class GenericFunctionType;
5959
class LazyConformanceLoader;
6060
class LazyMemberLoader;
61+
class ModuleDecl;
6162
class PatternBindingInitializer;
6263
class TrailingWhereClause;
6364
class TypeExpr;
@@ -2581,6 +2582,59 @@ class DeclAttributes {
25812582
SourceLoc getStartLoc(bool forModifiers = false) const;
25822583
};
25832584

2585+
/// Attributes applied directly to the declaration.
2586+
///
2587+
/// We should really just have \c DeclAttributes and \c SemanticDeclAttributes,
2588+
/// but currently almost all callers expect the latter. Instead of changing all
2589+
/// callers of \c getAttrs, instead provide a way to retrieive the original
2590+
/// attributes.
2591+
class OrigDeclAttributes {
2592+
SmallVector<DeclAttribute *> attributes;
2593+
using AttrListTy = SmallVectorImpl<DeclAttribute *>;
2594+
2595+
public:
2596+
OrigDeclAttributes() = default;
2597+
2598+
OrigDeclAttributes(DeclAttributes semanticAttrs, ModuleDecl *mod);
2599+
2600+
2601+
using iterator = AttrListTy::iterator;
2602+
using const_iterator = AttrListTy::const_iterator;
2603+
2604+
iterator begin() { return attributes.begin(); }
2605+
iterator end() { return attributes.end(); }
2606+
const_iterator begin() const { return attributes.begin(); }
2607+
const_iterator end() const { return attributes.end(); }
2608+
2609+
template <typename AttrType, bool AllowInvalid>
2610+
using AttributeKindRange =
2611+
OptionalTransformRange<iterator_range<const_iterator>,
2612+
ToAttributeKind<AttrType, AllowInvalid>, const_iterator>;
2613+
2614+
template <typename AttrType, bool AllowInvalid = false>
2615+
AttributeKindRange<AttrType, AllowInvalid> getAttributes() const {
2616+
return AttributeKindRange<AttrType, AllowInvalid>(make_range(begin(), end()), ToAttributeKind<AttrType, AllowInvalid>());
2617+
}
2618+
2619+
/// Retrieve the first attribute of the given attribute class.
2620+
template <typename AttrType>
2621+
const AttrType *getAttribute(bool allowInvalid = false) const {
2622+
for (auto *attr : attributes) {
2623+
if (auto *specificAttr = dyn_cast<AttrType>(attr)) {
2624+
if (specificAttr->isValid() || allowInvalid)
2625+
return specificAttr;
2626+
}
2627+
}
2628+
return nullptr;
2629+
}
2630+
2631+
/// Determine whether there is an attribute with the given attribute class.
2632+
template <typename AttrType>
2633+
bool hasAttribute(bool allowInvalid = false) const {
2634+
return getAttribute<AttrType>(allowInvalid) != nullptr;
2635+
}
2636+
};
2637+
25842638
/// TypeAttributes - These are attributes that may be applied to types.
25852639
class TypeAttributes {
25862640
// Get a SourceLoc for every possible attribute that can be parsed in source.

include/swift/AST/Decl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,11 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
862862
/// with this declaration.
863863
ArrayRef<CustomAttr *> getRuntimeDiscoverableAttrs() const;
864864

865+
/// Returns the attributes that were directly attached to this declaration
866+
/// as written in source, ie. does not include attributes generated by macro
867+
/// expansions.
868+
OrigDeclAttributes getOriginalAttrs() const;
869+
865870
/// Returns the semantic attributes attached to this declaration,
866871
/// including attributes that are generated as the result of member
867872
/// attribute macro expansion.
@@ -923,6 +928,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
923928

924929
SourceLoc TrailingSemiLoc;
925930

931+
/// Whether this declaration is within a generated buffer, \c false if this
932+
/// declaration was constructed from a serialized module.
933+
bool isInGeneratedBuffer() const;
934+
926935
/// Returns the appropriate kind of entry point to generate for this class,
927936
/// based on its attributes.
928937
///

include/swift/AST/Module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@ class ModuleDecl
349349
/// \c nullptr if the source location isn't in this module.
350350
SourceFile *getSourceFileContainingLocation(SourceLoc loc);
351351

352+
/// Whether the given location is inside a generated buffer, \c false if
353+
/// the given location isn't in this module.
354+
bool isInGeneratedBuffer(SourceLoc loc);
355+
352356
/// Creates a map from \c #filePath strings to corresponding \c #fileID
353357
/// strings, diagnosing any conflicts.
354358
///

include/swift/IDE/SourceEntityWalker.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +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; }
207+
204208
protected:
205209
SourceEntityWalker() = default;
206210
SourceEntityWalker(const SourceEntityWalker &) = default;

include/swift/IDE/SyntaxModel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ struct SyntaxStructureElement {
139139
struct SyntaxStructureNode {
140140
const Decl *Dcl = nullptr;
141141
SyntaxStructureKind Kind;
142-
DeclAttributes Attrs;
142+
OrigDeclAttributes Attrs;
143143
CharSourceRange Range;
144144
CharSourceRange BodyRange;
145145
CharSourceRange NameRange;

lib/AST/ASTWalker.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -432,9 +432,11 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
432432
bool visitMacroExpansionDecl(MacroExpansionDecl *MED) {
433433
if (MED->getArgs() && doIt(MED->getArgs()))
434434
return true;
435-
for (auto *decl : MED->getRewritten())
436-
if (doIt(decl))
437-
return true;
435+
if (Walker.shouldWalkMacroExpansions()) {
436+
for (auto *decl : MED->getRewritten())
437+
if (doIt(decl))
438+
return true;
439+
}
438440
return false;
439441
}
440442

@@ -1295,17 +1297,19 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
12951297
}
12961298

12971299
Expr *visitMacroExpansionExpr(MacroExpansionExpr *E) {
1298-
Expr *rewritten = nullptr;
1299-
if (E->getRewritten()) {
1300-
rewritten = doIt(E->getRewritten());
1301-
if (!rewritten) return nullptr;
1302-
}
13031300
ArgumentList *args = nullptr;
13041301
if (E->getArgs()) {
13051302
args = doIt(E->getArgs());
13061303
if (!args) return nullptr;
13071304
}
1308-
E->setRewritten(rewritten);
1305+
if (Walker.shouldWalkMacroExpansions()) {
1306+
Expr *rewritten = nullptr;
1307+
if (E->getRewritten()) {
1308+
rewritten = doIt(E->getRewritten());
1309+
if (!rewritten) return nullptr;
1310+
}
1311+
E->setRewritten(rewritten);
1312+
}
13091313
E->setArgs(args);
13101314
return E;
13111315
}
@@ -1421,6 +1425,9 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
14211425
}
14221426

14231427
bool shouldSkip(Decl *D) {
1428+
if (!Walker.shouldWalkMacroExpansions() && D->isInGeneratedBuffer())
1429+
return true;
1430+
14241431
if (auto *VD = dyn_cast<VarDecl>(D)) {
14251432
// VarDecls are walked via their NamedPattern, ignore them if we encounter
14261433
// then in the few cases where they are also pushed outside as members.

lib/AST/Attr.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,14 @@ SourceLoc DeclAttributes::getStartLoc(bool forModifiers) const {
851851
return lastAttr ? lastAttr->getRangeWithAt().Start : SourceLoc();
852852
}
853853

854+
OrigDeclAttributes::OrigDeclAttributes(DeclAttributes allAttributes, ModuleDecl *mod) {
855+
for (auto *attr : allAttributes) {
856+
if (!mod->isInGeneratedBuffer(attr->AtLoc)) {
857+
attributes.emplace_back(attr);
858+
}
859+
}
860+
}
861+
854862
static void printAvailableAttr(const AvailableAttr *Attr, ASTPrinter &Printer,
855863
const PrintOptions &Options) {
856864
if (Attr->isLanguageVersionSpecific())

lib/AST/Decl.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,10 @@ StringRef Decl::getDescriptiveKindName(DescriptiveDeclKind K) {
367367
llvm_unreachable("bad DescriptiveDeclKind");
368368
}
369369

370+
OrigDeclAttributes Decl::getOriginalAttrs() const {
371+
return OrigDeclAttributes(getAttrs(), getModuleContext());
372+
}
373+
370374
DeclAttributes Decl::getSemanticAttrs() const {
371375
auto mutableThis = const_cast<Decl *>(this);
372376
(void)evaluateOrDefault(getASTContext().evaluator,
@@ -684,7 +688,7 @@ SourceRange Decl::getSourceRangeIncludingAttrs() const {
684688

685689
// Otherwise, include attributes directly attached to the accessor.
686690
SourceLoc VarLoc = AD->getStorage()->getStartLoc();
687-
for (auto Attr : getAttrs()) {
691+
for (auto *Attr : getOriginalAttrs()) {
688692
if (!Attr->getRange().isValid())
689693
continue;
690694

@@ -703,19 +707,23 @@ SourceRange Decl::getSourceRangeIncludingAttrs() const {
703707
if (auto *PBD = dyn_cast<PatternBindingDecl>(this)) {
704708
for (auto i : range(PBD->getNumPatternEntries()))
705709
PBD->getPattern(i)->forEachVariable([&](VarDecl *VD) {
706-
for (auto Attr : VD->getAttrs())
710+
for (auto *Attr : VD->getOriginalAttrs())
707711
if (Attr->getRange().isValid())
708712
Range.widen(Attr->getRangeWithAt());
709713
});
710714
}
711715

712-
for (auto Attr : getAttrs()) {
716+
for (auto *Attr : getOriginalAttrs()) {
713717
if (Attr->getRange().isValid())
714718
Range.widen(Attr->getRangeWithAt());
715719
}
716720
return Range;
717721
}
718722

723+
bool Decl::isInGeneratedBuffer() const {
724+
return getModuleContext()->isInGeneratedBuffer(getStartLoc());
725+
}
726+
719727
SourceLoc Decl::getLocFromSource() const {
720728
switch (getKind()) {
721729
#define DECL(ID, X) \

lib/AST/Module.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,13 @@ SourceFile *ModuleDecl::getSourceFileContainingLocation(SourceLoc loc) {
648648
return foundSourceFile;
649649
}
650650

651+
bool ModuleDecl::isInGeneratedBuffer(SourceLoc loc) {
652+
SourceFile *file = getSourceFileContainingLocation(loc);
653+
if (!file)
654+
return false;
655+
return file->Kind == SourceFileKind::MacroExpansion;
656+
}
657+
651658
ArrayRef<SourceFile *>
652659
PrimarySourceFilesRequest::evaluate(Evaluator &evaluator,
653660
ModuleDecl *mod) const {

0 commit comments

Comments
 (0)