Skip to content

Commit ac4aa41

Browse files
committed
[Macros] Use macro expansion mangling for unique names in macros
Use the name mangling scheme we've devised for macro expansions to back the implementation of the macro expansion context's `getUniqueName` operation. This way, we guarantee that the names provided by macro expansions don't conflict, as well as making them demangleable so we can determine what introduced the names.
1 parent 1e6daae commit ac4aa41

File tree

13 files changed

+110
-19
lines changed

13 files changed

+110
-19
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ Entities
395395

396396
macro-discriminator-list ::= macro-discriminator-list? 'fM' macro-expansion-operator INDEX
397397

398-
macro-expansion-operator ::= 'f' // freestanding macro
399-
macro-expansion-operator ::= 'u' // uniquely-named entity
398+
macro-expansion-operator ::= identifier 'f' // freestanding macro
399+
macro-expansion-operator ::= identifier 'u' // uniquely-named entity
400400

401401
file-discriminator ::= identifier 'Ll' // anonymous file-discriminated declaration
402402

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ NODE(LazyProtocolWitnessTableAccessor)
149149
NODE(LazyProtocolWitnessTableCacheVariable)
150150
NODE(LocalDeclName)
151151
NODE(Macro)
152+
NODE(MacroExpansionUniqueName)
152153
CONTEXT_NODE(MaterializeForSet)
153154
NODE(MergedFunction)
154155
NODE(Metatype)

