Skip to content

Commit 8871129

Browse files
committed
[Macros] Add frontend flag to dump macro expansions for diagnostics.
Add frontend flag `-emit-macro-expansion-files diagnostics` to emit any macro expansion buffers referenced by diagnostics into files in a temporary directory. This makes debugging type-checking failures in macro expansions far easier, because you can see them after the compiler process has exited.
1 parent 32bd60a commit 8871129

10 files changed

+53
-16
lines changed

include/swift/Basic/DiagnosticOptions.h

+3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ class DiagnosticOptions {
7373
/// descriptive style that's specific to Swift (currently experimental).
7474
FormattingStyle PrintedFormattingStyle = FormattingStyle::LLVM;
7575

76+
/// Whether to emit macro expansion buffers into separate, temporary files.
77+
bool EmitMacroExpansionFiles = false;
78+
7679
std::string DiagnosticDocumentationPath = "";
7780

7881
std::string LocalizationCode = "";

include/swift/Basic/SourceManager.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,8 @@ class SourceManager {
350350
llvm::SMDiagnostic GetMessage(SourceLoc Loc, llvm::SourceMgr::DiagKind Kind,
351351
const Twine &Msg,
352352
ArrayRef<llvm::SMRange> Ranges,
353-
ArrayRef<llvm::SMFixIt> FixIts) const;
353+
ArrayRef<llvm::SMFixIt> FixIts,
354+
bool EmitMacroExpansionFiles = false) const;
354355

355356
/// Verifies that all buffers are still valid.
356357
void verifyAllBuffers() const;

include/swift/Frontend/PrintingDiagnosticConsumer.h

+5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class PrintingDiagnosticConsumer : public DiagnosticConsumer {
3333
llvm::raw_ostream &Stream;
3434
bool ForceColors = false;
3535
bool PrintEducationalNotes = false;
36+
bool EmitMacroExpansionFiles = false;
3637
bool DidErrorOccur = false;
3738
DiagnosticOptions::FormattingStyle FormattingStyle =
3839
DiagnosticOptions::FormattingStyle::LLVM;
@@ -77,6 +78,10 @@ class PrintingDiagnosticConsumer : public DiagnosticConsumer {
7778
FormattingStyle = style;
7879
}
7980

81+
void setEmitMacroExpansionFiles(bool ShouldEmit) {
82+
EmitMacroExpansionFiles = ShouldEmit;
83+
}
84+
8085
bool didErrorOccur() {
8186
return DidErrorOccur;
8287
}

include/swift/Frontend/SerializedDiagnosticConsumer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace swift {
3636
///
3737
/// \returns A new diagnostic consumer that serializes diagnostics.
3838
std::unique_ptr<DiagnosticConsumer>
39-
createConsumer(llvm::StringRef outputPath);
39+
createConsumer(llvm::StringRef outputPath, bool emitMacroExpansionFiles);
4040
}
4141
}
4242

include/swift/Option/FrontendOptions.td

+2
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ def debug_requirement_machine : Joined<["-"], "debug-requirement-machine=">,
342342

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

346348
def analyze_requirement_machine : Flag<["-"], "analyze-requirement-machine">,
347349
Flags<[FrontendOption, HelpHidden, DoesNotAffectIncrementalBuild]>,

lib/DriverTool/swift_api_digester_main.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1846,7 +1846,7 @@ createDiagConsumer(llvm::raw_ostream &OS, bool &FailOnError, bool DisableFailOnE
18461846
if (!SerializedDiagPath.empty()) {
18471847
FailOnError = !DisableFailOnError;
18481848
results.emplace_back(std::make_unique<PrintingDiagnosticConsumer>());
1849-
results.emplace_back(serialized_diagnostics::createConsumer(SerializedDiagPath));
1849+
results.emplace_back(serialized_diagnostics::createConsumer(SerializedDiagPath, false));
18501850
} else if (CompilerStyleDiags) {
18511851
FailOnError = !DisableFailOnError;
18521852
results.emplace_back(std::make_unique<PrintingDiagnosticConsumer>());

lib/Frontend/CompilerInvocation.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -1476,6 +1476,15 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
14761476
}
14771477
}
14781478

1479+
for (const Arg *arg: Args.filtered(OPT_emit_macro_expansion_files)) {
1480+
StringRef contents = arg->getValue();
1481+
bool negated = contents.startswith("no-");
1482+
if (negated)
1483+
contents = contents.drop_front(3);
1484+
if (contents == "diagnostics")
1485+
Opts.EmitMacroExpansionFiles = !negated;
1486+
}
1487+
14791488
Opts.FixitCodeForAllDiagnostics |= Args.hasArg(OPT_fixit_all);
14801489
Opts.SuppressWarnings |= Args.hasArg(OPT_suppress_warnings);
14811490
Opts.SuppressRemarks |= Args.hasArg(OPT_suppress_remarks);

lib/Frontend/PrintingDiagnosticConsumer.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -1182,15 +1182,17 @@ void PrintingDiagnosticConsumer::printDiagnostic(SourceManager &SM,
11821182
Info.FormatArgs);
11831183
}
11841184

