Skip to content

Commit 2bcef82

Browse files
authored
Merge pull request #65032 from DougGregor/attached-macro-mangle-without-cycles
2 parents 6ec8a8c + fb82b8f commit 2bcef82

14 files changed

+140
-70
lines changed

docs/ABI/Mangling.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,13 @@ Entities
396396

397397
macro-discriminator-list ::= macro-discriminator-list? file-discriminator? macro-expansion-operator INDEX
398398

399-
macro-expansion-operator ::= identifier 'fMa' // attached accessor macro
400-
macro-expansion-operator ::= identifier 'fMA' // attached member-attribute macro
399+
macro-expansion-operator ::= decl-name identifier 'fMa' // attached accessor macro
400+
macro-expansion-operator ::= decl-name identifier 'fMA' // attached member-attribute macro
401401
macro-expansion-operator ::= identifier 'fMf' // freestanding macro
402-
macro-expansion-operator ::= identifier 'fMm' // attached member macro
403-
macro-expansion-operator ::= identifier 'fMp' // attached peer macro
404-
macro-expansion-operator ::= identifier 'fMc' // attached conformance macro
405-
macro-expansion-operator ::= identifier 'fMu' // uniquely-named entity
402+
macro-expansion-operator ::= decl-name identifier 'fMm' // attached member macro
403+
macro-expansion-operator ::= decl-name identifier 'fMp' // attached peer macro
404+
macro-expansion-operator ::= decl-name identifier 'fMc' // attached conformance macro
405+
macro-expansion-operator ::= decl-name identifier 'fMu' // uniquely-named entity
406406

