Skip to content

Commit 28b80ad

Browse files
authored
Merge pull request #63039 from hborla/attribute-macros
[Macros] Implement attached macros that generate member attributes.
2 parents d70e16b + 0d71097 commit 28b80ad

Some content is hidden

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

45 files changed

+897
-111
lines changed

include/swift/AST/Attr.h

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2369,6 +2369,18 @@ class AttachedAttr final
23692369
}
23702370
};
23712371

2372+
/// Predicate used to filter MatchingAttributeRange.
2373+
template <typename ATTR, bool AllowInvalid> struct ToAttributeKind {
2374+
ToAttributeKind() {}
2375+
2376+
Optional<const ATTR *>
2377+
operator()(const DeclAttribute *Attr) const {
2378+
if (isa<ATTR>(Attr) && (Attr->isValid() || AllowInvalid))
2379+
return cast<ATTR>(Attr);
2380+
return None;
2381+
}
2382+
};
2383+
23722384
/// Attributes that may be applied to declarations.
23732385
class DeclAttributes {
23742386
/// Linked list of declaration attributes.
@@ -2542,19 +2554,6 @@ class DeclAttributes {
25422554
const_cast<const DeclAttributes *>(this)->getEffectiveSendableAttr());
25432555
}
25442556

2545-
private:
2546-
/// Predicate used to filter MatchingAttributeRange.
2547-
template <typename ATTR, bool AllowInvalid> struct ToAttributeKind {
2548-
ToAttributeKind() {}
2549-
2550-
Optional<const ATTR *>
2551-
operator()(const DeclAttribute *Attr) const {
2552-
if (isa<ATTR>(Attr) && (Attr->isValid() || AllowInvalid))
2553-
return cast<ATTR>(Attr);
2554-
return None;
2555-
}
2556-
};
2557-
25582557
public:
25592558
template <typename ATTR, bool AllowInvalid>
25602559
using AttributeKindRange =
@@ -2610,6 +2609,55 @@ class DeclAttributes {
26102609
SourceLoc getStartLoc(bool forModifiers = false) const;
26112610
};
26122611

2612+
/// Semantic attributes that are applied to a declaration.
2613+
///
2614+
/// This attribute list can include attributes that are not written in
2615+
/// source on a declaration, such as attributes that are applied during
2616+
/// macro expansion or inferred from the declaration context.
2617+
class SemanticDeclAttributes {
2618+
llvm::SmallVector<DeclAttribute *, 4> attrList;
2619+
2620+
public:
2621+
SemanticDeclAttributes() {}
2622+
2623+
/// Add a constructed DeclAttribute to this list.
2624+
void add(DeclAttribute *attr) {
2625+
attrList.push_back(attr);
2626+
}
2627+
2628+
using SemanticAttrList = llvm::SmallVectorImpl<DeclAttribute *>;
2629+
2630+
template <typename AttrType, bool AllowInvalid>
2631+
using AttributeKindRange =
2632+
OptionalTransformRange<iterator_range<SemanticAttrList::const_iterator>,
2633+
ToAttributeKind<AttrType, AllowInvalid>,
2634+
SemanticAttrList::const_iterator>;
2635+
2636+
template <typename AttrType, bool AllowInvalid = false>
2637+
AttributeKindRange<AttrType, AllowInvalid> getAttributes() const {
2638+
return AttributeKindRange<AttrType, AllowInvalid>(
2639+
make_range(attrList.begin(), attrList.end()),
2640+
ToAttributeKind<AttrType, AllowInvalid>());
2641+
}
2642+
2643+
/// Retrieve the first attribute of the given attribute class.
2644+
template <typename AttrType>
2645+
const AttrType *getAttribute(bool allowInvalid = false) const {
2646+
for (auto attr : attrList)
2647+
if (auto *specificAttr = dyn_cast<AttrType>(attr))
2648+
if (specificAttr->isValid() || allowInvalid)
2649+
return specificAttr;
2650+
2651+
return nullptr;
2652+
}
2653+
2654+
/// Determine whether there is an attribute with the given attribute class.
2655+
template <typename AttrType>
2656+
bool hasAttribute(bool allowInvalid = false) const {
2657+
return getAttribute<AttrType>(allowInvalid) != nullptr;
2658+
}
2659+
};
2660+
26132661
/// TypeAttributes - These are attributes that may be applied to types.
26142662
class TypeAttributes {
26152663
// Get a SourceLoc for every possible attribute that can be parsed in source.

include/swift/AST/Decl.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ enum class DescriptiveDeclKind : uint8_t {
191191
DidSet,
192192
EnumElement,
193193
Module,
194+
Missing,
194195
MissingMember,
195196
Requirement,
196197
OpaqueResultType,
@@ -849,6 +850,12 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
849850
return Attrs;
850851
}
851852

853+
/// Returns the semantic attributes attached to this declaration.
854+
///
855+
/// \c getSemanticAttrs is intended to be a requestified replacement
856+
/// for \c getAttrs
857+
SemanticDeclAttributes getSemanticAttrs() const;
858+
852859
/// Returns the innermost enclosing decl with an availability annotation.
853860
const Decl *getInnermostDeclWithAvailability() const;
854861

@@ -8276,6 +8283,34 @@ class PostfixOperatorDecl : public OperatorDecl {
82768283
}
82778284
};
82788285