1185-
auto Msg = SM.GetMessage(Info.Loc, SMKind, Text, Ranges, FixIts);
1185+
auto Msg = SM.GetMessage(Info.Loc, SMKind, Text, Ranges, FixIts,
1186+
EmitMacroExpansionFiles);
11861187
rawSM.PrintMessage(out, Msg, ForceColors);
11871188
}
11881189

11891190
llvm::SMDiagnostic
11901191
SourceManager::GetMessage(SourceLoc Loc, llvm::SourceMgr::DiagKind Kind,
11911192
const Twine &Msg,
11921193
ArrayRef<llvm::SMRange> Ranges,
1193-
ArrayRef<llvm::SMFixIt> FixIts) const {
1194+
ArrayRef<llvm::SMFixIt> FixIts,
1195+
bool EmitMacroExpansionFiles) const {
11941196

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

12021204
if (Loc.isValid()) {
1203-
BufferID = getDisplayNameForLoc(Loc);
1205+
BufferID = getDisplayNameForLoc(Loc, EmitMacroExpansionFiles);
12041206
auto CurMB = LLVMSourceMgr.getMemoryBuffer(findBufferContainingLoc(Loc));
12051207

12061208
// Scan backward to find the start of the line.

lib/Frontend/SerializedDiagnosticConsumer.cpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,15 @@ struct SharedState : llvm::RefCountedBase<SharedState> {
103103
class SerializedDiagnosticConsumer : public DiagnosticConsumer {
104104
/// State shared among the various clones of this diagnostic consumer.
105105
llvm::IntrusiveRefCntPtr<SharedState> State;
106+
bool EmitMacroExpansionFiles = false;
106107
bool CalledFinishProcessing = false;
107108
bool CompilationWasComplete = true;
108109

109110
public:
110-
SerializedDiagnosticConsumer(StringRef serializedDiagnosticsPath)
111-
: State(new SharedState(serializedDiagnosticsPath)) {
111+
SerializedDiagnosticConsumer(StringRef serializedDiagnosticsPath,
112+
bool emitMacroExpansionFiles)
113+
: State(new SharedState(serializedDiagnosticsPath)),
114+
EmitMacroExpansionFiles(emitMacroExpansionFiles) {
112115
emitPreamble();
113116
}
114117

@@ -213,8 +216,11 @@ class SerializedDiagnosticConsumer : public DiagnosticConsumer {
213216

214217
namespace swift {
215218
namespace serialized_diagnostics {
216-
std::unique_ptr<DiagnosticConsumer> createConsumer(StringRef outputPath) {
217-
return std::make_unique<SerializedDiagnosticConsumer>(outputPath);
219+
std::unique_ptr<DiagnosticConsumer> createConsumer(
220+
StringRef outputPath, bool emitMacroExpansionFiles
221+
) {
222+
return std::make_unique<SerializedDiagnosticConsumer>(
223+
outputPath, emitMacroExpansionFiles);
218224
}
219225
} // namespace serialized_diagnostics
220226
} // namespace swift
@@ -256,7 +262,8 @@ unsigned SerializedDiagnosticConsumer::getEmitFile(
256262
// The source range that this buffer was generated from, expressed as
257263
// offsets into the original buffer.
258264
if (generatedInfo->originalSourceRange.isValid()) {
259-
auto originalFilename = SM.getDisplayNameForLoc(generatedInfo->originalSourceRange.Start);
265+
auto originalFilename = SM.getDisplayNameForLoc(generatedInfo->originalSourceRange.Start,
266+
EmitMacroExpansionFiles);
260267
addRangeToRecord(
261268
Lexer::getCharSourceRangeFromSourceRange(
262269
SM, generatedInfo->originalSourceRange),
@@ -532,7 +539,7 @@ emitDiagnosticMessage(SourceManager &SM,
532539

533540
StringRef filename = "";
534541
if (Loc.isValid())
535-
filename = SM.getDisplayNameForLoc(Loc);
542+
filename = SM.getDisplayNameForLoc(Loc, EmitMacroExpansionFiles);
536543

537544
// Emit the RECORD_DIAG record.
538545
Record.clear();

lib/FrontendTool/FrontendTool.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -1931,15 +1931,19 @@ createDispatchingDiagnosticConsumerIfNeeded(
19311931
/// If no serialized diagnostics are being produced, returns null.
19321932
static std::unique_ptr<DiagnosticConsumer>
19331933
createSerializedDiagnosticConsumerIfNeeded(
1934-
const FrontendInputsAndOutputs &inputsAndOutputs) {
1934+
const FrontendInputsAndOutputs &inputsAndOutputs,
1935+
bool emitMacroExpansionFiles
1936+
) {
19351937
return createDispatchingDiagnosticConsumerIfNeeded(
19361938
inputsAndOutputs,
1937-
[](const InputFile &input) -> std::unique_ptr<DiagnosticConsumer> {
1939+
[emitMacroExpansionFiles](
1940+
const InputFile &input
1941+
) -> std::unique_ptr<DiagnosticConsumer> {
19381942
auto serializedDiagnosticsPath = input.getSerializedDiagnosticsPath();
19391943
if (serializedDiagnosticsPath.empty())
19401944
return nullptr;
19411945
return serialized_diagnostics::createConsumer(
1942-
serializedDiagnosticsPath);
1946+
serializedDiagnosticsPath, emitMacroExpansionFiles);
19431947
});
19441948
}
19451949

@@ -2270,7 +2274,8 @@ int swift::performFrontend(ArrayRef<const char *> Args,
22702274
// See https://github.com/apple/swift/issues/45288 for details.
22712275
std::unique_ptr<DiagnosticConsumer> SerializedConsumerDispatcher =
22722276
createSerializedDiagnosticConsumerIfNeeded(
2273-
Invocation.getFrontendOptions().InputsAndOutputs);
2277+
Invocation.getFrontendOptions().InputsAndOutputs,
2278+
Invocation.getDiagnosticOptions().EmitMacroExpansionFiles);
22742279
if (SerializedConsumerDispatcher)
22752280
Instance->addDiagnosticConsumer(SerializedConsumerDispatcher.get());
22762281

@@ -2288,6 +2293,9 @@ int swift::performFrontend(ArrayRef<const char *> Args,
22882293
PDC.setFormattingStyle(
22892294
Invocation.getDiagnosticOptions().PrintedFormattingStyle);
22902295

2296+
PDC.setEmitMacroExpansionFiles(
2297+
Invocation.getDiagnosticOptions().EmitMacroExpansionFiles);
2298+
22912299
if (Invocation.getFrontendOptions().PrintStats) {
22922300
llvm::EnableStatistics();
22932301
}

0 commit comments

Comments
 (0)