407407
file-discriminator ::= identifier 'Ll' // anonymous file-discriminated declaration
408408

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,8 @@ class ASTMangler : public Mangler {
401401
void appendType(Type type, GenericSignature sig,
402402
const ValueDecl *forDecl = nullptr);
403403

404-
void appendDeclName(const ValueDecl *decl);
404+
void appendDeclName(
405+
const ValueDecl *decl, DeclBaseName name = DeclBaseName());
405406

406407
GenericTypeParamType *appendAssocType(DependentMemberType *DepTy,
407408
GenericSignature sig,

lib/AST/ASTMangler.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,8 +1006,9 @@ static Optional<std::string> getOverriddenSwiftProtocolObjCName(
10061006
return None;
10071007
}
10081008

1009-
void ASTMangler::appendDeclName(const ValueDecl *decl) {
1010-
DeclBaseName name = decl->getBaseName();
1009+
void ASTMangler::appendDeclName(const ValueDecl *decl, DeclBaseName name) {
1010+
if (name.empty())
1011+
name = decl->getBaseName();
10111012
assert(!name.isSpecial() && "Cannot print special names");
10121013

10131014
auto *synthesizedTypeAttr =
@@ -4022,28 +4023,43 @@ std::string ASTMangler::mangleAttachedMacroExpansion(
40224023
const Decl *decl, CustomAttr *attr, MacroRole role) {
40234024
beginMangling();
40244025

4026+
// Append the context and name of the declaration.
4027+
// We don't mangle the declaration itself because doing so requires semantic
4028+
// information (e.g., its interface type), which introduces cyclic
4029+
// dependencies.
40254030
const Decl *attachedTo = decl;
4031+
DeclBaseName attachedToName;
40264032
if (auto valueDecl = dyn_cast<ValueDecl>(decl)) {
4027-
if (role != MacroRole::MemberAttribute) {
4028-
appendAnyDecl(valueDecl);
4029-
} else {
4030-
// Appending the member would result in a cycle since `VarDecl` appends
4031-
// its type, which would then loop back around to getting the attributes
4032-
// again. We'll instead add a discriminator for each member.
4033-
appendContextOf(valueDecl);
4033+
appendContextOf(valueDecl);
4034+
4035+
// Mangle the name, replacing special names with their user-facing names.
4036+
attachedToName = valueDecl->getName().getBaseName();
4037+
if (attachedToName.isSpecial()) {
4038+
attachedToName =
4039+
decl->getASTContext().getIdentifier(attachedToName.userFacingName());
4040+
}
4041+
appendDeclName(valueDecl, attachedToName);
4042+
4043+
// For member attribute macros, the attribute is attached to the enclosing
4044+
// declaration.
4045+
if (role == MacroRole::MemberAttribute) {
40344046
attachedTo = decl->getDeclContext()->getAsDecl();
40354047
}
40364048
} else {
40374049
appendContext(decl->getDeclContext(), "");
4050+
appendIdentifier("_");
40384051
}
40394052

4053+
// Determine the name of the macro.
40404054
DeclBaseName macroName;
40414055
if (auto *macroDecl = attachedTo->getResolvedMacro(attr)) {
40424056
macroName = macroDecl->getName().getBaseName();
40434057
} else {
40444058
macroName = decl->getASTContext().getIdentifier("__unknown_macro__");
40454059
}
40464060

4061+
// FIXME: attached macro discriminators should take attachedToName into
4062+
// account.
40474063
appendMacroExpansionOperator(
40484064
macroName.userFacingName(), role,
40494065
decl->getAttachedMacroDiscriminator(macroName, role, attr));

lib/Demangling/Demangler.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4061,47 +4061,74 @@ static bool isMacroExpansionNodeKind(Node::Kind kind) {
40614061

40624062
NodePointer Demangler::demangleMacroExpansion() {
40634063
Node::Kind kind;
4064+
bool isAttached;
4065+
bool isFreestanding;
40644066
switch (nextChar()) {
40654067
case 'a':
40664068
kind = Node::Kind::AccessorAttachedMacroExpansion;
4069+
isAttached = true;
4070+
isFreestanding = false;
40674071
break;
40684072

40694073
case 'A':
40704074
kind = Node::Kind::MemberAttributeAttachedMacroExpansion;
4075+
isAttached = true;
4076+
isFreestanding = false;
40714077
break;
40724078

40734079
case 'f':
40744080
kind = Node::Kind::FreestandingMacroExpansion;
4081+
isAttached = false;
4082+
isFreestanding = true;
40754083
break;
40764084

40774085
case 'm':
40784086
kind = Node::Kind::MemberAttachedMacroExpansion;
4087+
isAttached = true;
4088+
isFreestanding = false;
40794089
break;
40804090

40814091
case 'p':
40824092
kind = Node::Kind::PeerAttachedMacroExpansion;
4093+
isAttached = true;
4094+
isFreestanding = false;
40834095
break;
40844096

40854097
case 'c':
40864098
kind = Node::Kind::ConformanceAttachedMacroExpansion;
4099+
isAttached = true;
4100+
isFreestanding = false;
40874101
break;
40884102

40894103
case 'u':
40904104
kind = Node::Kind::MacroExpansionUniqueName;
4105+
isAttached = false;
4106+
isFreestanding = false;
40914107
break;
40924108

40934109
default:
40944110
return nullptr;
40954111
}
40964112

4097-
NodePointer name = popNode(Node::Kind::Identifier);
4098-
NodePointer privateDiscriminator = popNode(Node::Kind::PrivateDeclName);
4113+
NodePointer macroName = popNode(Node::Kind::Identifier);
4114+
NodePointer privateDiscriminator = nullptr;
4115+
if (isFreestanding)
4116+
privateDiscriminator = popNode(Node::Kind::PrivateDeclName);
4117+
NodePointer attachedName = nullptr;
4118+
if (isAttached)
4119+
attachedName = popNode(isDeclName);
4120+
40994121
NodePointer context = popNode(isMacroExpansionNodeKind);
41004122
if (!context)
41014123
context = popContext();
41024124
NodePointer discriminator = demangleIndexAsNode();
4103-
auto result = createWithChildren(
4104-
kind, context, name, discriminator);
4125+
NodePointer result;
4126+
if (isAttached) {
4127+
result = createWithChildren(
4128+
kind, context, attachedName, macroName, discriminator);
4129+
} else {
4130+
result = createWithChildren(kind, context, macroName, discriminator);
4131+
}
41054132
if (privateDiscriminator)
41064133
result->addChild(privateDiscriminator, *this);
41074134
return result;

lib/Demangling/NodePrinter.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,28 +1434,38 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
14341434
/*hasName*/ true);
14351435
case Node::Kind::AccessorAttachedMacroExpansion:
14361436
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
1437-
/*hasName*/true, "accessor macro expansion #",
1438-
(int)Node->getChild(2)->getIndex() + 1);
1437+
/*hasName*/true,
1438+
("accessor macro @" +
1439+
nodeToString(Node->getChild(2)) + " expansion #"),
1440+
(int)Node->getChild(3)->getIndex() + 1);
14391441
case Node::Kind::FreestandingMacroExpansion:
14401442
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
14411443
/*hasName*/true, "freestanding macro expansion #",
14421444
(int)Node->getChild(2)->getIndex() + 1);
14431445
case Node::Kind::MemberAttributeAttachedMacroExpansion:
14441446
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
1445-
/*hasName*/true, "member attribute macro expansion #",
1446-
(int)Node->getChild(2)->getIndex() + 1);
1447+
/*hasName*/true,
1448+
("member attribute macro @" +
1449+
nodeToString(Node->getChild(2)) + " expansion #"),
1450+
(int)Node->getChild(3)->getIndex() + 1);
14471451
case Node::Kind::MemberAttachedMacroExpansion:
14481452
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
1449-
/*hasName*/true, "member macro expansion #",
1450-
(int)Node->getChild(2)->getIndex() + 1);
1453+
/*hasName*/true,
1454+
("member macro @" + nodeToString(Node->getChild(2)) +
1455+
" expansion #"),
1456+
(int)Node->getChild(3)->getIndex() + 1);
14511457
case Node::Kind::PeerAttachedMacroExpansion:
14521458
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
1453-
/*hasName*/true, "peer macro expansion #",
1454-
(int)Node->getChild(2)->getIndex() + 1);
1459+
/*hasName*/true,
1460+
("peer macro @" + nodeToString(Node->getChild(2)) +
1461+
" expansion #"),
1462+
(int)Node->getChild(3)->getIndex() + 1);
14551463
case Node::Kind::ConformanceAttachedMacroExpansion:
14561464
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
1457-
/*hasName*/true, "conformance macro expansion #",
1458-
(int)Node->getChild(2)->getIndex() + 1);
1465+
/*hasName*/true,
1466+
("conformance macro @" + nodeToString(Node->getChild(2)) +
1467+
" expansion #"),
1468+
(int)Node->getChild(3)->getIndex() + 1);
14591469
case Node::Kind::MacroExpansionUniqueName:
14601470
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
14611471
/*hasName*/true, "unique name #",

