Skip to content

[Macros] Use macro expansion mangling for unique names in macros #63322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,8 @@ Entities

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

macro-expansion-operator ::= 'f' // freestanding macro
macro-expansion-operator ::= 'u' // uniquely-named entity
macro-expansion-operator ::= identifier 'f' // freestanding macro
macro-expansion-operator ::= identifier 'u' // uniquely-named entity

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

Expand Down
3 changes: 3 additions & 0 deletions include/swift/Basic/DiagnosticOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ class DiagnosticOptions {
/// descriptive style that's specific to Swift (currently experimental).
FormattingStyle PrintedFormattingStyle = FormattingStyle::LLVM;

/// Whether to emit macro expansion buffers into separate, temporary files.
bool EmitMacroExpansionFiles = true;

std::string DiagnosticDocumentationPath = "";

std::string LocalizationCode = "";
Expand Down
3 changes: 2 additions & 1 deletion include/swift/Basic/SourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ class SourceManager {
llvm::SMDiagnostic GetMessage(SourceLoc Loc, llvm::SourceMgr::DiagKind Kind,
const Twine &Msg,
ArrayRef<llvm::SMRange> Ranges,
ArrayRef<llvm::SMFixIt> FixIts) const;
ArrayRef<llvm::SMFixIt> FixIts,
bool EmitMacroExpansionFiles = false) const;

/// Verifies that all buffers are still valid.
void verifyAllBuffers() const;
Expand Down
3 changes: 2 additions & 1 deletion include/swift/Demangling/DemangleNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ NODE(ExistentialMetatype)
CONTEXT_NODE(ExplicitClosure)
CONTEXT_NODE(Extension)
NODE(FieldOffset)
NODE(FreestandingMacroExpansion)
NODE(FullTypeMetadata)
CONTEXT_NODE(Function)
NODE(FunctionSignatureSpecialization)
Expand Down Expand Up @@ -148,7 +149,7 @@ NODE(LazyProtocolWitnessTableAccessor)
NODE(LazyProtocolWitnessTableCacheVariable)
NODE(LocalDeclName)
NODE(Macro)
NODE(MacroExpansion)
NODE(MacroExpansionUniqueName)
CONTEXT_NODE(MaterializeForSet)
NODE(MergedFunction)
NODE(Metatype)
Expand Down
5 changes: 5 additions & 0 deletions include/swift/Frontend/PrintingDiagnosticConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class PrintingDiagnosticConsumer : public DiagnosticConsumer {
llvm::raw_ostream &Stream;
bool ForceColors = false;
bool PrintEducationalNotes = false;
bool EmitMacroExpansionFiles = false;
bool DidErrorOccur = false;
DiagnosticOptions::FormattingStyle FormattingStyle =
DiagnosticOptions::FormattingStyle::LLVM;
Expand Down Expand Up @@ -77,6 +78,10 @@ class PrintingDiagnosticConsumer : public DiagnosticConsumer {
FormattingStyle = style;
}

void setEmitMacroExpansionFiles(bool ShouldEmit) {
EmitMacroExpansionFiles = ShouldEmit;
}

bool didErrorOccur() {
return DidErrorOccur;
}
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Frontend/SerializedDiagnosticConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace swift {
///
/// \returns A new diagnostic consumer that serializes diagnostics.
std::unique_ptr<DiagnosticConsumer>
createConsumer(llvm::StringRef outputPath);
createConsumer(llvm::StringRef outputPath, bool emitMacroExpansionFiles);
}
}

Expand Down
2 changes: 2 additions & 0 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ def debug_requirement_machine : Joined<["-"], "debug-requirement-machine=">,

def dump_macro_expansions : Flag<["-"], "dump-macro-expansions">,
HelpText<"Dumps the results of each macro expansion">;
def emit_macro_expansion_files : Separate<["-"], "emit-macro-expansion-files">,
HelpText<"Specify when to emit macro expansion file: 'none', 'debug', or 'diagnostics'">;

def analyze_requirement_machine : Flag<["-"], "analyze-requirement-machine">,
Flags<[FrontendOption, HelpHidden, DoesNotAffectIncrementalBuild]>,
Expand Down
4 changes: 2 additions & 2 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -747,11 +747,11 @@ def strict_concurrency : Joined<["-"], "strict-concurrency=">,

def enable_experimental_feature :
Separate<["-"], "enable-experimental-feature">,
Flags<[FrontendOption]>,
Flags<[FrontendOption, ModuleInterfaceOptionIgnorable]>,
HelpText<"Enable an experimental feature">;

def enable_upcoming_feature : Separate<["-"], "enable-upcoming-feature">,
Flags<[FrontendOption]>,
Flags<[FrontendOption, ModuleInterfaceOptionIgnorable]>,
HelpText<"Enable a feature that will be introduced in an upcoming language "
"version">;

Expand Down
5 changes: 4 additions & 1 deletion include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ class Parser {

bool allowTopLevelCode() const;

bool isInMacroExpansion(SourceLoc loc) const;

const std::vector<Token> &getSplitTokens() const { return SplitTokens; }

void markSplitToken(tok Kind, StringRef Txt);
Expand Down Expand Up @@ -575,7 +577,8 @@ class Parser {
return;

if (tok.getText().size() == 1 || Context.LangOpts.EnableDollarIdentifiers ||
isInSILMode() || L->isSwiftInterface())
isInSILMode() || L->isSwiftInterface() ||
isInMacroExpansion(tok.getLoc()))
return;

diagnose(tok.getLoc(), diag::dollar_identifier_decl,
Expand Down
14 changes: 11 additions & 3 deletions lib/ASTGen/Sources/ASTGen/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,13 @@ fileprivate struct ThrownErrorDiagnostic: DiagnosticMessage {
}
}

@_cdecl("swift_ASTGen_evaluateMacro")
@_cdecl("swift_ASTGen_expandFreestandingMacro")
@usableFromInline
func evaluateMacro(
func expandFreestandingMacro(
diagEnginePtr: UnsafeMutablePointer<UInt8>,
macroPtr: UnsafeRawPointer,
discriminatorText: UnsafePointer<UInt8>,
discriminatorTextLength: Int,
sourceFilePtr: UnsafeRawPointer,
sourceLocationPtr: UnsafePointer<UInt8>?,
expandedSourcePointer: UnsafeMutablePointer<UnsafePointer<UInt8>?>,
Expand Down Expand Up @@ -144,7 +146,13 @@ func evaluateMacro(
let sourceManager = SourceManager(cxxDiagnosticEngine: diagEnginePtr)
sourceManager.insert(sourceFilePtr)

let context = sourceManager.createMacroExpansionContext()
let discriminatorBuffer = UnsafeBufferPointer(
start: discriminatorText, count: discriminatorTextLength
)
let discriminator = String(decoding: discriminatorBuffer, as: UTF8.self)
let context = sourceManager.createMacroExpansionContext(
discriminator: discriminator
)

guard let parentSyntax = token.parent else {
print("not on a macro expansion node: \(token.recursiveDescription)")
Expand Down
6 changes: 4 additions & 2 deletions lib/ASTGen/Sources/ASTGen/SourceManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ extension SourceManager {
}

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

return BasicMacroExpansionContext(sourceFiles: sourceFiles)
return BasicMacroExpansionContext(
expansionDiscriminator: discriminator, sourceFiles: sourceFiles
)
}
}
10 changes: 8 additions & 2 deletions lib/Demangling/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3899,15 +3899,21 @@ NodePointer Demangler::demangleMacroExpansion() {
Node::Kind kind;
switch (nextChar()) {
case 'f':
kind = Node::Kind::MacroExpansion;
kind = Node::Kind::FreestandingMacroExpansion;
break;

case 'u':
kind = Node::Kind::MacroExpansionUniqueName;
break;

default:
return nullptr;
}

NodePointer name = popNode(Node::Kind::Identifier);
NodePointer context = popContext();
NodePointer context = popNode(Node::Kind::FreestandingMacroExpansion);
if (!context)
context = popContext();
NodePointer discriminator = demangleIndexAsNode();
return createWithChildren(kind, context, name, discriminator);
}
11 changes: 8 additions & 3 deletions lib/Demangling/NodePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ class NodePrinter {
case Node::Kind::Extension:
case Node::Kind::EnumCase:
case Node::Kind::FieldOffset:
case Node::Kind::FreestandingMacroExpansion:
case Node::Kind::FullObjCResilientClassStub:
case Node::Kind::FullTypeMetadata:
case Node::Kind::Function:
Expand Down Expand Up @@ -439,7 +440,7 @@ class NodePrinter {
case Node::Kind::LazyProtocolWitnessTableCacheVariable:
case Node::Kind::LocalDeclName:
case Node::Kind::Macro:
case Node::Kind::MacroExpansion:
case Node::Kind::MacroExpansionUniqueName:
case Node::Kind::MaterializeForSet:
case Node::Kind::MergedFunction:
case Node::Kind::Metaclass:
Expand Down Expand Up @@ -1337,9 +1338,13 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth,
Node->getNumChildren() == 3? TypePrinting::WithColon
: TypePrinting::FunctionStyle,
/*hasName*/ true);
case Node::Kind::MacroExpansion:
case Node::Kind::FreestandingMacroExpansion:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/true, "macro expansion #",
/*hasName*/true, "freestanding macro expansion #",
(int)Node->getChild(2)->getIndex() + 1);
case Node::Kind::MacroExpansionUniqueName:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
/*hasName*/true, "unique name #",
(int)Node->getChild(2)->getIndex() + 1);
case Node::Kind::GenericTypeParamDecl:
return printEntity(Node, depth, asPrefixContext, TypePrinting::NoType,
Expand Down
10 changes: 9 additions & 1 deletion lib/Demangling/OldRemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1063,12 +1063,20 @@ ManglingError Remangler::mangleMacro(Node *node, unsigned depth) {
return mangleChildNodes(node, depth + 1);
}

ManglingError Remangler::mangleMacroExpansion(Node *node, unsigned depth) {
ManglingError Remangler::mangleFreestandingMacroExpansion(
Node *node, unsigned depth) {
Buffer << "fMf";
RETURN_IF_ERROR(mangleIndex(node, depth + 1));
return mangleChildNodes(node, depth + 1);
}

ManglingError Remangler::mangleMacroExpansionUniqueName(
Node *node, unsigned depth) {
Buffer << "fMu";
RETURN_IF_ERROR(mangleIndex(node, depth + 1));
return mangleChildNodes(node, depth + 1);
}

ManglingError Remangler::mangleAccessor(Node *storageNode,
StringRef accessorCode,
EntityContext &ctx, unsigned depth) {
Expand Down
11 changes: 10 additions & 1 deletion lib/Demangling/Remangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2872,13 +2872,22 @@ ManglingError Remangler::mangleMacro(Node *node, unsigned depth) {
return ManglingError::Success;
}

ManglingError Remangler::mangleMacroExpansion(Node *node, unsigned depth) {
ManglingError Remangler::mangleFreestandingMacroExpansion(
Node *node, unsigned depth) {
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1));
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
Buffer << "fMf";
return mangleChildNode(node, 2, depth + 1);
}

ManglingError Remangler::mangleMacroExpansionUniqueName(
Node *node, unsigned depth) {
RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1));
RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1));
Buffer << "fMu";
return mangleChildNode(node, 2, depth + 1);
}

ManglingError Remangler::mangleSuffix(Node *node, unsigned depth) {
// Just add the suffix back on.
Buffer << node->getText();
Expand Down
2 changes: 1 addition & 1 deletion lib/DriverTool/swift_api_digester_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1846,7 +1846,7 @@ createDiagConsumer(llvm::raw_ostream &OS, bool &FailOnError, bool DisableFailOnE
if (!SerializedDiagPath.empty()) {
FailOnError = !DisableFailOnError;
results.emplace_back(std::make_unique<PrintingDiagnosticConsumer>());
results.emplace_back(serialized_diagnostics::createConsumer(SerializedDiagPath));
results.emplace_back(serialized_diagnostics::createConsumer(SerializedDiagPath, false));
} else if (CompilerStyleDiags) {
FailOnError = !DisableFailOnError;
results.emplace_back(std::make_unique<PrintingDiagnosticConsumer>());
Expand Down
9 changes: 9 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,15 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
}
}

for (const Arg *arg: Args.filtered(OPT_emit_macro_expansion_files)) {
StringRef contents = arg->getValue();
bool negated = contents.startswith("no-");
if (negated)
contents = contents.drop_front(3);
if (contents == "diagnostics")
Opts.EmitMacroExpansionFiles = !negated;
}

Opts.FixitCodeForAllDiagnostics |= Args.hasArg(OPT_fixit_all);
Opts.SuppressWarnings |= Args.hasArg(OPT_suppress_warnings);
Opts.SuppressRemarks |= Args.hasArg(OPT_suppress_remarks);
Expand Down
8 changes: 5 additions & 3 deletions lib/Frontend/PrintingDiagnosticConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1182,15 +1182,17 @@ void PrintingDiagnosticConsumer::printDiagnostic(SourceManager &SM,
Info.FormatArgs);
}

auto Msg = SM.GetMessage(Info.Loc, SMKind, Text, Ranges, FixIts);
auto Msg = SM.GetMessage(Info.Loc, SMKind, Text, Ranges, FixIts,
EmitMacroExpansionFiles);
rawSM.PrintMessage(out, Msg, ForceColors);
}

