[cfe-commits] r77264 - in /cfe/trunk: include/clang/Frontend/Analyses.def include/clang/Frontend/PathDiagnosticClients.h lib/Frontend/AnalysisConsumer.cpp lib/Frontend/HTMLDiagnostics.cpp lib/Frontend/PlistDiagnostics.cpp

Ted Kremenek kremenek at apple.com
Mon Jul 27 15:13:40 PDT 2009


Author: kremenek
Date: Mon Jul 27 17:13:39 2009
New Revision: 77264

URL: http://llvm.org/viewvc/llvm-project?rev=77264&view=rev
Log:
(1) Enable PlistDiagnostics to take an option "PathDiagnosticClientFactory"
object that it can use to forward PathDiagnostics for further processing. Along
with this feature, the PlistDiagnostics object logs which files are created by
the forwarding of the PathDiagnostics.

(2) Create a new PathDiagnosticClientFactory object for HTMLDiagnostics,
allowing other PathDiagnosticClients to forward PathDiagnostics through an
opaque interface.

(3) Create a "plist-html" diagnostics option in AnalysisConsumer to allow the
    logging of HTML files created in a hybrid Plist+HTML diagnostic client.

Modified:
    cfe/trunk/include/clang/Frontend/Analyses.def
    cfe/trunk/include/clang/Frontend/PathDiagnosticClients.h
    cfe/trunk/lib/Frontend/AnalysisConsumer.cpp
    cfe/trunk/lib/Frontend/HTMLDiagnostics.cpp
    cfe/trunk/lib/Frontend/PlistDiagnostics.cpp

Modified: cfe/trunk/include/clang/Frontend/Analyses.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/Analyses.def?rev=77264&r1=77263&r2=77264&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/Analyses.def (original)
+++ cfe/trunk/include/clang/Frontend/Analyses.def Mon Jul 27 17:13:39 2009
@@ -69,6 +69,7 @@
 
 ANALYSIS_DIAGNOSTICS(HTML,  "html",  "Output analysis results using HTML",   CreateHTMLDiagnosticClient, false)
 ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", CreatePlistDiagnosticClient, true)
+ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", CreatePlistHTMLDiagnosticClient, true)
 
 #undef ANALYSIS
 #undef ANALYSIS_STORE

Modified: cfe/trunk/include/clang/Frontend/PathDiagnosticClients.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PathDiagnosticClients.h?rev=77264&r1=77263&r2=77264&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PathDiagnosticClients.h (original)
+++ cfe/trunk/include/clang/Frontend/PathDiagnosticClients.h Mon Jul 27 17:13:39 2009
@@ -14,21 +14,41 @@
 #ifndef LLVM_CLANG_FRONTEND_PATH_DIAGNOSTIC_CLIENTS_H
 #define LLVM_CLANG_FRONTEND_PATH_DIAGNOSTIC_CLiENTS_H
 
+#include <memory>
 #include <string>
+#include "llvm/ADT/SmallVector.h"
 
 namespace clang {
 
 class PathDiagnosticClient;
 class Preprocessor;
 class PreprocessorFactory;
+  
+class PathDiagnosticClientFactory {
+public:
+  PathDiagnosticClientFactory() {}
+  virtual ~PathDiagnosticClientFactory() {}
+  
+  virtual const char *getName() const = 0;
 
-PathDiagnosticClient* CreateHTMLDiagnosticClient(const std::string& prefix,
-                                                 Preprocessor* PP = 0,
-                                                 PreprocessorFactory* PPF = 0);
+  virtual PathDiagnosticClient*
+  createPathDiagnosticClient(llvm::SmallVectorImpl<std::string> *FilesMade) = 0;
+};
+
+PathDiagnosticClient*
+CreateHTMLDiagnosticClient(const std::string& prefix, Preprocessor* PP = 0,
+                           PreprocessorFactory* PPF = 0,
+                           llvm::SmallVectorImpl<std::string>* FilesMade = 0);
+  
+PathDiagnosticClientFactory*
+CreateHTMLDiagnosticClientFactory(const std::string& prefix,
+                                  Preprocessor* PP = 0,
+                                  PreprocessorFactory* PPF = 0);
   
-PathDiagnosticClient* CreatePlistDiagnosticClient(const std::string& prefix,
-                                                  Preprocessor* PP,
-                                                  PreprocessorFactory* PPF);
-}
+PathDiagnosticClient*
+CreatePlistDiagnosticClient(const std::string& prefix, Preprocessor* PP,
+                            PreprocessorFactory* PPF,
+                            PathDiagnosticClientFactory *PF = 0);
 