lib/Demangling/Remangler.cpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2908,51 +2908,46 @@ ManglingError Remangler::mangleFreestandingMacroExpansion(
29082908
ManglingError Remangler::mangleAccessorAttachedMacroExpansion(
29092909
Node *node, unsigned depth) {
29102910
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1));
2911-
if (auto privateDiscriminator = node->getChild(3))
2912-
RETURN_IF_ERROR(mangle(privateDiscriminator, depth + 1));
29132911
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
2912+
RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1));
29142913
Buffer << "fMa";
2915-
return mangleChildNode(node, 2, depth + 1);
2914+
return mangleChildNode(node, 3, depth + 1);
29162915
}
29172916

29182917
ManglingError Remangler::mangleMemberAttributeAttachedMacroExpansion(
29192918
Node *node, unsigned depth) {
29202919
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1));
2921-
if (auto privateDiscriminator = node->getChild(3))
2922-
RETURN_IF_ERROR(mangle(privateDiscriminator, depth + 1));
29232920
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
2921+
RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1));
29242922
Buffer << "fMA";
2925-
return mangleChildNode(node, 2, depth + 1);
2923+
return mangleChildNode(node, 3, depth + 1);
29262924
}
29272925

29282926
ManglingError Remangler::mangleMemberAttachedMacroExpansion(
29292927
Node *node, unsigned depth) {
29302928
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1));
2931-
if (auto privateDiscriminator = node->getChild(3))
2932-
RETURN_IF_ERROR(mangle(privateDiscriminator, depth + 1));
29332929
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
2930+
RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1));
29342931
Buffer << "fMm";
2935-
return mangleChildNode(node, 2, depth + 1);
2932+
return mangleChildNode(node, 3, depth + 1);
29362933
}
29372934

