]> granicus.if.org Git - clang/commitdiff
PlistSupport: Unify ARCMigrate / StaticAnalyzer plist writers
authorAlp Toker <alp@nuanti.com>
Sat, 25 Jan 2014 11:14:41 +0000 (11:14 +0000)
committerAlp Toker <alp@nuanti.com>
Sat, 25 Jan 2014 11:14:41 +0000 (11:14 +0000)
Reduces the ARCMT migrator plist writer down to a single function,
arcmt::writeARCDiagsToPlist() which shares supporting functions with the
analyzer plist writer.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200075 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/PlistSupport.h [new file with mode: 0644]
lib/ARCMigrate/PlistReporter.cpp
lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
new file mode 100644 (file)
index 0000000..e410aa3
--- /dev/null
@@ -0,0 +1,109 @@
+//===---------- PlistSupport.h - Plist Output Utilities ---------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/raw_ostream.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+
+namespace clang {
+
+typedef llvm::DenseMap<FileID, unsigned> FIDMap;
+
+static const char *PlistHeader =
+    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+    "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
+    "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+    "<plist version=\"1.0\">\n";
+
+static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
+                   const SourceManager &SM, SourceLocation L) {
+
+  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+  FIDMap::iterator I = FIDs.find(FID);
+  if (I != FIDs.end())
+    return;
+  FIDs[FID] = V.size();
+  V.push_back(FID);
+}
+
+static unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
+                       SourceLocation L) {
+  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+  FIDMap::const_iterator I = FIDs.find(FID);
+  assert(I != FIDs.end());
+  return I->second;
+}
+
+static raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
+  for (unsigned i = 0; i < indent; ++i)
+    o << ' ';
+  return o;
+}
+
+static void EmitLocation(raw_ostream &o, const SourceManager &SM,
+                         const LangOptions &LangOpts, SourceLocation L,
+                         const FIDMap &FM, unsigned indent,
+                         bool extend = false) {
+
+  FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM));
+
+  // Add in the length of the token, so that we cover multi-char tokens.
+  unsigned offset =
+      extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
+
+  Indent(o, indent) << "<dict>\n";
+  Indent(o, indent) << " <key>line</key><integer>"
+                    << Loc.getExpansionLineNumber() << "</integer>\n";
+  Indent(o, indent) << " <key>col</key><integer>"
+                    << Loc.getExpansionColumnNumber() + offset
+                    << "</integer>\n";
+  Indent(o, indent) << " <key>file</key><integer>" << GetFID(FM, SM, Loc)
+                    << "</integer>\n";
+  Indent(o, indent) << "</dict>\n";
+}
+
+static inline void EmitRange(raw_ostream &o, const SourceManager &SM,
+                             const LangOptions &LangOpts, CharSourceRange R,
+                             const FIDMap &FM, unsigned indent) {
+  Indent(o, indent) << "<array>\n";
+  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1);
+  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange());
+  Indent(o, indent) << "</array>\n";
+}
+
+static raw_ostream &EmitString(raw_ostream &o, StringRef s) {
+  o << "<string>";
+  for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) {
+    char c = *I;
+    switch (c) {
+    default:
+      o << c;
+      break;
+    case '&':
+      o << "&amp;";
+      break;
+    case '<':
+      o << "&lt;";
+      break;
+    case '>':
+      o << "&gt;";
+      break;
+    case '\'':
+      o << "&apos;";
+      break;
+    case '\"':
+      o << "&quot;";
+      break;
+    }
+  }
+  o << "</string>";
+  return o;
+}
+}
index 144ba2e398ad68661ce719aeb8dc65e1c2c0f6ca..433f41c517a12549c8dde70aa8a44d2e49c8b233 100644 (file)
@@ -9,88 +9,12 @@
 
 #include "Internals.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/PlistSupport.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
 using namespace clang;
 using namespace arcmt;
 
