Skip to content

Commit de16b47

Browse files
committed
[Macros] Introduce the @attached attribute for declaring attached macros.
Describe attached macros with the `@attached` attribute, providing the macro role and affected names as arguments to the macro. The form of this macro will remain the same as it gains other kinds of attached macro roles beyond "accessor". Remove the "accessors" role from `@declaration`, which will be going away.
1 parent 8c3bd02 commit de16b47

24 files changed

+474
-62
lines changed

include/swift/AST/Attr.h

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,17 +2308,17 @@ class DeclarationAttr final
23082308
private llvm::TrailingObjects<DeclarationAttr, MacroIntroducedDeclName> {
23092309
friend TrailingObjects;
23102310

2311-
MacroContext macroContext;
2311+
MacroRole role;
23122312
unsigned numPeerNames, numMemberNames;
23132313

2314-
DeclarationAttr(SourceLoc atLoc, SourceRange range, MacroContext macroContext,
2314+
DeclarationAttr(SourceLoc atLoc, SourceRange range, MacroRole role,
23152315
ArrayRef<MacroIntroducedDeclName> peerNames,
23162316
ArrayRef<MacroIntroducedDeclName> memberNames,
23172317
bool implicit);
23182318

23192319
public:
23202320
static DeclarationAttr *create(ASTContext &ctx, SourceLoc atLoc,
2321-
SourceRange range, MacroContext macroContext,
2321+
SourceRange range, MacroRole role,
23222322
ArrayRef<MacroIntroducedDeclName> peerNames,
23232323
ArrayRef<MacroIntroducedDeclName> memberNames,
23242324
bool implicit);
@@ -2327,7 +2327,7 @@ class DeclarationAttr final
23272327
return numPeerNames + numMemberNames;
23282328
}
23292329

2330-
MacroContext getMacroContext() const { return macroContext; }
2330+
MacroRole getMacroRole() const { return role; }
23312331
ArrayRef<MacroIntroducedDeclName> getPeerAndMemberNames() const;
23322332
ArrayRef<MacroIntroducedDeclName> getPeerNames() const;
23332333
ArrayRef<MacroIntroducedDeclName> getMemberNames() const;
@@ -2337,6 +2337,38 @@ class DeclarationAttr final
23372337
}
23382338
};
23392339

