aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/TextDiagnosticPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/TextDiagnosticPrinter.cpp')
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp48
1 files changed, 36 insertions, 12 deletions
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 62ce684387..8593e22f10 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -91,9 +91,9 @@ void TextDiagnosticPrinter::PrintIncludeStack(DiagnosticsEngine::Level Level,
SourceLocation Loc,
const SourceManager &SM) {
// Skip redundant include stacks altogether.
- if (LastWarningLoc == Loc)
+ if (LastNonNoteLoc == Loc)
return;
- LastWarningLoc = Loc;
+ LastNonNoteLoc = FullSourceLoc(Loc, SM);
if (!DiagOpts->ShowNoteIncludeStack && Level == DiagnosticsEngine::Note)
return;
@@ -537,19 +537,40 @@ class TextDiagnostic {
const LangOptions &LangOpts;
const DiagnosticOptions &DiagOpts;
+ /// \brief The location of the previous diagnostic if known.
+ ///
+ /// This will be invalid in cases where there is no (known) previous
+ /// diagnostic location, or that location itself is invalid or comes from
+ /// a different source manager than SM.
+ SourceLocation LastLoc;
+
+ /// \brief The location of the previous non-note diagnostic if known.
+ ///
+ /// Same restriction as \see LastLoc but tracks the last non-note location.
+ SourceLocation LastNonNoteLoc;
+
public:
TextDiagnostic(TextDiagnosticPrinter &Printer,
- raw_ostream &OS,
- const SourceManager &SM,
- const LangOptions &LangOpts,
- const DiagnosticOptions &DiagOpts)
- : Printer(Printer), OS(OS), SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts) {
+ raw_ostream &OS,
+ const SourceManager &SM,
+ const LangOptions &LangOpts,
+ const DiagnosticOptions &DiagOpts,
+ FullSourceLoc LastLoc = FullSourceLoc(),
+ FullSourceLoc LastNonNoteLoc = FullSourceLoc())
+ : Printer(Printer), OS(OS), SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts),
+ LastLoc(LastLoc), LastNonNoteLoc(LastNonNoteLoc) {
+ if (LastLoc.isValid() && &SM != &LastLoc.getManager())
+ this->LastLoc = SourceLocation();
+ if (LastNonNoteLoc.isValid() && &SM != &LastNonNoteLoc.getManager())
+ this->LastNonNoteLoc = SourceLocation();
}
+ /// \brief Get the last diagnostic location emitted.
+ SourceLocation getLastLoc() const { return LastLoc; }
+
void Emit(SourceLocation Loc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
- FullSourceLoc LastLoc = FullSourceLoc(),
bool LastCaretDiagnosticWasNote = false) {
PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Loc);
@@ -592,6 +613,8 @@ public:
unsigned MacroDepth = 0;
EmitCaret(Loc, MutableRanges, FixItHints, MacroDepth);
}
+
+ LastLoc = Loc;
}
/// \brief Emit the caret and underlining text.
@@ -1262,16 +1285,17 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
assert(Info.hasSourceManager() &&
"Unexpected diagnostic with no source manager");
const SourceManager &SM = Info.getSourceManager();
- TextDiagnostic TextDiag(*this, OS, SM, *LangOpts, *DiagOpts);
+ TextDiagnostic TextDiag(*this, OS, SM, *LangOpts, *DiagOpts,
+ LastNonNoteLoc, LastLoc);
TextDiag.Emit(Info.getLocation(), Level, DiagMessageStream.str(),
Info.getRanges(),
llvm::makeArrayRef(Info.getFixItHints(),
Info.getNumFixItHints()),
- LastLoc, LastCaretDiagnosticWasNote);
+ LastCaretDiagnosticWasNote);
- // Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
- LastLoc = FullSourceLoc(Info.getLocation(), Info.getSourceManager());
+ // Cache the LastLoc from the TextDiagnostic printing.
+ LastLoc = FullSourceLoc(TextDiag.getLastLoc(), SM);
LastCaretDiagnosticWasNote = (Level == DiagnosticsEngine::Note);
OS.flush();