8286+
/// Represents a missing declaration in the source code. This
8287+
/// is used for parser recovery, e.g. when parsing a floating
8288+
/// attribute list.
8289+
class MissingDecl: public Decl {
8290+
MissingDecl(DeclContext *DC) : Decl(DeclKind::Missing, DC) {
8291+
setImplicit();
8292+
}
8293+
8294+
friend class Decl;
8295+
SourceLoc getLocFromSource() const {
8296+
return SourceLoc();
8297+
}
8298+
8299+
public:
8300+
static MissingDecl *
8301+
create(ASTContext &ctx, DeclContext *DC) {
8302+
return new (ctx) MissingDecl(DC);
8303+
}
8304+
8305+
SourceRange getSourceRange() const {
8306+
return SourceRange();
8307+
}
8308+
8309+
static bool classof(const Decl *D) {
8310+
return D->getKind() == DeclKind::Missing;
8311+
}
8312+
};
8313+
82798314
/// Represents a hole where a declaration should have been.
82808315
///
82818316
/// Among other things, these are used to keep vtable layout consistent.

include/swift/AST/DeclNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ DECL(Import, Decl)
181181
DECL(IfConfig, Decl)
182182
DECL(PoundDiagnostic, Decl)
183183
DECL(PrecedenceGroup, Decl)
184+
DECL(Missing, Decl)
184185
DECL(MissingMember, Decl)
185186
DECL(PatternBinding, Decl)
186187
DECL(EnumCase, Decl)

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,6 +2044,10 @@ ERROR(macro_attribute_introduced_name_requires_argument,PointsToFirstBadToken,
20442044
ERROR(macro_attribute_introduced_name_requires_no_argument,PointsToFirstBadToken,
20452045
"introduced name kind %0 must not have an argument", (Identifier))
20462046

2047+
ERROR(unexpected_attribute_expansion,PointsToFirstBadToken,
2048+
"unexpected token '%0' in expanded attribute list'",
2049+
(StringRef))
2050+
20472051
ERROR(parser_round_trip_error,none,
20482052
"source file did not round-trip through the new Swift parser", ())
20492053
ERROR(parser_new_parser_errors,none,

include/swift/AST/MacroDeclaration.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ enum class MacroRole: uint32_t {
3232
/// An attached macro that declares accessors for a variable or subscript
3333
/// declaration.
3434
Accessor = 0x04,
35+
/// An attached macro that generates attributes for the
36+
/// members inside the declaration.
37+
MemberAttribute = 0x08,
3538
};
3639

3740
/// The contexts in which a particular macro declaration can be used.

include/swift/AST/SourceFile.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,17 @@ class SourceFile final : public FileUnit {
500500
/// the \c SourceFileKind is \c MacroExpansion.
501501
ASTNode getMacroExpansion() const;
502502

503+
/// For source files created to hold the source code created by expanding
504+
/// an attached macro, this is the custom attribute that describes the macro
505+
/// expansion.
506+
///
507+
/// The source location of this attribute is the place in the source that
508+
/// triggered the creation of the macro expansion whose resulting source
509+
/// code is in this source file. This will only produce a non-null value when
510+
/// the \c SourceFileKind is \c MacroExpansion , and the macro is an attached
511+
/// macro.
512+
CustomAttr *getAttachedMacroAttribute() const;
513+
503514
/// When this source file is enclosed within another source file, for example
504515
/// because it describes a macro expansion, return the source file it was
505516
/// enclosed in.

include/swift/AST/TypeCheckRequests.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,26 @@ class AttachedPropertyWrappersRequest :
742742
bool isCached() const { return true; }
743743
};
744744

745+
/// Request the semantic attributes attached to the given declaration.
746+
class AttachedSemanticAttrsRequest :
747+
public SimpleRequest<AttachedSemanticAttrsRequest,
748+
SemanticDeclAttributes(Decl *),
749+
RequestFlags::Cached> {
750+
public:
751+
using SimpleRequest::SimpleRequest;
752+
753+
private:
754+
friend SimpleRequest;
755+
756+
// Evaluation.
757+
SemanticDeclAttributes
758+
evaluate(Evaluator &evaluator, Decl *decl) const;
759+
760+
public:
761+
// Caching
762+
bool isCached() const { return true; }
763+
};
764+
745765
/// Request the raw (possibly unbound generic) type of the property wrapper
746766
/// that is attached to the given variable.
747767
class AttachedPropertyWrapperTypeRequest :

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ SWIFT_REQUEST(TypeChecker, AttachedPropertyWrapperTypeRequest,
2929
SWIFT_REQUEST(TypeChecker, AttachedPropertyWrappersRequest,
3030
llvm::TinyPtrVector<CustomAttr *>(VarDecl *), Cached,
3131
NoLocationInfo)
32+
SWIFT_REQUEST(TypeChecker, AttachedSemanticAttrsRequest,
33+
SemanticDeclAttributes(Decl *), Cached,
34+
NoLocationInfo)
3235
SWIFT_REQUEST(TypeChecker, CallerSideDefaultArgExprRequest,
3336
Expr *(DefaultArgumentExpr *), SeparatelyCached, NoLocationInfo)
3437
SWIFT_REQUEST(TypeChecker, CheckInconsistentImplementationOnlyImportsRequest,

include/swift/Basic/SourceManager.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,17 @@ class GeneratedSourceInfo {
3232
public:
3333
/// The kind of generated source code.
3434
enum Kind {
35-
/// The expansion of a macro.
36-
MacroExpansion,
35+
/// The expansion of a freestanding expression macro.
36+
ExpressionMacroExpansion,
37+
38+
/// The expansion of a freestanding declaration macro.
39+
FreestandingDeclMacroExpansion,
40+
41+
/// The expansion of an accessor attached macro.
42+
AccessorMacroExpansion,
43+
44+
/// The expansion of a member attribute attached macro.
45+
MemberAttributeMacroExpansion,
3746

3847
/// A new function body that is replacing an existing function body.
3948
ReplacedFunctionBody,

include/swift/Parse/Parser.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,11 @@ class Parser {
903903
/// Each item will be a declaration, statement, or expression.
904904
void parseTopLevelItems(SmallVectorImpl<ASTNode> &items);
905905

906+
/// Parse the source file via the Swift Parser using the ASTGen library.
907+
void parseSourceFileViaASTGen(SmallVectorImpl<ASTNode> &items,
908+
Optional<DiagnosticTransaction> &transaction,
909+
bool suppressDiagnostics = false);
910+
906911
/// Parse the top-level SIL decls into the SIL module.
907912
/// \returns \c true if there was a parsing error.
908913
bool parseTopLevelSIL();
@@ -1225,6 +1230,13 @@ class Parser {
12251230
AbstractStorageDecl *storage, SmallVectorImpl<ASTNode> &items
12261231
);
12271232

1233+
/// Parse the result of attribute macro expansion, which is a floating
1234+
/// attribute list.
1235+
///
1236+
/// Parsing a floating attribute list will produce a `MissingDecl` with
1237+
/// the attribute list attached.
1238+
void parseExpandedAttributeList(SmallVectorImpl<ASTNode> &items);
1239+
12281240
ParserResult<FuncDecl> parseDeclFunc(SourceLoc StaticLoc,
12291241
StaticSpellingKind StaticSpelling,
12301242
ParseDeclOptions Flags,

0 commit comments

Comments
 (0)