[cfe-commits] r142067 - in /cfe/trunk: include/clang/Frontend/TextDiagnosticPrinter.h lib/Frontend/TextDiagnosticPrinter.cpp

Chandler Carruth chandlerc at gmail.com
Sat Oct 15 04:44:28 PDT 2011


Author: chandlerc
Date: Sat Oct 15 06:44:27 2011
New Revision: 142067

URL: http://llvm.org/viewvc/llvm-project?rev=142067&view=rev
Log:
Rationalize some of how the locations of prior diagnostics are tracked
across emissions.

1) The include stack printing is conditioned on non-note diagnostics,
   not just on warning diagnostics.
2) Those should be full source locations as they're tied to a source
   manager.
3) We should pass in the prior state to the TextDiagnostic constructor,
   allow it to mutate as diagnostics are emitted, and then cache the
   final state before tearing it down.

Some of this remains incomplete, specifically #3 isn't finished for the
non-note location. That'll come when the include stack printing sinks
down a level.

This also highlights how *completely* bug-ridden this code is. For
example, we currently do all these comparisons of a FullSourceLoc and
a SourceLocation... which silently does a SourceLocation to
SourceLocation comparison, completely disregarding the source manager
from whence one of the arguments came. Oops! Good thing in practice this
wasn't important, but it could in theory be suppressing caret
diagnostics in a second TU on a single clang invocation. I'm hoping to
hammer these bugs out as the refactorings occur, although for so many of
them it's really unlikely I can dream up a test case that would show the
potentially buggy behavior.

Modified:
    cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h
    cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp

Modified: cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h?rev=142067&r1=142066&r2=142067&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h (original)
+++ cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h Sat Oct 15 06:44:27 2011
@@ -27,8 +27,8 @@
   const LangOptions *LangOpts;
   const DiagnosticOptions *DiagOpts;
 
-  SourceLocation LastWarningLoc;
   FullSourceLoc LastLoc;
+  FullSourceLoc LastNonNoteLoc;
   unsigned LastCaretDiagnosticWasNote : 1;
   unsigned OwnsOutputStream : 1;
 

Modified: cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp?rev=142067&r1=142066&r2=142067&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Sat Oct 15 06:44:27 2011
@@ -91,9 +91,9 @@
                                               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 @@
   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 @@
       unsigned MacroDepth = 0;
       EmitCaret(Loc, MutableRanges, FixItHints, MacroDepth);
     }
+
+    LastLoc = Loc;
   }
 
   /// \brief Emit the caret and underlining text.
@@ -1262,16 +1285,17 @@
   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();





More information about the cfe-commits mailing list