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

Chandler Carruth chandlerc at gmail.com
Wed Sep 7 01:05:58 PDT 2011


Author: chandlerc
Date: Wed Sep  7 03:05:58 2011
New Revision: 139228

URL: http://llvm.org/viewvc/llvm-project?rev=139228&view=rev
Log:
Extract the emission of the diagnostic's location into a separate
function. This is really the beginning of the second phase of
refactorings here. The end goal is to have (roughly) three interfaces:

1) Base class to format a single diagnostic suitable for display on the
   console.
2) Extension of the base class which also displays a caret diagnostic
   suitable for display on the console.
3) An adaptor that implements the DiagnosticClient by delegating to #1
   and/or #2 as appropriate.

Once we have these, things like libclang's formatDiagnostic can use #1
and #2 to provide really well formatted (and consistently formatted!)
textual formatting of diagnostics.

Getting there is going to be quite a bit of shuffling. I'm basically
sketching out where the interface boundaries can be drawn for #1 and #2
within the existing classes. That lets me shuffle with a minimum of fuss
and delta. Once that's done, and any of the related interfaces that need
to change are updated, I'll hoist these into separate headers and
re-implement libclang in terms of their interfaces. Long WIP, but
comments at each step welcome. =D

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=139228&r1=139227&r2=139228&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h (original)
+++ cfe/trunk/include/clang/Frontend/TextDiagnosticPrinter.h Wed Sep  7 03:05:58 2011
@@ -60,6 +60,11 @@
                                 const DiagnosticInfo &Info);
 
 private:
+  void EmitDiagnosticLoc(Diagnostic::Level Level,
+                         const DiagnosticInfo &Info,
+                         const SourceManager &SM,
+                         PresumedLoc PLoc);
+
   void EmitCaretDiagnostic(SourceLocation Loc,
                            SmallVectorImpl<CharSourceRange> &Ranges,
                            const SourceManager &SM,

Modified: cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp?rev=139228&r1=139227&r2=139228&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/TextDiagnosticPrinter.cpp Wed Sep  7 03:05:58 2011
@@ -942,6 +942,114 @@
   return SM.getPresumedLoc(Loc);
 }
 