-// FIXME: This duplicates significant functionality from PlistDiagnostics.cpp,
-// it would be jolly good if there was a reusable PlistWriter or something.
-
-typedef llvm::DenseMap<FileID, unsigned> FIDMap;
-
-static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
-                   const SourceManager &SM, SourceLocation L) {
-
-  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
-  FIDMap::iterator I = FIDs.find(FID);
-  if (I != FIDs.end()) return;
-  FIDs[FID] = V.size();
-  V.push_back(FID);
-}
-
-static unsigned GetFID(const FIDMap& FIDs, const SourceManager &SM,
-                       SourceLocation L) {
-  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
-  FIDMap::const_iterator I = FIDs.find(FID);
-  assert(I != FIDs.end());
-  return I->second;
-}
-
-static raw_ostream& Indent(raw_ostream& o, const unsigned indent) {
-  for (unsigned i = 0; i < indent; ++i) o << ' ';
-  return o;
-}
-
-static void EmitLocation(raw_ostream& o, const SourceManager &SM,
-                         const LangOptions &LangOpts,
-                         SourceLocation L, const FIDMap &FM,
-                         unsigned indent, bool extend = false) {
-
-  FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager&>(SM));
-
-  // Add in the length of the token, so that we cover multi-char tokens.
-  unsigned offset =
-    extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
-
-  Indent(o, indent) << "<dict>\n";
-  Indent(o, indent) << " <key>line</key><integer>"
-                    << Loc.getExpansionLineNumber() << "</integer>\n";
-  Indent(o, indent) << " <key>col</key><integer>"
-                    << Loc.getExpansionColumnNumber() + offset << "</integer>\n";
-  Indent(o, indent) << " <key>file</key><integer>"
-                    << GetFID(FM, SM, Loc) << "</integer>\n";
-  Indent(o, indent) << "</dict>\n";
-}
-
-static void EmitRange(raw_ostream& o, const SourceManager &SM,
-                      const LangOptions &LangOpts,
-                      CharSourceRange R, const FIDMap &FM,
-                      unsigned indent) {
-  Indent(o, indent) << "<array>\n";
-  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent+1);
-  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent+1, R.isTokenRange());
-  Indent(o, indent) << "</array>\n";
-}
-
-static raw_ostream& EmitString(raw_ostream& o,
-                                     StringRef s) {
-  o << "<string>";
-  for (StringRef::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) {
-    char c = *I;
-    switch (c) {
-    default:   o << c; break;
-    case '&':  o << "&amp;"; break;
-    case '<':  o << "&lt;"; break;
-    case '>':  o << "&gt;"; break;
-    case '\'': o << "&apos;"; break;
-    case '\"': o << "&quot;"; break;
-    }
-  }
-  o << "</string>";
-  return o;
-}
-
 void arcmt::writeARCDiagsToPlist(const std::string &outPath,
                                  ArrayRef<StoredDiagnostic> diags,
                                  SourceManager &SM,
@@ -123,10 +47,7 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath,
   }
 
   // Write the plist header.
-  o << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-  "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
-  "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
-  "<plist version=\"1.0\">\n";
+  o << PlistHeader;
 
   // Write the root object: a <dict> containing...
   //  - "files", an <array> mapping from FIDs to file names
index 5dca811722ac900c5d979ea99249bfddb880e9fd..1a40f5e58272ecf4a5af3acbfb42a95352db97ed 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/PlistSupport.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
 using namespace clang;
 using namespace ento;
 
-typedef llvm::DenseMap<FileID, unsigned> FIDMap;
-
-
 namespace {
   class PlistDiagnostics : public PathDiagnosticConsumer {
     const std::string OutputFile;
@@ -80,50 +77,6 @@ void ento::createPlistMultiFileDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
                                    PP.getLangOpts(), true));
 }
 
