summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/SourceManager.h36
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp39
2 files changed, 21 insertions, 54 deletions
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 506947cbd6..a69ffad290 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -1479,35 +1479,19 @@ public:
bool UseLineDirectives = true) const{
// This is a condensed form of the algorithm used by emitCaretDiagnostic to
// walk to the top of the macro call stack.
- while (Loc.isMacroID()) {
- Loc = skipToMacroArgExpansion(Loc);
+ while (Loc.isMacroID())
Loc = getImmediateMacroCallerLoc(Loc);
- }
return getPresumedLoc(Loc, UseLineDirectives);
}
- /// Look through spelling locations for a macro argument expansion, and if
- /// found skip to it so that we can trace the argument rather than the macros
- /// in which that argument is used. If no macro argument expansion is found,
- /// don't skip anything and return the starting location.
- SourceLocation skipToMacroArgExpansion(SourceLocation StartLoc) const {
- for (SourceLocation L = StartLoc; L.isMacroID();
- L = getImmediateSpellingLoc(L)) {
- if (isMacroArgExpansion(L))
- return L;
- }
- // Otherwise just return initial location, there's nothing to skip.
- return StartLoc;
- }
-
/// Gets the location of the immediate macro caller, one level up the stack
/// toward the initial macro typed into the source.
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const {
if (!Loc.isMacroID()) return Loc;
// When we have the location of (part of) an expanded parameter, its
- // spelling location points to the argument as typed into the macro call,
+ // spelling location points to the argument as expanded in the macro call,
// and therefore is used to locate the macro caller.
if (isMacroArgExpansion(Loc))
return getImmediateSpellingLoc(Loc);
@@ -1517,22 +1501,6 @@ public:
return getImmediateExpansionRange(Loc).first;
}
- /// Gets the location of the immediate macro callee, one level down the stack
- /// toward the leaf macro.
- SourceLocation getImmediateMacroCalleeLoc(SourceLocation Loc) const {
- if (!Loc.isMacroID()) return Loc;
-
- // When we have the location of (part of) an expanded parameter, its
- // expansion location points to the unexpanded parameter reference within
- // the macro definition (or callee).
- if (isMacroArgExpansion(Loc))
- return getImmediateExpansionRange(Loc).first;
-
- // Otherwise, the callee of the macro is located where this location was
- // spelled inside the macro definition.
- return getImmediateSpellingLoc(Loc);
- }
-
private:
const llvm::MemoryBuffer *getFakeBufferForRecovery() const;
const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const;
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index 930a975dba..084c5cb288 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -380,7 +380,7 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(
unsigned OnMacroInst)
{
assert(!Loc.isInvalid() && "must have a valid source location here");
-
+
// If this is a file source location, directly emit the source snippet and
// caret line. Also record the macro depth reached.
if (Loc.isFileID()) {
@@ -394,22 +394,12 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(
return;
}
// Otherwise recurse through each macro expansion layer.
-
- // When processing macros, skip over the expansions leading up to
- // a macro argument, and trace the argument's expansion stack instead.
- Loc = SM.skipToMacroArgExpansion(Loc);
-
- SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc);
+ // Walk up to the caller of this macro, and produce a backtrace down to there.
+ SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc);
emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, SM, MacroDepth,
OnMacroInst + 1);
-
- // Save the original location so we can find the spelling of the macro call.
- SourceLocation MacroLoc = Loc;
-
- // Map the location.
- Loc = SM.getImmediateMacroCalleeLoc(Loc);
-
+
unsigned MacroSkipStart = 0, MacroSkipEnd = 0;
if (MacroDepth > DiagOpts->MacroBacktraceLimit &&
DiagOpts->MacroBacktraceLimit != 0) {
@@ -417,11 +407,11 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(
DiagOpts->MacroBacktraceLimit % 2;
MacroSkipEnd = MacroDepth - DiagOpts->MacroBacktraceLimit / 2;
}
-
+
// Whether to suppress printing this macro expansion.
bool Suppressed = (OnMacroInst >= MacroSkipStart &&
OnMacroInst < MacroSkipEnd);
-
+
if (Suppressed) {
// Tell the user that we've skipped contexts.
if (OnMacroInst == MacroSkipStart) {
@@ -435,15 +425,24 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(
return;
}
- // Map the ranges.
+ // Find the spelling location for the macro definition. We must use the
+ // spelling location here to avoid emitting a macro bactrace for the note.
+ SourceLocation SpellingLoc = Loc;
+ // If this is the expansion of a macro argument, point the caret at the
+ // use of the argument in the definition of the macro, not the expansion.
+ if (SM.isMacroArgExpansion(Loc))
+ SpellingLoc = SM.getImmediateExpansionRange(Loc).first;
+ SpellingLoc = SM.getSpellingLoc(SpellingLoc);
+
+ // Map the ranges into the FileID of the diagnostic location.
SmallVector<CharSourceRange, 4> SpellingRanges;
- mapDiagnosticRanges(MacroLoc, Ranges, SpellingRanges, &SM);
+ mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
SmallString<100> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
Message << "expanded from macro '"
- << getImmediateMacroName(MacroLoc, SM, LangOpts) << "'";
- emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note,
+ << getImmediateMacroName(Loc, SM, LangOpts) << "'";
+ emitDiagnostic(SpellingLoc, DiagnosticsEngine::Note,
Message.str(),
SpellingRanges, ArrayRef<FixItHint>(), &SM);
}