29382935
ManglingError Remangler::manglePeerAttachedMacroExpansion(
29392936
Node *node, unsigned depth) {
29402937
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1));
2941-
if (auto privateDiscriminator = node->getChild(3))
2942-
RETURN_IF_ERROR(mangle(privateDiscriminator, depth + 1));
29432938
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
2939+
RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1));
29442940
Buffer << "fMp";
2945-
return mangleChildNode(node, 2, depth + 1);
2941+
return mangleChildNode(node, 3, depth + 1);
29462942
}
29472943

29482944
ManglingError Remangler::mangleConformanceAttachedMacroExpansion(
29492945
Node *node, unsigned depth) {
29502946
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1));
2951-
if (auto privateDiscriminator = node->getChild(3))
2952-
RETURN_IF_ERROR(mangle(privateDiscriminator, depth + 1));
29532947
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
2948+
RETURN_IF_ERROR(mangleChildNode(node, 2, depth + 1));
29542949
Buffer << "fMc";
2955-
return mangleChildNode(node, 2, depth + 1);
2950+
return mangleChildNode(node, 3, depth + 1);
29562951
}
29572952

29582953
ManglingError Remangler::mangleMacroExpansionUniqueName(

lib/Sema/TypeCheckMacros.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,7 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
13141314
Optional<unsigned> swift::expandAccessors(
13151315
AbstractStorageDecl *storage, CustomAttr *attr, MacroDecl *macro
13161316
) {
1317+
(void)storage->getInterfaceType();
13171318
// Evaluate the macro.
13181319
auto macroSourceFile = evaluateAttachedMacro(macro, storage, attr,
13191320
/*passParentContext*/false,

test/Demangle/Inputs/manglings.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,5 @@ $s4main4TestVAA3ABCV4hereyySiFfa ---> runtime attribute generator of main.ABC.he
454454
$s9MacroUser13testStringify1a1bySi_SitF9stringifyfMf1_ ---> freestanding macro expansion #3 of stringify in MacroUser.testStringify(a: Swift.Int, b: Swift.Int) -> ()
455455
$s9MacroUser016testFreestandingA9ExpansionyyF4Foo3L_V23bitwidthNumberedStructsfMf_6methodfMu0_ ---> unique name #2 of method in freestanding macro expansion #1 of bitwidthNumberedStructs in Foo3 #1 in MacroUser.testFreestandingMacroExpansion() -> ()
456456
@__swiftmacro_1a13testStringifyAA1bySi_SitF9stringifyfMf_ ---> freestanding macro expansion #1 of stringify in a.testStringify(a: Swift.Int, b: Swift.Int) -> ()
457-
@__swiftmacro_15accessor_macros8MyStructV4nameSSvp17myPropertyWrapperfMa_ ---> accessor macro expansion #1 of myPropertyWrapper in accessor_macros.MyStruct.name : Swift.String
458-
@__swiftmacro_18macro_expand_peers1SV1f1a3for_SSSi_SSSdtYaF20addCompletionHandlerfMp_ ---> peer macro expansion #1 of addCompletionHandler in macro_expand_peers.S.f(a: Swift.Int, for: Swift.String, _: Swift.Double) async -> Swift.String
459-
@__swiftmacro_25macro_expand_conformances7GenericV20DelegatedConformancefMc_ ---> conformance macro expansion #1 of DelegatedConformance in macro_expand_conformances.Generic
457+
@__swiftmacro_18macro_expand_peers1SV1f20addCompletionHandlerfMp_ ---> peer macro @addCompletionHandler expansion #1 of f in macro_expand_peers.S
460458
@__swiftmacro_9MacroUser16MemberNotCoveredV33_4361AD9339943F52AE6186DD51E04E91Ll0dE0fMf0_ ---> freestanding macro expansion #2 of NotCovered(in _4361AD9339943F52AE6186DD51E04E91) in MacroUser.MemberNotCovered

test/Macros/accessor_macros.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct MyStruct {
4343

4444
@myPropertyWrapper
4545
var name: String
46-
// CHECK-DUMP: @__swiftmacro_15accessor_macros8MyStructV4nameSSvp17myPropertyWrapperfMa_.swift
46+
// CHECK-DUMP: @__swiftmacro_15accessor_macros8MyStructV4name17myPropertyWrapperfMa_.swift
4747
// CHECK-DUMP: get {
4848
// CHECK-DUMP: _name.wrappedValue
4949
// CHECK-DUMP: }
@@ -53,7 +53,7 @@ struct MyStruct {
5353

5454
@myPropertyWrapper
5555
var birthDate: Date?
56-
// CHECK-DUMP: @__swiftmacro_15accessor_macros8MyStructV9birthDateAA0F0VSgvp17myPropertyWrapperfMa_.swift
56+
// CHECK-DUMP: @__swiftmacro_15accessor_macros8MyStructV9birthDate17myPropertyWrapperfMa_.swift
5757
// CHECK-DUMP: get {
5858
// CHECK-DUMP: _birthDate.wrappedValue
5959
// CHECK-DUMP: }

test/Macros/macro_expand.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct Bad {}
6767
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type '_ImageLiteralType'
6868
// CHECK-DIAGS: error: macro expansion cannot introduce default literal type '_FileReferenceLiteralType'
6969

70-
// CHECK-DIAGS: CONTENTS OF FILE @__swiftmacro_9MacroUser3BadV7InvalidfMp_.swift
70+
// CHECK-DIAGS: CONTENTS OF FILE @__swiftmacro_9MacroUser3Bad7InvalidfMp_.swift
7171
// CHECK-DIAGS: import Swift
7272
// CHECK-DIAGS: precedencegroup MyPrecedence {}
7373
// CHECK-DIAGS: @attached(member) macro myMacro()

test/Macros/macro_expand_conformances.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct S {}
2929
@Hashable
3030
struct S2 {}
3131

32-
// CHECK-DUMP: @__swiftmacro_25macro_expand_conformances1SV9EquatablefMc_.swift
32+
// CHECK-DUMP: @__swiftmacro_25macro_expand_conformances1S9EquatablefMc_.swift
3333
// CHECK-DUMP: extension S : Equatable {}
3434

3535
// CHECK: true
@@ -55,7 +55,7 @@ struct Wrapped: P {
5555
@DelegatedConformance
5656
struct Generic<Element> {}
5757

58-
// CHECK-DUMP: @__swiftmacro_25macro_expand_conformances7GenericV20DelegatedConformancefMc_.swift
58+
// CHECK-DUMP: @__swiftmacro_25macro_expand_conformances7Generic20DelegatedConformancefMc_.swift
5959
// CHECK-DUMP: extension Generic : P where Element: P {}
6060

6161
func requiresP(_ value: (some P).Type) {

0 commit comments

Comments
 (0)