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

Daniel Dunbar daniel at zuster.org
Thu Apr 7 11:37:34 PDT 2011


Author: ddunbar
Date: Thu Apr  7 13:37:34 2011
New Revision: 129091

URL: http://llvm.org/viewvc/llvm-project?rev=129091&view=rev
Log:
Frontend: Continue flushing out LogDiagnosticPrinter.

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

Modified: cfe/trunk/include/clang/Frontend/LogDiagnosticPrinter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/LogDiagnosticPrinter.h?rev=129091&r1=129090&r2=129091&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/LogDiagnosticPrinter.h (original)
+++ cfe/trunk/include/clang/Frontend/LogDiagnosticPrinter.h Thu Apr  7 13:37:34 2011
@@ -12,12 +12,33 @@
 
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVector.h"
 
 namespace clang {
 class DiagnosticOptions;
 class LangOptions;
 
 class LogDiagnosticPrinter : public DiagnosticClient {
+  struct DiagEntry {
+    /// The primary message line of the diagnostic.
+    std::string Message;
+  
+    /// The source file name, if available.
+    std::string Filename;
+  
+    /// The source file line number, if available.
+    unsigned Line;
+  
+    /// The source file column number, if available.
+    unsigned Column;
+  
+    /// The ID of the diagnostic.
+    unsigned DiagnosticID;
+  
+    /// The level of the diagnostic.
+    Diagnostic::Level DiagnosticLevel;
+  };
+  
   llvm::raw_ostream &OS;
   const LangOptions *LangOpts;
   const DiagnosticOptions *DiagOpts;
@@ -26,6 +47,8 @@
   FullSourceLoc LastLoc;
   unsigned OwnsOutputStream : 1;
 
+  llvm::SmallVector<DiagEntry, 8> Entries;
+
 public:
   LogDiagnosticPrinter(llvm::raw_ostream &OS, const DiagnosticOptions &Diags,
                        bool OwnsOutputStream = false);
@@ -35,9 +58,7 @@
     LangOpts = &LO;
   }
 
-  void EndSourceFile() {
-    LangOpts = 0;
-  }
+  void EndSourceFile();
 
   virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
                                 const DiagnosticInfo &Info);

Modified: cfe/trunk/lib/Frontend/LogDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/LogDiagnosticPrinter.cpp?rev=129091&r1=129090&r2=129091&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/LogDiagnosticPrinter.cpp (original)
+++ cfe/trunk/lib/Frontend/LogDiagnosticPrinter.cpp Thu Apr  7 13:37:34 2011
@@ -8,6 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/LogDiagnosticPrinter.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
@@ -24,16 +26,90 @@
     delete &OS;
 }
 
-void LogDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
-                                             const DiagnosticInfo &Info) {
-  // Default implementation (Warnings/errors count).
-  DiagnosticClient::HandleDiagnostic(Level, Info);
+static llvm::StringRef getLevelName(Diagnostic::Level Level) {
+  switch (Level) {
+  default:
+    return "<unknown>";
+  case Diagnostic::Ignored: return "ignored";
+  case Diagnostic::Note:    return "note";
+  case Diagnostic::Warning: return "warning";
+  case Diagnostic::Error:   return "error";
+  case Diagnostic::Fatal:   return "fatal error";
+  }
+}
+
+void LogDiagnosticPrinter::EndSourceFile() {
+  // We emit all the diagnostics in EndSourceFile. However, we don't emit any
+  // entry if no diagnostics were present.
+  //
+  // Note that DiagnosticClient has no "end-of-compilation" callback, so we will
+  // miss any diagnostics which are emitted after and outside the translation
+  // unit processing.
+  if (Entries.empty())
+    return;
 
   // Write to a temporary string to ensure atomic write of diagnostic object.
   llvm::SmallString<512> Msg;
   llvm::raw_svector_ostream OS(Msg);
 
-  OS << "hello!\n";
+  OS << "{\n";
+  // FIXME: Output main translation unit file name.
+  // FIXME: Include the invocation, if dwarf-debug-flags is available.
+  OS << "  \"diagnostics\" : [\n";
+  for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
+    DiagEntry &DE = Entries[i];
+
+    OS << "    {\n";
+    OS << "      \"filename\" : \"" << DE.Filename << "\",\n";
+    OS << "      \"line\" : " << DE.Line << ",\n";
+    OS << "      \"column\" : " << DE.Column << ",\n";
+    OS << "      \"message\" : \"" << DE.Message << "\",\n";
+    OS << "      \"level\" : \"" << getLevelName(DE.DiagnosticLevel) << "\"\n";
+    OS << "    }" << ((i + 1 != e) ? "," : "") << '\n';
+  }
+  OS << "  ]\n";
+  OS << "},\n";
 
   this->OS << OS.str();
 }
+
+void LogDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
+                                            const DiagnosticInfo &Info) {
+  // Default implementation (Warnings/errors count).
+  DiagnosticClient::HandleDiagnostic(Level, Info);
+
+  // Create the diag entry.
+  DiagEntry DE;
+  DE.DiagnosticID = Info.getID();
+  DE.DiagnosticLevel = Level;
+
+  // Format the message.
+  llvm::SmallString<100> MessageStr;
+  Info.FormatDiagnostic(MessageStr);
+  DE.Message = MessageStr.str();
+
+  // Set the location information.
+  DE.Filename = "";
+  DE.Line = DE.Column = 0;
+  if (Info.getLocation().isValid()) {
+    const SourceManager &SM = Info.getSourceManager();
+    PresumedLoc PLoc = SM.getPresumedLoc(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())
+          DE.Filename = FE->getName();
+      }
+    } else {
+      DE.Filename = PLoc.getFilename();
+      DE.Line = PLoc.getLine();
+      DE.Column = PLoc.getColumn();
+    }
+  }
+
+  // Record the diagnostic entry.
+  Entries.push_back(DE);
+}





More information about the cfe-commits mailing list