include/swift/Parse/Parser.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ class Parser {
195195

196196
bool allowTopLevelCode() const;
197197

198+
bool isInMacroExpansion(SourceLoc loc) const;
199+
198200
const std::vector<Token> &getSplitTokens() const { return SplitTokens; }
199201

200202
void markSplitToken(tok Kind, StringRef Txt);
@@ -575,7 +577,8 @@ class Parser {
575577
return;
576578

577579
if (tok.getText().size() == 1 || Context.LangOpts.EnableDollarIdentifiers ||
578-
isInSILMode() || L->isSwiftInterface())
580+
isInSILMode() || L->isSwiftInterface() ||
581+
isInMacroExpansion(tok.getLoc()))
579582
return;
580583

581584
diagnose(tok.getLoc(), diag::dollar_identifier_decl,

lib/ASTGen/Sources/ASTGen/Macros.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,13 @@ fileprivate struct ThrownErrorDiagnostic: DiagnosticMessage {
106106
}
107107
}
108108

109-
@_cdecl("swift_ASTGen_evaluateMacro")
109+
@_cdecl("swift_ASTGen_expandFreestandingMacro")
110110
@usableFromInline
111-
func evaluateMacro(
111+
func expandFreestandingMacro(
112112
diagEnginePtr: UnsafeMutablePointer<UInt8>,
113113
macroPtr: UnsafeRawPointer,
114+
discriminatorText: UnsafePointer<UInt8>,
115+
discriminatorTextLength: Int,
114116
sourceFilePtr: UnsafeRawPointer,
115117
sourceLocationPtr: UnsafePointer<UInt8>?,
116118
expandedSourcePointer: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
@@ -144,7 +146,13 @@ func evaluateMacro(
144146
let sourceManager = SourceManager(cxxDiagnosticEngine: diagEnginePtr)
145147
sourceManager.insert(sourceFilePtr)
146148

147-
let context = sourceManager.createMacroExpansionContext()
149+
let discriminatorBuffer = UnsafeBufferPointer(
150+
start: discriminatorText, count: discriminatorTextLength
151+
)
152+
let discriminator = String(decoding: discriminatorBuffer, as: UTF8.self)
153+
let context = sourceManager.createMacroExpansionContext(
154+
discriminator: discriminator
155+
)
148156

149157
guard let parentSyntax = token.parent else {
150158
print("not on a macro expansion node: \(token.recursiveDescription)")

lib/ASTGen/Sources/ASTGen/SourceManager.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ extension SourceManager {
145145
}
146146

147147
/// Create a new macro expansion context
148-
func createMacroExpansionContext() -> BasicMacroExpansionContext {
148+
func createMacroExpansionContext(discriminator: String = "") -> BasicMacroExpansionContext {
149149
// Collect the set of source files for this context.
150150
var sourceFiles: [SourceFileSyntax : BasicMacroExpansionContext.KnownSourceFile] = [:]
151151
for (syntax, exported) in exportedSourceFilesBySyntax {
@@ -155,6 +155,8 @@ extension SourceManager {
155155
)
156156
}
157157

158-
return BasicMacroExpansionContext(sourceFiles: sourceFiles)
158+
return BasicMacroExpansionContext(
159+
expansionDiscriminator: discriminator, sourceFiles: sourceFiles
160+
)
159161
}
160162
}

lib/Demangling/Demangler.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3902,12 +3902,18 @@ NodePointer Demangler::demangleMacroExpansion() {
39023902
kind = Node::Kind::FreestandingMacroExpansion;
39033903
break;
39043904

3905+
case 'u':
3906+
kind = Node::Kind::MacroExpansionUniqueName;
3907+
break;
3908+
39053909
default:
39063910
return nullptr;
39073911
}
39083912

39093913
NodePointer name = popNode(Node::Kind::Identifier);
3910-
NodePointer context = popContext();
3914+
NodePointer context = popNode(Node::Kind::FreestandingMacroExpansion);
3915+
if (!context)
3916+
context = popContext();
39113917
NodePointer discriminator = demangleIndexAsNode();
39123918
return createWithChildren(kind, context, name, discriminator);
39133919
}

lib/Demangling/NodePrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ class NodePrinter {
440440
case Node::Kind::LazyProtocolWitnessTableCacheVariable:
441441
case Node::Kind::LocalDeclName:
442442
case Node::Kind::Macro:
443+
case Node::Kind::MacroExpansionUniqueName:
443444
case Node::Kind::MaterializeForSet:
444445
case Node::Kind::MergedFunction:
445446
case Node::Kind::Metaclass:
@@ -1341,6 +1342,10 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
13411342
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
13421343
/*hasName*/true, "freestanding macro expansion #",
13431344
(int)Node->getChild(2)->getIndex() + 1);
1345+
case Node::Kind::MacroExpansionUniqueName:
1346+
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
1347+
/*hasName*/true, "unique name #",
1348+
(int)Node->getChild(2)->getIndex() + 1);
13441349
case Node::Kind::GenericTypeParamDecl:
13451350
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
13461351
/*hasName*/ true);

lib/Demangling/OldRemangler.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,13 @@ ManglingError Remangler::mangleFreestandingMacroExpansion(
10701070
return mangleChildNodes(node, depth + 1);
10711071
}
10721072

1073+
ManglingError Remangler::mangleMacroExpansionUniqueName(
1074+
Node *node, unsigned depth) {
1075+
Buffer << "fMu";
1076+
RETURN_IF_ERROR(mangleIndex(node, depth + 1));
1077+
return mangleChildNodes(node, depth + 1);
1078+
}
1079+
10731080
ManglingError Remangler::mangleAccessor(Node *storageNode,
10741081
StringRef accessorCode,
10751082
EntityContext &ctx, unsigned depth) {

lib/Demangling/Remangler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2880,6 +2880,14 @@ ManglingError Remangler::mangleFreestandingMacroExpansion(
28802880
return mangleChildNode(node, 2, depth + 1);
28812881
}
28822882

2883+
ManglingError Remangler::mangleMacroExpansionUniqueName(
2884+
Node *node, unsigned depth) {
2885+
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1));
2886+
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
2887+
Buffer << "fMu";
2888+
return mangleChildNode(node, 2, depth + 1);
2889+
}
2890+
28832891
ManglingError Remangler::mangleSuffix(Node *node, unsigned depth) {
28842892
// Just add the suffix back on.
28852893
Buffer << node->getText();

lib/Parse/Parser.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,18 @@ bool Parser::allowTopLevelCode() const {
520520
return SF.isScriptMode();
521521
}
522522

523+
bool Parser::isInMacroExpansion(SourceLoc loc) const {
524+
if (loc.isInvalid())
525+
return false;
526+
527+
auto bufferID = SourceMgr.findBufferContainingLoc(loc);
528+
auto generatedSourceInfo = SourceMgr.getGeneratedSourceInfo(bufferID);
529+
if (!generatedSourceInfo)
530+
return false;
531+
532+
return true;
533+
}
534+
523535
const Token &Parser::peekToken() {
524536
return L->peekNextToken();
525537
}

0 commit comments

Comments
 (0)