2340+
/// The @attached attribute, which declares that a given macro can be
2341+
/// "attached" as an attribute to declarations.
2342+
class AttachedAttr final
2343+
: public DeclAttribute,
2344+
private llvm::TrailingObjects<AttachedAttr, MacroIntroducedDeclName> {
2345+
friend TrailingObjects;
2346+
2347+
MacroRole role;
2348+
unsigned numNames;
2349+
2350+
AttachedAttr(SourceLoc atLoc, SourceRange range, MacroRole role,
2351+
ArrayRef<MacroIntroducedDeclName> names,
2352+
bool implicit);
2353+
2354+
public:
2355+
static AttachedAttr *create(ASTContext &ctx, SourceLoc atLoc,
2356+
SourceRange range, MacroRole role,
2357+
ArrayRef<MacroIntroducedDeclName> names,
2358+
bool implicit);
2359+
2360+
size_t numTrailingObjects(OverloadToken<MacroIntroducedDeclName>) const {
2361+
return numNames;
2362+
}
2363+
2364+
MacroRole getMacroRole() const { return role; }
2365+
ArrayRef<MacroIntroducedDeclName> getNames() const;
2366+
2367+
static bool classof(const DeclAttribute *DA) {
2368+
return DA->getKind() == DAK_Attached;
2369+
}
2370+
};
2371+
23402372
/// Attributes that may be applied to declarations.
23412373
class DeclAttributes {
23422374
/// Linked list of declaration attributes.

include/swift/AST/Decl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8372,7 +8372,7 @@ class MacroDecl : public GenericContext, public ValueDecl {
83728372
Type getResultInterfaceType() const;
83738373

83748374
/// Determine the contexts in which this macro can be applied.
8375-
MacroContexts getMacroContexts() const;
8375+
MacroRoles getMacroRoles() const;
83768376

83778377
/// Retrieve the definition of this macro.
83788378
MacroDefinition getDefinition() const;

include/swift/AST/DiagnosticsParse.def

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,6 +2020,30 @@ ERROR(macro_expansion_decl_expected_macro_identifier,PointsToFirstBadToken,
20202020
ERROR(declaration_attr_expected_kind,PointsToFirstBadToken,
20212021
"expected a declaration macro kind ('freestanding' or 'attached')", ())
20222022

2023+
ERROR(macro_role_attr_expected_kind,PointsToFirstBadToken,
2024+
"expected %select{a freestanding|an attached}0 macro role such as "
2025+
"%select{'expression'|'accessor'}0", (bool))
2026+
ERROR(macro_role_syntax_mismatch,PointsToFirstBadToken,
2027+
"expected %select{a freestanding|an attached}0 macro cannot have "
2028+
"the %1 role", (bool, Identifier))
2029+
ERROR(macro_attribute_unknown_label,PointsToFirstBadToken,
2030+
"@%select{freestanding|attached}0 has no argument with label %1",
2031+
(bool, Identifier))
2032+
ERROR(macro_attribute_duplicate_label,PointsToFirstBadToken,
2033+
"@%select{freestanding|attached}0 already has an argument with "
2034+
"label %1", (bool, Identifier))
2035+
ERROR(macro_attribute_missing_label,PointsToFirstBadToken,
2036+
"@%select{freestanding|attached}0 argument is missing label '%1'",
2037+
(bool, StringRef))
2038+
ERROR(macro_attribute_unknown_name_kind,PointsToFirstBadToken,
2039+
"unknown introduced name kind %0", (Identifier))
2040+
ERROR(macro_attribute_unknown_argument_form,PointsToFirstBadToken,
2041+
"introduced name argument should be an identifier", ())
2042+
ERROR(macro_attribute_introduced_name_requires_argument,PointsToFirstBadToken,
2043+
"introduced name kind %0 requires a single argument '(name)'", (Identifier))
2044+
ERROR(macro_attribute_introduced_name_requires_no_argument,PointsToFirstBadToken,
2045+
"introduced name kind %0 must not have an argument", (Identifier))
2046+
20232047
ERROR(parser_round_trip_error,none,
20242048
"source file did not round-trip through the new Swift parser", ())
20252049
ERROR(parser_new_parser_errors,none,

include/swift/AST/MacroDeclaration.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,31 @@ namespace swift {
2323

2424
/// The context in which a macro can be used, which determines the syntax it
2525
/// uses.
26-
enum class MacroContext: uint8_t {
26+
enum class MacroRole: uint32_t {
2727
/// An expression macro, referenced explicitly via "#stringify" or similar
2828
/// in the source code.
2929
Expression = 0x01,
3030
/// A freestanding declaration macro.
3131
FreestandingDeclaration = 0x02,
32-
/// An attached declaration macro.
33-
AttachedDeclaration = 0x04,
32+
/// An attached macro that declares accessors for a variable or subscript
33+
/// declaration.
34+
Accessor = 0x04,
3435
};
3536

3637
/// The contexts in which a particular macro declaration can be used.
37-
using MacroContexts = OptionSet<MacroContext>;
38+
using MacroRoles = OptionSet<MacroRole>;
39+
40+
/// Whether a macro with the given set of macro contexts is freestanding, i.e.,
41+
/// written in the source code with the `#` syntax.
42+
bool isFreestandingMacro(MacroRoles contexts);
43+
44+
/// Whether a macro with the given set of macro contexts is attached, i.e.,
45+
/// written in the source code as an attribute with the `@` syntax.
46+
bool isAttachedMacro(MacroRoles contexts);
3847

3948
enum class MacroIntroducedDeclNameKind {
4049
Named,
4150
Overloaded,
42-
Accessors,
4351
Prefixed,
4452
Suffixed,
4553
Arbitrary,
@@ -65,10 +73,6 @@ class MacroIntroducedDeclName {
6573
return MacroIntroducedDeclName(Kind::Overloaded);
6674
}
6775

68-
static MacroIntroducedDeclName getAccessors() {
69-
return MacroIntroducedDeclName(Kind::Accessors);
70-
}
71-
7276
static MacroIntroducedDeclName getPrefixed(Identifier prefix) {
7377
return MacroIntroducedDeclName(Kind::Prefixed, prefix);
7478
}

include/swift/Parse/Parser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,10 @@ class Parser {
11001100
ParserResult<DeclarationAttr> parseDeclarationAttribute(SourceLoc AtLoc,
11011101
SourceLoc Loc);
11021102

1103+
/// Parse the @attached attribute.
1104+
ParserResult<AttachedAttr> parseAttachedAttribute(SourceLoc AtLoc,
1105+
SourceLoc Loc);
1106+
11031107
/// Parse a specific attribute.
11041108
ParserStatus parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
11051109
PatternBindingInitializer *&initContext,

lib/AST/Attr.cpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,8 @@ StringRef DeclAttribute::getAttrName() const {
14851485
return "_documentation";
14861486
case DAK_Declaration:
14871487
return "declaration";
1488+
case DAK_Attached:
1489+
return "attached";
14881490
}
14891491
llvm_unreachable("bad DeclAttrKind");
14901492
}
@@ -2311,12 +2313,12 @@ bool CustomAttr::isArgUnsafe() const {
23112313
}
23122314

23132315
DeclarationAttr::DeclarationAttr(SourceLoc atLoc, SourceRange range,
2314-
MacroContext macroContext,
2316+
MacroRole role,
23152317
ArrayRef<MacroIntroducedDeclName> peerNames,
23162318
ArrayRef<MacroIntroducedDeclName> memberNames,
23172319
bool implicit)
23182320
: DeclAttribute(DAK_Declaration, atLoc, range, implicit),
2319-
macroContext(macroContext), numPeerNames(peerNames.size()),
2321+
role(role), numPeerNames(peerNames.size()),
23202322
numMemberNames(memberNames.size()) {
23212323
auto *trailingNamesBuffer = getTrailingObjects<MacroIntroducedDeclName>();
23222324
std::uninitialized_copy(peerNames.begin(), peerNames.end(),
@@ -2327,14 +2329,14 @@ DeclarationAttr::DeclarationAttr(SourceLoc atLoc, SourceRange range,
23272329

23282330
DeclarationAttr *
23292331
DeclarationAttr::create(ASTContext &ctx, SourceLoc atLoc, SourceRange range,
2330-
MacroContext macroContext,
2332+
MacroRole role,
23312333
ArrayRef<MacroIntroducedDeclName> peerNames,
23322334
ArrayRef<MacroIntroducedDeclName> memberNames,
23332335
bool implicit) {
23342336
unsigned size = totalSizeToAlloc<MacroIntroducedDeclName>(
23352337
peerNames.size() + memberNames.size());
23362338
auto *mem = ctx.Allocate(size, alignof(DeclarationAttr));
2337-
return new (mem) DeclarationAttr(atLoc, range, macroContext, peerNames,
2339+
return new (mem) DeclarationAttr(atLoc, range, role, peerNames,
23382340
memberNames, implicit);
23392341
}
23402342

@@ -2356,6 +2358,34 @@ ArrayRef<MacroIntroducedDeclName> DeclarationAttr::getMemberNames() const {
23562358
};
23572359
}
23582360

2361+
AttachedAttr::AttachedAttr(SourceLoc atLoc, SourceRange range,
2362+
MacroRole role,
2363+
ArrayRef<MacroIntroducedDeclName> names,
2364+
bool implicit)
2365+
: DeclAttribute(DAK_Attached, atLoc, range, implicit),
2366+
role(role), numNames(names.size()) {
2367+
auto *trailingNamesBuffer = getTrailingObjects<MacroIntroducedDeclName>();
2368+
std::uninitialized_copy(names.begin(), names.end(), trailingNamesBuffer);
2369+
}
2370+
2371+
AttachedAttr *
2372+
AttachedAttr::create(ASTContext &ctx, SourceLoc atLoc, SourceRange range,
2373+
MacroRole role,
2374+
ArrayRef<MacroIntroducedDeclName> names,
2375+
bool implicit) {
2376+
unsigned size = totalSizeToAlloc<MacroIntroducedDeclName>(names.size());
2377+
auto *mem = ctx.Allocate(size, alignof(AttachedAttr));
2378+
return new (mem) AttachedAttr(atLoc, range, role, names, implicit);
2379+
}
2380+
2381+
ArrayRef<MacroIntroducedDeclName> AttachedAttr::getNames() const {
2382+
return {
2383+
getTrailingObjects<MacroIntroducedDeclName>(),
2384+
numNames
2385+
};
2386+
}
2387+
2388+
23592389
const DeclAttribute *
23602390
DeclAttributes::getEffectiveSendableAttr() const {
23612391
const NonSendableAttr *assumedAttr = nullptr;

lib/AST/Decl.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9672,6 +9672,20 @@ BuiltinTupleDecl::BuiltinTupleDecl(Identifier Name, DeclContext *Parent)
96729672
: NominalTypeDecl(DeclKind::BuiltinTuple, Parent, Name, SourceLoc(),
96739673
ArrayRef<InheritedEntry>(), nullptr) {}
96749674

9675+
static MacroRoles freestandingMacroRoles =
9676+
(MacroRoles() |
9677+
MacroRole::Expression |
9678+
MacroRole::FreestandingDeclaration);
9679+
static MacroRoles attachedMacroRoles = (MacroRoles() | MacroRole::Accessor);
9680+
9681+
bool swift::isFreestandingMacro(MacroRoles contexts) {
9682+
return bool(contexts & freestandingMacroRoles);
9683+
}
9684+
9685+
bool swift::isAttachedMacro(MacroRoles contexts) {
9686+
return bool(contexts & attachedMacroRoles);
9687+
}
9688+
96759689
MacroDecl::MacroDecl(
96769690
SourceLoc macroLoc, DeclName name, SourceLoc nameLoc,
96779691
GenericParamList *genericParams,
@@ -9712,12 +9726,14 @@ SourceRange MacroDecl::getSourceRange() const {
97129726
return SourceRange(macroLoc, endLoc);
97139727
}
97149728

9715-
MacroContexts MacroDecl::getMacroContexts() const {
9716-
MacroContexts contexts = None;
9729+
MacroRoles MacroDecl::getMacroRoles() const {
9730+
MacroRoles contexts = None;
97179731
if (getAttrs().hasAttribute<ExpressionAttr>())
9718-
contexts |= MacroContext::Expression;
9732+
contexts |= MacroRole::Expression;
97199733
for (auto attr : getAttrs().getAttributes<DeclarationAttr>())
9720-
contexts |= attr->getMacroContext();
9734+
contexts |= attr->getMacroRole();
9735+
for (auto attr : getAttrs().getAttributes<AttachedAttr>())
9736+
contexts |= attr->getMacroRole();
97219737
return contexts;
97229738
}
97239739

lib/AST/NameLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3061,7 +3061,7 @@ static MacroDecl *findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc) {
30613061
for (const auto &result : lookup.allResults()) {
30623062
// Only keep attached macros, which can be spelled as custom attributes.
30633063
if (auto macro = dyn_cast<MacroDecl>(result.getValueDecl()))
3064-
if (macro->getMacroContexts().contains(MacroContext::AttachedDeclaration))
3064+
if (isAttachedMacro(macro->getMacroRoles()))
30653065
macros.push_back(macro);
30663066
}
30673067

0 commit comments

Comments
 (0)