llvm::SMDiagnostic
SourceManager::GetMessage(SourceLoc Loc, llvm::SourceMgr::DiagKind Kind,
const Twine &Msg,
ArrayRef<llvm::SMRange> Ranges,
ArrayRef<llvm::SMFixIt> FixIts) const {
ArrayRef<llvm::SMFixIt> FixIts,
bool EmitMacroExpansionFiles) const {

// First thing to do: find the current buffer containing the specified
// location to pull out the source line.
Expand All @@ -1200,7 +1202,7 @@ SourceManager::GetMessage(SourceLoc Loc, llvm::SourceMgr::DiagKind Kind,
std::string LineStr;

if (Loc.isValid()) {
BufferID = getDisplayNameForLoc(Loc);
BufferID = getDisplayNameForLoc(Loc, EmitMacroExpansionFiles);
auto CurMB = LLVMSourceMgr.getMemoryBuffer(findBufferContainingLoc(Loc));

// Scan backward to find the start of the line.
Expand Down
19 changes: 13 additions & 6 deletions lib/Frontend/SerializedDiagnosticConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,15 @@ struct SharedState : llvm::RefCountedBase<SharedState> {
class SerializedDiagnosticConsumer : public DiagnosticConsumer {
/// State shared among the various clones of this diagnostic consumer.
llvm::IntrusiveRefCntPtr<SharedState> State;
bool EmitMacroExpansionFiles = false;
bool CalledFinishProcessing = false;
bool CompilationWasComplete = true;

public:
SerializedDiagnosticConsumer(StringRef serializedDiagnosticsPath)
: State(new SharedState(serializedDiagnosticsPath)) {
SerializedDiagnosticConsumer(StringRef serializedDiagnosticsPath,
bool emitMacroExpansionFiles)
: State(new SharedState(serializedDiagnosticsPath)),
EmitMacroExpansionFiles(emitMacroExpansionFiles) {
emitPreamble();
}

Expand Down Expand Up @@ -213,8 +216,11 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer {

namespace swift {
namespace serialized_diagnostics {
std::unique_ptr<DiagnosticConsumer> createConsumer(StringRef outputPath) {
return std::make_unique<SerializedDiagnosticConsumer>(outputPath);
std::unique_ptr<DiagnosticConsumer> createConsumer(
StringRef outputPath, bool emitMacroExpansionFiles
) {
return std::make_unique<SerializedDiagnosticConsumer>(
outputPath, emitMacroExpansionFiles);
}
} // namespace serialized_diagnostics
} // namespace swift
Expand Down Expand Up @@ -256,7 +262,8 @@ unsigned SerializedDiagnosticConsumer::getEmitFile(
// The source range that this buffer was generated from, expressed as
// offsets into the original buffer.
if (generatedInfo->originalSourceRange.isValid()) {
auto originalFilename = SM.getDisplayNameForLoc(generatedInfo->originalSourceRange.Start);
auto originalFilename = SM.getDisplayNameForLoc(generatedInfo->originalSourceRange.Start,
EmitMacroExpansionFiles);
addRangeToRecord(
Lexer::getCharSourceRangeFromSourceRange(
SM, generatedInfo->originalSourceRange),
Expand Down Expand Up @@ -532,7 +539,7 @@ emitDiagnosticMessage(SourceManager &SM,

StringRef filename = "";
if (Loc.isValid())
filename = SM.getDisplayNameForLoc(Loc);
filename = SM.getDisplayNameForLoc(Loc, EmitMacroExpansionFiles);

// Emit the RECORD_DIAG record.
Record.clear();
Expand Down
Loading