+/// \brief Print out the file/line/column information and include trace.
+///
+/// This method handlen the emission of the diagnostic location information.
+/// This includes extracting as much location information as is present for the
+/// diagnostic and printing it, as well as any include stack or source ranges
+/// necessary.
+void TextDiagnosticPrinter::EmitDiagnosticLoc(Diagnostic::Level Level,
+                                              const DiagnosticInfo &Info,
+                                              const SourceManager &SM,
+                                              PresumedLoc PLoc) {
+  if (PLoc.isInvalid()) {
+    // At least print the file name if available:
+    FileID FID = SM.getFileID(Info.getLocation());
+    if (!FID.isInvalid()) {
+      const FileEntry* FE = SM.getFileEntryForID(FID);
+      if (FE && FE->getName()) {
+        OS << FE->getName();
+        if (FE->getDevice() == 0 && FE->getInode() == 0
+            && FE->getFileMode() == 0) {
+          // in PCH is a guess, but a good one:
+          OS << " (in PCH)";
+        }
+        OS << ": ";
+      }
+    }
+    return;
+  }
+  unsigned LineNo = PLoc.getLine();
+
+  if (!DiagOpts->ShowLocation)
+    return;
+
+  if (DiagOpts->ShowColors)
+    OS.changeColor(savedColor, true);
+
+  OS << PLoc.getFilename();
+  switch (DiagOpts->Format) {
+  case DiagnosticOptions::Clang: OS << ':'  << LineNo; break;
+  case DiagnosticOptions::Msvc:  OS << '('  << LineNo; break;
+  case DiagnosticOptions::Vi:    OS << " +" << LineNo; break;
+  }
+
+  if (DiagOpts->ShowColumn)
+    // Compute the column number.
+    if (unsigned ColNo = PLoc.getColumn()) {
+      if (DiagOpts->Format == DiagnosticOptions::Msvc) {
+        OS << ',';
+        ColNo--;
+      } else 
+        OS << ':';
+      OS << ColNo;
+    }
+  switch (DiagOpts->Format) {
+  case DiagnosticOptions::Clang: 
+  case DiagnosticOptions::Vi:    OS << ':';    break;
+  case DiagnosticOptions::Msvc:  OS << ") : "; break;
+  }
+
+  if (DiagOpts->ShowSourceRanges && Info.getNumRanges()) {
+    FileID CaretFileID =
+      SM.getFileID(SM.getExpansionLoc(Info.getLocation()));
+    bool PrintedRange = false;
+
+    for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) {
+      // Ignore invalid ranges.
+      if (!Info.getRange(i).isValid()) continue;
+
+      SourceLocation B = Info.getRange(i).getBegin();
+      SourceLocation E = Info.getRange(i).getEnd();
+      B = SM.getExpansionLoc(B);
+      E = SM.getExpansionLoc(E);
+
+      // If the End location and the start location are the same and are a
+      // macro location, then the range was something that came from a
+      // macro expansion or _Pragma.  If this is an object-like macro, the
+      // best we can do is to highlight the range.  If this is a
+      // function-like macro, we'd also like to highlight the arguments.
+      if (B == E && Info.getRange(i).getEnd().isMacroID())
+        E = SM.getExpansionRange(Info.getRange(i).getEnd()).second;
+
+      std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
+      std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
+
+      // If the start or end of the range is in another file, just discard
+      // it.
+      if (BInfo.first != CaretFileID || EInfo.first != CaretFileID)
+        continue;
+
+      // Add in the length of the token, so that we cover multi-char
+      // tokens.
+      unsigned TokSize = 0;
+      if (Info.getRange(i).isTokenRange())
+        TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts);
+
+      OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
+        << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
+        << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
+        << (SM.getColumnNumber(EInfo.first, EInfo.second)+TokSize)
+        << '}';
+      PrintedRange = true;
+    }
+
+    if (PrintedRange)
+      OS << ':';
+  }
+  OS << ' ';
+}
+
 void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
                                              const DiagnosticInfo &Info) {
   // Default implementation (Warnings/errors count).
@@ -956,113 +1064,20 @@
   if (!Prefix.empty())
     OS << Prefix << ": ";
 
-  // If the location is specified, print out a file/line/col and include trace
-  // if enabled.
   if (Info.getLocation().isValid()) {
     const SourceManager &SM = Info.getSourceManager();
     PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Info.getLocation());
-    if (PLoc.isInvalid()) {
-      // At least print the file name if available:
-      FileID FID = SM.getFileID(Info.getLocation());
-      if (!FID.isInvalid()) {
-        const FileEntry* FE = SM.getFileEntryForID(FID);
-        if (FE && FE->getName()) {
-          OS << FE->getName();
-          if (FE->getDevice() == 0 && FE->getInode() == 0
-              && FE->getFileMode() == 0) {
-            // in PCH is a guess, but a good one:
-            OS << " (in PCH)";
-          }
-          OS << ": ";
-        }
-      }
-    } else {
-      unsigned LineNo = PLoc.getLine();
 
-      // First, if this diagnostic is not in the main file, print out the
-      // "included from" lines.
-      PrintIncludeStack(Level, PLoc.getIncludeLoc(), SM);
-      StartOfLocationInfo = OS.tell();
-
-      // Compute the column number.
-      if (DiagOpts->ShowLocation) {
-        if (DiagOpts->ShowColors)
-          OS.changeColor(savedColor, true);
-
-        OS << PLoc.getFilename();
-        switch (DiagOpts->Format) {
-        case DiagnosticOptions::Clang: OS << ':'  << LineNo; break;
-        case DiagnosticOptions::Msvc:  OS << '('  << LineNo; break;
-        case DiagnosticOptions::Vi:    OS << " +" << LineNo; break;
-        }
-        if (DiagOpts->ShowColumn)
-          if (unsigned ColNo = PLoc.getColumn()) {
-            if (DiagOpts->Format == DiagnosticOptions::Msvc) {
-              OS << ',';
-              ColNo--;
-            } else 
-              OS << ':';
-            OS << ColNo;
-          }
-        switch (DiagOpts->Format) {
-        case DiagnosticOptions::Clang: 
-        case DiagnosticOptions::Vi:    OS << ':';    break;
-        case DiagnosticOptions::Msvc:  OS << ") : "; break;
-        }
+    // First, if this diagnostic is not in the main file, print out the
+    // "included from" lines.
+    PrintIncludeStack(Level, PLoc.getIncludeLoc(), SM);
+    StartOfLocationInfo = OS.tell();
 
-                
-        if (DiagOpts->ShowSourceRanges && Info.getNumRanges()) {
-          FileID CaretFileID =
-            SM.getFileID(SM.getExpansionLoc(Info.getLocation()));
-          bool PrintedRange = false;
-
-          for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) {
-            // Ignore invalid ranges.
-            if (!Info.getRange(i).isValid()) continue;
-
-            SourceLocation B = Info.getRange(i).getBegin();
-            SourceLocation E = Info.getRange(i).getEnd();
-            B = SM.getExpansionLoc(B);
-            E = SM.getExpansionLoc(E);
-
-            // If the End location and the start location are the same and are a
-            // macro location, then the range was something that came from a
-            // macro expansion or _Pragma.  If this is an object-like macro, the
-            // best we can do is to highlight the range.  If this is a
-            // function-like macro, we'd also like to highlight the arguments.
-            if (B == E && Info.getRange(i).getEnd().isMacroID())
-              E = SM.getExpansionRange(Info.getRange(i).getEnd()).second;
-
-            std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
-            std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
-
-            // If the start or end of the range is in another file, just discard
-            // it.
-            if (BInfo.first != CaretFileID || EInfo.first != CaretFileID)
-              continue;
-
-            // Add in the length of the token, so that we cover multi-char
-            // tokens.
-            unsigned TokSize = 0;
-            if (Info.getRange(i).isTokenRange())
-              TokSize = Lexer::MeasureTokenLength(E, SM, *LangOpts);
-
-            OS << '{' << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
-               << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
-               << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
-               << (SM.getColumnNumber(EInfo.first, EInfo.second)+TokSize)
-               << '}';
-            PrintedRange = true;
-          }
+    // Next emit the location of this particular diagnostic.
+    EmitDiagnosticLoc(Level, Info, SM, PLoc);
 
-          if (PrintedRange)
-            OS << ':';
-        }
-      }
-      OS << ' ';
-      if (DiagOpts->ShowColors)
-        OS.resetColor();
-    }
+    if (DiagOpts->ShowColors)
+      OS.resetColor();
   }
 
   if (DiagOpts->ShowColors) {





More information about the cfe-commits mailing list