Skip to content

Commit 43cadca

Browse files
committed
[Macros] Serialization and printing for @attached.
1 parent de16b47 commit 43cadca

File tree

8 files changed

+120
-17
lines changed

8 files changed

+120
-17
lines changed

include/swift/AST/MacroDeclaration.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ enum class MacroRole: uint32_t {
3737
/// The contexts in which a particular macro declaration can be used.
3838
using MacroRoles = OptionSet<MacroRole>;
3939

40+
/// Retrieve the string form of the given macro role, as written on the
41+
/// corresponding attribute.
42+
StringRef getMacroRoleString(MacroRole role);
43+
4044
/// Whether a macro with the given set of macro contexts is freestanding, i.e.,
4145
/// written in the source code with the `#` syntax.
4246
bool isFreestandingMacro(MacroRoles contexts);
@@ -53,6 +57,12 @@ enum class MacroIntroducedDeclNameKind {
5357
Arbitrary,
5458
};
5559

60+
/// Whether a macro-introduced name of this kind requires an argument.
61+
bool macroIntroducedNameRequiresArgument(MacroIntroducedDeclNameKind kind);
62+
63+
StringRef getMacroIntroducedDeclNameString(
64+
MacroIntroducedDeclNameKind kind);
65+
5666
class MacroIntroducedDeclName {
5767
public:
5868
using Kind = MacroIntroducedDeclNameKind;

lib/AST/Attr.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,30 @@ bool DeclAttribute::printImpl(ASTPrinter &Printer, const PrintOptions &Options,
13091309
break;
13101310
}
13111311

1312+
case DAK_Attached: {
1313+
Printer.printAttrName("@attached");
1314+
Printer << "(";
1315+
auto Attr = cast<AttachedAttr>(this);
1316+
Printer << getMacroRoleString(Attr->getMacroRole());
1317+
if (!Attr->getNames().empty()) {
1318+
Printer << ", names: ";
1319+
interleave(
1320+
Attr->getNames(),
1321+
[&](MacroIntroducedDeclName name) {
1322+
Printer << getMacroIntroducedDeclNameString(name.getKind());
1323+
if (macroIntroducedNameRequiresArgument(name.getKind())) {
1324+
Printer << "(" << name.getIdentifier() << ")";
1325+
}
1326+
},
1327+
[&] {
1328+
Printer << ", ";
1329+
}
1330+
);
1331+
}
1332+
Printer << ")";
1333+
break;
1334+
}
1335+
13121336
case DAK_Count:
13131337
llvm_unreachable("exceed declaration attribute kinds");
13141338

lib/AST/Decl.cpp

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

9675+
StringRef swift::getMacroRoleString(MacroRole role) {
9676+
switch (role) {
9677+
case MacroRole::Expression:
9678+
return "expression";
9679+
9680+
case MacroRole::FreestandingDeclaration:
9681+
return "freestanding";
9682+
9683+
case MacroRole::Accessor:
9684+
return "accessor";
9685+
}
9686+
}
9687+
9688+
bool swift::macroIntroducedNameRequiresArgument(
9689+
MacroIntroducedDeclNameKind kind
9690+
) {
9691+
switch (kind) {
9692+
case MacroIntroducedDeclNameKind::Named:
9693+
case MacroIntroducedDeclNameKind::Prefixed:
9694+
case MacroIntroducedDeclNameKind::Suffixed:
9695+
return true;
9696+
9697+
case MacroIntroducedDeclNameKind::Overloaded:
9698+
case MacroIntroducedDeclNameKind::Arbitrary:
9699+
return false;
9700+
}
9701+
}
9702+
9703+
StringRef swift::getMacroIntroducedDeclNameString(
9704+
MacroIntroducedDeclNameKind kind) {
9705+
switch (kind) {
9706+
case MacroIntroducedDeclNameKind::Named:
9707+
return "named";
9708+
9709+
case MacroIntroducedDeclNameKind::Overloaded:
9710+
return "overloaded";
9711+
9712+
case MacroIntroducedDeclNameKind::Prefixed:
9713+
return "prefixed";
9714+
9715+
case MacroIntroducedDeclNameKind::Suffixed:
9716+
return "suffixed";
9717+
9718+
case MacroIntroducedDeclNameKind::Arbitrary:
9719+
return "arbitrary";
9720+
}
9721+
}
9722+
96759723
static MacroRoles freestandingMacroRoles =
96769724
(MacroRoles() |
96779725
MacroRole::Expression |

lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,21 +2236,6 @@ static Optional<MacroRole> getMacroRole(
22362236
return role;
22372237
}
22382238

2239-
/// Determine whether a macro-introduced name requires an argument (which is
2240-
/// always a string literal).
2241-
static bool introducedNameRequiresArgument(MacroIntroducedDeclNameKind kind) {
2242-
switch (kind) {
2243-
case MacroIntroducedDeclNameKind::Named:
2244-
case MacroIntroducedDeclNameKind::Prefixed:
2245-
case MacroIntroducedDeclNameKind::Suffixed:
2246-
return true;
2247-
2248-
case MacroIntroducedDeclNameKind::Overloaded:
2249-
case MacroIntroducedDeclNameKind::Arbitrary:
2250-
return false;
2251-
}
2252-
}
2253-
22542239
static Optional<MacroIntroducedDeclNameKind>
22552240
getMacroIntroducedDeclNameKind(Identifier name) {
22562241
return llvm::StringSwitch<Optional<MacroIntroducedDeclNameKind>>(name.str())
@@ -2307,7 +2292,7 @@ static SmallVector<MacroIntroducedDeclName, 2> getMacroIntroducedNames(
23072292
continue;
23082293
}
23092294

2310-
if (introducedNameRequiresArgument(*introducedKind)) {
2295+
if (macroIntroducedNameRequiresArgument(*introducedKind)) {
23112296
diags.diagnose(
23122297
arg.getExpr()->getLoc(),
23132298
diag::macro_attribute_introduced_name_requires_argument,
@@ -2352,7 +2337,7 @@ static SmallVector<MacroIntroducedDeclName, 2> getMacroIntroducedNames(
23522337
continue;
23532338
}
23542339

2355-
if (!introducedNameRequiresArgument(*introducedKind)) {
2340+
if (!macroIntroducedNameRequiresArgument(*introducedKind)) {
23562341
diags.diagnose(
23572342
call->getArgs()->getLoc(),
23582343
diag::macro_attribute_introduced_name_requires_no_argument,

lib/Serialization/Deserialization.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5447,6 +5447,30 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
54475447
break;
54485448
}
54495449

5450+
case decls_block::Attached_DECL_ATTR: {
5451+
bool isImplicit;
5452+
uint8_t rawMacroRole;
5453+
uint64_t numNames;
5454+
ArrayRef<uint64_t> introducedDeclNames;
5455+
serialization::decls_block::AttachedDeclAttrLayout::
5456+
readRecord(scratch, isImplicit, rawMacroRole, numNames,
5457+
introducedDeclNames);
5458+
auto role = *getActualMacroRole(rawMacroRole);
5459+
if (introducedDeclNames.size() != numNames * 2)
5460+
return MF.diagnoseFatal();
5461+
SmallVector<MacroIntroducedDeclName, 1> names;
5462+
for (unsigned i = 0; i < introducedDeclNames.size(); i += 2) {
5463+
auto kind = getActualMacroIntroducedDeclNameKind(
5464+
(uint8_t)introducedDeclNames[i]);
5465+
auto identifier =
5466+
MF.getIdentifier(IdentifierID(introducedDeclNames[i + 1]));
5467+
names.push_back(MacroIntroducedDeclName(*kind, identifier));
5468+
}
5469+
Attr = AttachedAttr::create(
5470+
ctx, SourceLoc(), SourceRange(), role, names, isImplicit);
5471+
break;
5472+
}
5473+
54505474
#define SIMPLE_DECL_ATTR(NAME, CLASS, ...) \
54515475
case decls_block::CLASS##_DECL_ATTR: { \
54525476
bool isImplicit; \

test/ModuleInterface/macros.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,10 @@
1616
// CHECK-NEXT: #endif
1717
@expression public macro publicLine<T: ExpressibleByIntegerLiteral>: T = #externalMacro(module: "SomeModule", type: "Line")
1818

19+
// CHECK: #if compiler(>=5.3) && $Macros
20+
// CHECK: @attached(accessor) public macro myWrapper: Swift.Void = #externalMacro(module: "SomeModule", type: "Wrapper")
21+
// CHECK-NEXT: #endif
22+
@attached(accessor) public macro myWrapper: Void = #externalMacro(module: "SomeModule", type: "Wrapper")
23+
1924
// CHECK-NOT: internalStringify
2025
@expression macro internalStringify<T>(_ value: T) -> (T, String) = #externalMacro(module: "SomeModule", type: "StringifyMacro")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
@expression public macro publicStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro
22

33
@expression macro internalStringify<T>(_ value: T) -> (T, String) = SomeModule.StringifyMacro
4+
5+
@attached(accessor) public macro myWrapper: Void = SomeModule.MyWrapperMacro

test/Serialization/macros.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,8 @@ func test(a: Int, b: Int) {
1515
_ = #internalStringify(a + b)
1616
// expected-error@-1{{no macro named 'internalStringify'}}
1717
}
18+
19+
struct TestStruct {
20+
@myWrapper var x: Int
21+
// expected-error@-1{{external macro implementation type 'SomeModule.MyWrapperMacro' could not be found for macro 'myWrapper'}}
22+
}

0 commit comments

Comments
 (0)