summaryrefslogtreecommitdiffstats
path: root/lib/Frontend/DiagnosticRenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/DiagnosticRenderer.cpp')
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp127
1 files changed, 36 insertions, 91 deletions
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index 6c3bb1d..f052f90 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -22,56 +22,6 @@
#include <algorithm>
using namespace clang;
-/// 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.
-static SourceLocation skipToMacroArgExpansion(const SourceManager &SM,
- SourceLocation StartLoc) {
- for (SourceLocation L = StartLoc; L.isMacroID();
- L = SM.getImmediateSpellingLoc(L)) {
- if (SM.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.
-static SourceLocation getImmediateMacroCallerLoc(const SourceManager &SM,
- SourceLocation Loc) {
- 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, and
- // therefore is used to locate the macro caller.
- if (SM.isMacroArgExpansion(Loc))
- return SM.getImmediateSpellingLoc(Loc);
-
- // Otherwise, the caller of the macro is located where this macro is
- // expanded (while the spelling is part of the macro definition).
- return SM.getImmediateExpansionRange(Loc).first;
-}
-
-/// Gets the location of the immediate macro callee, one level down the stack
-/// toward the leaf macro.
-static SourceLocation getImmediateMacroCalleeLoc(const SourceManager &SM,
- SourceLocation Loc) {
- if (!Loc.isMacroID()) return Loc;
-
- // When we have the location of (part of) an expanded parameter, its
- // expansion location points to the unexpanded paramater reference within
- // the macro definition (or callee).
- if (SM.isMacroArgExpansion(Loc))
- return SM.getImmediateExpansionRange(Loc).first;
-
- // Otherwise, the callee of the macro is located where this location was
- // spelled inside the macro definition.
- return SM.getImmediateSpellingLoc(Loc);
-}
-
/// \brief Retrieve the name of the immediate macro expansion.
///
/// This routine starts from a source location, and finds the name of the macro
@@ -109,24 +59,9 @@ static StringRef getImmediateMacroName(SourceLocation Loc,
return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength);
}
-/// Get the presumed location of a diagnostic message. This computes the
-/// presumed location for the top of any macro backtrace when present.
-static PresumedLoc getDiagnosticPresumedLoc(const SourceManager &SM,
- SourceLocation Loc) {
- // 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(SM, Loc);
- Loc = getImmediateMacroCallerLoc(SM, Loc);
- }
-
- return SM.getPresumedLoc(Loc);
-}
-
-DiagnosticRenderer::DiagnosticRenderer(const SourceManager &SM,
- const LangOptions &LangOpts,
+DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts,
const DiagnosticOptions &DiagOpts)
-: SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
+: LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
DiagnosticRenderer::~DiagnosticRenderer() {}
@@ -184,18 +119,23 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
StringRef Message,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
+ const SourceManager *SM,
DiagOrStoredDiag D) {
+ assert(SM || Loc.isInvalid());
beginDiagnostic(D, Level);
- PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Loc);
+ PresumedLoc PLoc;
+ if (Loc.isValid()) {
+ PLoc = SM->getPresumedLocForDisplay(Loc);
- // First, if this diagnostic is not in the main file, print out the
- // "included from" lines.
- emitIncludeStack(PLoc.getIncludeLoc(), Level);
+ // First, if this diagnostic is not in the main file, print out the
+ // "included from" lines.
+ emitIncludeStack(PLoc.getIncludeLoc(), Level, *SM);
+ }
// Next, emit the actual diagnostic message.
- emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, D);
+ emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, SM, D);
// Only recurse if we have a valid location.
if (Loc.isValid()) {
@@ -205,7 +145,7 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
llvm::SmallVector<FixItHint, 8> MergedFixits;
if (!FixItHints.empty()) {
- mergeFixits(FixItHints, SM, LangOpts, MergedFixits);
+ mergeFixits(FixItHints, *SM, LangOpts, MergedFixits);
FixItHints = MergedFixits;
}
@@ -216,7 +156,7 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
MutableRanges.push_back(I->RemoveRange);
unsigned MacroDepth = 0;
- emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints,
+ emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints, *SM,
MacroDepth);
}
@@ -230,6 +170,8 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) {
emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(),
Diag.getRanges(), Diag.getFixIts(),
+ Diag.getLocation().isValid() ? &Diag.getLocation().getManager()
+ : 0,
&Diag);
}
@@ -245,7 +187,8 @@ void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) {
/// \param Loc The include location of the current file (not the diagnostic
/// location).
void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
- DiagnosticsEngine::Level Level) {
+ DiagnosticsEngine::Level Level,
+ const SourceManager &SM) {
// Skip redundant include stacks altogether.
if (LastIncludeLoc == Loc)
return;
@@ -254,12 +197,13 @@ void DiagnosticRenderer::emitIncludeStack(SourceLocation Loc,
if (!DiagOpts.ShowNoteIncludeStack && Level == DiagnosticsEngine::Note)
return;
- emitIncludeStackRecursively(Loc);
+ emitIncludeStackRecursively(Loc, SM);
}
/// \brief Helper to recursivly walk up the include stack and print each layer
/// on the way back down.
-void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc) {
+void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc,
+ const SourceManager &SM) {
if (Loc.isInvalid())
return;
@@ -268,10 +212,10 @@ void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc) {
return;
// Emit the other include frames first.
- emitIncludeStackRecursively(PLoc.getIncludeLoc());
+ emitIncludeStackRecursively(PLoc.getIncludeLoc(), SM);
// Emit the inclusion text/note.
- emitIncludeLocation(Loc, PLoc);
+ emitIncludeLocation(Loc, PLoc, SM);
}
/// \brief Recursively emit notes for each macro expansion and caret
@@ -292,6 +236,7 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(
DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
+ const SourceManager &SM,
unsigned &MacroDepth,
unsigned OnMacroInst)
{
@@ -302,26 +247,26 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(
if (Loc.isFileID()) {
assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!");
MacroDepth = OnMacroInst;
- emitCodeContext(Loc, Level, Ranges, Hints);
+ emitCodeContext(Loc, Level, Ranges, Hints, SM);
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 = skipToMacroArgExpansion(SM, Loc);
+ Loc = SM.skipToMacroArgExpansion(Loc);
- SourceLocation OneLevelUp = getImmediateMacroCallerLoc(SM, Loc);
+ SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc);
// FIXME: Map ranges?
- emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, MacroDepth,
+ 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 = getImmediateMacroCalleeLoc(SM, Loc);
+ Loc = SM.getImmediateMacroCalleeLoc(Loc);
unsigned MacroSkipStart = 0, MacroSkipEnd = 0;
if (MacroDepth > DiagOpts.MacroBacktraceLimit &&
@@ -341,9 +286,9 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(
I != E; ++I) {
SourceLocation Start = I->getBegin(), End = I->getEnd();
if (Start.isMacroID())
- I->setBegin(getImmediateMacroCalleeLoc(SM, Start));
+ I->setBegin(SM.getImmediateMacroCalleeLoc(Start));
if (End.isMacroID())
- I->setEnd(getImmediateMacroCalleeLoc(SM, End));
+ I->setEnd(SM.getImmediateMacroCalleeLoc(End));
}
if (Suppressed) {
@@ -365,22 +310,22 @@ void DiagnosticRenderer::emitMacroExpansionsAndCarets(
<< getImmediateMacroName(MacroLoc, SM, LangOpts) << "'";
emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note,
Message.str(),
- Ranges, ArrayRef<FixItHint>());
+ Ranges, ArrayRef<FixItHint>(), &SM);
}
DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
void DiagnosticNoteRenderer::emitIncludeLocation(SourceLocation Loc,
- PresumedLoc PLoc) {
+ PresumedLoc PLoc,
+ const SourceManager &SM) {
// Generate a note indicating the include location.
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
Message << "in file included from " << PLoc.getFilename() << ':'
<< PLoc.getLine() << ":";
- emitNote(Loc, Message.str());
+ emitNote(Loc, Message.str(), &SM);
}
void DiagnosticNoteRenderer::emitBasicNote(StringRef Message) {
- emitNote(SourceLocation(), Message);
+ emitNote(SourceLocation(), Message, 0);
}
-
OpenPOWER on IntegriCloud