aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/TextDiagnostic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/TextDiagnostic.cpp')
-rw-r--r--lib/Frontend/TextDiagnostic.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp
index 7b3ebc4cd6..8dab0afcac 100644
--- a/lib/Frontend/TextDiagnostic.cpp
+++ b/lib/Frontend/TextDiagnostic.cpp
@@ -689,6 +689,9 @@ void TextDiagnostic::emitMacroExpansionsAndCarets(
emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, MacroDepth,
OnMacroInst + 1);
+ // Save the original location so we can find the spelling of the macro call.
+ SourceLocation MacroLoc = Loc;
+
// Map the location.
Loc = getImmediateMacroCalleeLoc(SM, Loc);
@@ -726,9 +729,27 @@ void TextDiagnostic::emitMacroExpansionsAndCarets(
return;
}
- // FIXME: Format an actual diagnostic rather than a hard coded string.
+ // Walk past macro argument expanions.
+ while (SM.isMacroArgExpansion(MacroLoc))
+ MacroLoc = SM.getImmediateExpansionRange(MacroLoc).first;
+
+ // Find the spelling location of the start of the non-argument expansion
+ // range. This is where the macro name was spelled in order to begin
+ // expanding this macro.
+ MacroLoc = SM.getSpellingLoc(SM.getImmediateExpansionRange(MacroLoc).first);
+
+ // Dig out the buffer where the macro name was spelled and the extents of the
+ // name so that we can render it into the expansion note.
+ std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(MacroLoc);
+ unsigned MacroTokenLength = Lexer::MeasureTokenLength(MacroLoc, SM, LangOpts);
+ StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first);
+
+ llvm::SmallString<100> MessageStorage;
+ llvm::raw_svector_ostream Message(MessageStorage);
+ Message << "expanded from macro: "
+ << ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength);
emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note,
- "expanded from:",
+ Message.str(),
Ranges, ArrayRef<FixItHint>());
}