aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-10-15 22:39:16 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-10-15 22:39:16 +0000
commit03efd2efeeafc97db9a956df8c6ab88fbb6160da (patch)
tree050b17e0e5feac365e3199c4880894425cc4e1e9
parent43bcdb2d4d8390aec89e75f4d232b1fb218a59c5 (diff)
Rationalize the last bit of "arbitrary" state that is carried between
diagnostics to control suppression of redundant information. It now follows the same model as all the other state, and has a bit more clear semantics. This is making the duality of the state a bit annoying, and I've added a FIXME to resolve it. The problem is that I need to lift the TextDiagnostic up into an externally visible layer before that can happen. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142083 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h2
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp32
2 files changed, 24 insertions, 10 deletions
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index d6aa6ea94c..4a748f39c4 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -29,7 +29,7 @@ class TextDiagnosticPrinter : public DiagnosticConsumer {
FullSourceLoc LastLoc;
FullSourceLoc LastIncludeLoc;
- unsigned LastCaretDiagnosticWasNote : 1;
+ DiagnosticsEngine::Level LastLevel;
unsigned OwnsOutputStream : 1;
/// A string to prefix to error messages.
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 074d4134a6..30d2c6392b 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -43,8 +43,7 @@ const unsigned WordWrapIndentation = 6;
TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &os,
const DiagnosticOptions &diags,
bool _OwnsOutputStream)
- : OS(os), LangOpts(0), DiagOpts(&diags),
- LastCaretDiagnosticWasNote(0),
+ : OS(os), LangOpts(0), DiagOpts(&diags), LastLevel(),
OwnsOutputStream(_OwnsOutputStream) {
}
@@ -498,15 +497,23 @@ class TextDiagnostic {
/// root locations rather than diagnostic locations.
SourceLocation LastIncludeLoc;
+ /// \brief The level of the last diagnostic emitted.
+ ///
+ /// The level of the last diagnostic emitted. Used to detect level changes
+ /// which change the amount of information displayed.
+ DiagnosticsEngine::Level LastLevel;
+
public:
TextDiagnostic(raw_ostream &OS,
const SourceManager &SM,
const LangOptions &LangOpts,
const DiagnosticOptions &DiagOpts,
FullSourceLoc LastLoc = FullSourceLoc(),
- FullSourceLoc LastIncludeLoc = FullSourceLoc())
+ FullSourceLoc LastIncludeLoc = FullSourceLoc(),
+ DiagnosticsEngine::Level LastLevel
+ = DiagnosticsEngine::Level())
: OS(OS), SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts),
- LastLoc(LastLoc), LastIncludeLoc(LastIncludeLoc) {
+ LastLoc(LastLoc), LastIncludeLoc(LastIncludeLoc), LastLevel(LastLevel) {
if (LastLoc.isValid() && &SM != &LastLoc.getManager())
this->LastLoc = SourceLocation();
if (LastIncludeLoc.isValid() && &SM != &LastIncludeLoc.getManager())
@@ -519,6 +526,9 @@ public:
/// \brief Get the last emitted include stack location.
SourceLocation getLastIncludeLoc() const { return LastIncludeLoc; }
+ /// \brief Get the last diagnostic level.
+ DiagnosticsEngine::Level getLastLevel() const { return LastLevel; }
+
void Emit(SourceLocation Loc, DiagnosticsEngine::Level Level,
StringRef Message, ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> FixItHints,
@@ -550,7 +560,7 @@ public:
// multiple times if one loc has multiple diagnostics.
if (DiagOpts.ShowCarets &&
(Loc != LastLoc || !Ranges.empty() || !FixItHints.empty() ||
- (LastCaretDiagnosticWasNote && Level != DiagnosticsEngine::Note))) {
+ (LastLevel == DiagnosticsEngine::Note && Level != LastLevel))) {
// Get the ranges into a local array we can hack on.
SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(),
Ranges.end());
@@ -566,6 +576,7 @@ public:
}
LastLoc = Loc;
+ LastLevel = Level;
}
/// \brief Emit the caret and underlining text.
@@ -1279,18 +1290,21 @@ void TextDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
"Unexpected diagnostic with no source manager");
const SourceManager &SM = Info.getSourceManager();
TextDiagnostic TextDiag(OS, SM, *LangOpts, *DiagOpts,
- LastLoc, LastIncludeLoc);
+ LastLoc, LastIncludeLoc, LastLevel);
TextDiag.Emit(Info.getLocation(), Level, DiagMessageStream.str(),
Info.getRanges(),
llvm::makeArrayRef(Info.getFixItHints(),
- Info.getNumFixItHints()),
- LastCaretDiagnosticWasNote);
+ Info.getNumFixItHints()));
// Cache the LastLoc from the TextDiagnostic printing.
+ // FIXME: Rather than this, we should persist a TextDiagnostic object across
+ // diagnostics until the SourceManager changes. That will allow the
+ // TextDiagnostic object to form a 'session' of output where we can
+ // reasonably collapse redundant information.
LastLoc = FullSourceLoc(TextDiag.getLastLoc(), SM);
LastIncludeLoc = FullSourceLoc(TextDiag.getLastIncludeLoc(), SM);
- LastCaretDiagnosticWasNote = (Level == DiagnosticsEngine::Note);
+ LastLevel = TextDiag.getLastLevel();
OS.flush();
}