]> granicus.if.org Git - clang/commitdiff
Rationalize the last bit of "arbitrary" state that is carried between
authorChandler Carruth <chandlerc@gmail.com>
Sat, 15 Oct 2011 22:39:16 +0000 (22:39 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Sat, 15 Oct 2011 22:39:16 +0000 (22:39 +0000)
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

include/clang/Frontend/TextDiagnosticPrinter.h
lib/Frontend/TextDiagnosticPrinter.cpp

index d6aa6ea94cfb6eeb7ace7b9900690c9d2a782f09..4a748f39c421253aa430a81b1afd661901e1b514 100644 (file)
@@ -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.
index 074d4134a6339427778c0fa7acb3cb86149b47e4..30d2c6392b0e590ef1a59500b3963fa80c1ea498 100644 (file)
@@ -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();
 }