+} // end clang namespace
 #endif

Modified: cfe/trunk/lib/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/AnalysisConsumer.cpp?rev=77264&r1=77263&r2=77264&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/Frontend/AnalysisConsumer.cpp Mon Jul 27 17:13:39 2009
@@ -50,6 +50,19 @@
 } // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
+// Special PathDiagnosticClients.
+//===----------------------------------------------------------------------===//
+
+static PathDiagnosticClient*
+CreatePlistHTMLDiagnosticClient(const std::string& prefix, Preprocessor* PP,
+                            PreprocessorFactory* PPF) {
+  llvm::sys::Path F(prefix);  
+  PathDiagnosticClientFactory *PF = 
+    CreateHTMLDiagnosticClientFactory(F.getDirname(), PP, PPF);
+  return CreatePlistDiagnosticClient(prefix, PP, PPF, PF);
+}
+
+//===----------------------------------------------------------------------===//
 // AnalysisConsumer declaration.
 //===----------------------------------------------------------------------===//
 

Modified: cfe/trunk/lib/Frontend/HTMLDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/HTMLDiagnostics.cpp?rev=77264&r1=77263&r2=77264&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/HTMLDiagnostics.cpp (original)
+++ cfe/trunk/lib/Frontend/HTMLDiagnostics.cpp Mon Jul 27 17:13:39 2009
@@ -39,9 +39,11 @@
   llvm::sys::Path Directory, FilePrefix;
   bool createdDir, noDir;
   Preprocessor* PP;
-  std::vector<const PathDiagnostic*> BatchedDiags;  
+  std::vector<const PathDiagnostic*> BatchedDiags;
+  llvm::SmallVectorImpl<std::string> *FilesMade;  
 public:
-  HTMLDiagnostics(const std::string& prefix, Preprocessor* pp);
+  HTMLDiagnostics(const std::string& prefix, Preprocessor* pp,
+                  llvm::SmallVectorImpl<std::string> *filesMade = 0);
 
   virtual ~HTMLDiagnostics();
   
@@ -65,9 +67,10 @@
   
 } // end anonymous namespace
 
-HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix, Preprocessor* pp)
+HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix, Preprocessor* pp,
+                                 llvm::SmallVectorImpl<std::string>* filesMade)
   : Directory(prefix), FilePrefix(prefix), createdDir(false), noDir(false),
-    PP(pp) {
+    PP(pp), FilesMade(filesMade) {
   
   // All html files begin with "report" 
   FilePrefix.appendComponent("report");
@@ -75,8 +78,43 @@
 
 PathDiagnosticClient*
 clang::CreateHTMLDiagnosticClient(const std::string& prefix, Preprocessor* PP,
-                                  PreprocessorFactory*) {
-  return new HTMLDiagnostics(prefix, PP);
+                                  PreprocessorFactory*,
+                                  llvm::SmallVectorImpl<std::string>* FilesMade)
+{
+  return new HTMLDiagnostics(prefix, PP, FilesMade);
+}
+
+//===----------------------------------------------------------------------===//
+// Factory for HTMLDiagnosticClients
+//===----------------------------------------------------------------------===//
+
+namespace {
+class VISIBILITY_HIDDEN HTMLDiagnosticsFactory
+  : public PathDiagnosticClientFactory {
+
+  std::string Prefix;
+  Preprocessor *PP;
+public:
+  HTMLDiagnosticsFactory(const std::string& prefix, Preprocessor* pp)
+    : Prefix(prefix), PP(pp) {}
+
+  virtual ~HTMLDiagnosticsFactory() {}
+    
+  const char *getName() const { return "HTMLDiagnostics"; }
+    
+  PathDiagnosticClient*
+  createPathDiagnosticClient(llvm::SmallVectorImpl<std::string> *FilesMade) {
+
+  return new HTMLDiagnostics(Prefix, PP, FilesMade);
+  }
+};
+} // end anonymous namespace
+
+PathDiagnosticClientFactory*
+clang::CreateHTMLDiagnosticClientFactory(const std::string& prefix,
+                                         Preprocessor* PP,
+                                         PreprocessorFactory*) {
+  return new HTMLDiagnosticsFactory(prefix, PP);
 }
 
 //===----------------------------------------------------------------------===//
@@ -317,12 +355,14 @@
       llvm::cerr << "warning: could not create file '" << F.toString() << "'\n";
       return;
     }
+
+    if (FilesMade)
+      FilesMade->push_back(H.getLast());
   }
   
   // Emit the HTML to disk.
