Skip to content

Commit 92ce766

Browse files
authored
Merge pull request #63035 from DougGregor/attached-attr
2 parents e963e0c + de16b47 commit 92ce766

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)