-static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
-                   const SourceManager* SM, SourceLocation L) {
-
-  FileID FID = SM->getFileID(SM->getExpansionLoc(L));
-  FIDMap::iterator I = FIDs.find(FID);
-  if (I != FIDs.end()) return;
-  FIDs[FID] = V.size();
-  V.push_back(FID);
-}
-
-static unsigned GetFID(const FIDMap& FIDs, const SourceManager &SM,
-                       SourceLocation L) {
-  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
-  FIDMap::const_iterator I = FIDs.find(FID);
-  assert(I != FIDs.end());
-  return I->second;
-}
-
-static raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
-  for (unsigned i = 0; i < indent; ++i) o << ' ';
-  return o;
-}
-
-static void EmitLocation(raw_ostream &o, const SourceManager &SM,
-                         const LangOptions &LangOpts,
-                         SourceLocation L, const FIDMap &FM,
-                         unsigned indent, bool extend = false) {
-
-  FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager&>(SM));
-
-  // Add in the length of the token, so that we cover multi-char tokens.
-  unsigned offset =
-    extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
-
-  Indent(o, indent) << "<dict>\n";
-  Indent(o, indent) << " <key>line</key><integer>"
-                    << Loc.getExpansionLineNumber() << "</integer>\n";
-  Indent(o, indent) << " <key>col</key><integer>"
-                    << Loc.getExpansionColumnNumber() + offset << "</integer>\n";
-  Indent(o, indent) << " <key>file</key><integer>"
-                    << GetFID(FM, SM, Loc) << "</integer>\n";
-  Indent(o, indent) << "</dict>\n";
-}
-
 static void EmitLocation(raw_ostream &o, const SourceManager &SM,
                          const LangOptions &LangOpts,
                          const PathDiagnosticLocation &L, const FIDMap& FM,
@@ -141,23 +94,6 @@ static void EmitRange(raw_ostream &o, const SourceManager &SM,
   Indent(o, indent) << "</array>\n";
 }
 
-static raw_ostream &EmitString(raw_ostream &o, StringRef s) {
-  o << "<string>";
-  for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) {
-    char c = *I;
-    switch (c) {
-    default:   o << c; break;
-    case '&':  o << "&amp;"; break;
-    case '<':  o << "&lt;"; break;
-    case '>':  o << "&gt;"; break;
-    case '\'': o << "&apos;"; break;
-    case '\"': o << "&quot;"; break;
-    }
-  }
-  o << "</string>";
-  return o;
-}
-
 static void ReportControlFlow(raw_ostream &o,
                               const PathDiagnosticControlFlowPiece& P,
                               const FIDMap& FM,
@@ -387,12 +323,12 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
       for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E;
            ++I) {
         const PathDiagnosticPiece *piece = I->getPtr();
-        AddFID(FM, Fids, SM, piece->getLocation().asLocation());
+        AddFID(FM, Fids, *SM, piece->getLocation().asLocation());
         ArrayRef<SourceRange> Ranges = piece->getRanges();
         for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
                                              E = Ranges.end(); I != E; ++I) {
-          AddFID(FM, Fids, SM, I->getBegin());
-          AddFID(FM, Fids, SM, I->getEnd());
+          AddFID(FM, Fids, *SM, I->getBegin());
+          AddFID(FM, Fids, *SM, I->getEnd());
         }
 
         if (const PathDiagnosticCallPiece *call =
@@ -400,7 +336,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
           IntrusiveRefCntPtr<PathDiagnosticEventPiece>
             callEnterWithin = call->getCallEnterWithinCallerEvent();
           if (callEnterWithin)
-            AddFID(FM, Fids, SM, callEnterWithin->getLocation().asLocation());
+            AddFID(FM, Fids, *SM, callEnterWithin->getLocation().asLocation());
 
           WorkList.push_back(&call->path);
         }
@@ -421,10 +357,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl(
   }
 
   // Write the plist header.
-  o << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-  "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
-  "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
-  "<plist version=\"1.0\">\n";
+  o << PlistHeader;
 
   // Write the root object: a <dict> containing...
   //  - "clang_version", the string representation of clang version