-
   for (RewriteBuffer::iterator I = Buf->begin(), E = Buf->end(); I!=E; ++I)
-      os << *I;
+      os << *I;  
 }
 
 void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,

Modified: cfe/trunk/lib/Frontend/PlistDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PlistDiagnostics.cpp?rev=77264&r1=77263&r2=77264&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/Frontend/PlistDiagnostics.cpp Mon Jul 27 17:13:39 2009
@@ -37,12 +37,16 @@
     std::vector<const PathDiagnostic*> BatchedDiags;
     const std::string OutputFile;
     const LangOptions &LangOpts;
+    llvm::OwningPtr<PathDiagnosticClientFactory> PF;
+    llvm::OwningPtr<PathDiagnosticClient> SubPDC;
+    llvm::SmallVector<std::string, 1> FilesMade;
   public:
-    PlistDiagnostics(const std::string& prefix, const LangOptions &LangOpts);
+    PlistDiagnostics(const std::string& prefix, const LangOptions &LangOpts,
+                     PathDiagnosticClientFactory *pf);
     ~PlistDiagnostics();
     void HandlePathDiagnostic(const PathDiagnostic* D);
     
-    PathGenerationScheme getGenerationScheme() const { return Extensive; }
+    PathGenerationScheme getGenerationScheme() const;
     bool supportsLogicalOpControlFlow() const { return true; }
     bool supportsAllBlockEdges() const { return true; }
     virtual bool useVerboseDescription() const { return false; }
@@ -50,13 +54,27 @@
 } // end anonymous namespace
 
 PlistDiagnostics::PlistDiagnostics(const std::string& output,
-                                   const LangOptions &LO)
-  : OutputFile(output), LangOpts(LO) {}
+                                   const LangOptions &LO,
+                                   PathDiagnosticClientFactory *pf)
+  : OutputFile(output), LangOpts(LO), PF(pf) {
+    
+  if (PF)
+    SubPDC.reset(PF->createPathDiagnosticClient(&FilesMade));
+}
 
 PathDiagnosticClient*
 clang::CreatePlistDiagnosticClient(const std::string& s,
-                                   Preprocessor *PP, PreprocessorFactory*) {
-  return new PlistDiagnostics(s, PP->getLangOptions());
+                                   Preprocessor *PP, PreprocessorFactory*,
+                                   PathDiagnosticClientFactory *PF) {
+  return new PlistDiagnostics(s, PP->getLangOptions(), PF);
+}
+
+PathDiagnosticClient::PathGenerationScheme
+PlistDiagnostics::getGenerationScheme() const {
+  if (const PathDiagnosticClient *PD = SubPDC.get())
+    return PD->getGenerationScheme();
+  
+  return Extensive;
 }
 
 static void AddFID(FIDMap &FIDs, llvm::SmallVectorImpl<FileID> &V,
@@ -358,9 +376,9 @@
     // Create an owning smart pointer for 'D' just so that we auto-free it
     // when we exit this method.
     llvm::OwningPtr<PathDiagnostic> OwnedD(const_cast<PathDiagnostic*>(D));
-
+    
     o << "   <array>\n";
-  
+
     for (PathDiagnostic::const_iterator I=D->begin(), E=D->end(); I != E; ++I)
       ReportDiag(o, *I, FM, *SM, LangOpts);
     
@@ -378,6 +396,24 @@
     o << "  <key>location</key>\n";
     EmitLocation(o, *SM, LangOpts, D->getLocation(), FM, 2);
     
+    // Output the diagnostic to the sub-diagnostic client, if any.
+    if (PF) {
+      if (!SubPDC.get())
+        SubPDC.reset(PF->createPathDiagnosticClient(&FilesMade));
+      
+      FilesMade.clear();
+      SubPDC->HandlePathDiagnostic(OwnedD.take());      
+      SubPDC.reset(0);
+      
+      if (!FilesMade.empty()) {
+        o << "  <key>" << PF->getName() << "_files</key>\n";
+        o << "  <array>\n";
+        for (size_t i = 0, n = FilesMade.size(); i < n ; ++i)
+          o << "   <string>" << FilesMade[i] << "</string>\n";
+        o << "  </array>\n";        
+      }
+    }
+    
     // Close up the entry.
     o << "  </dict>\n";
   }





More information about the cfe-commits mailing list