From 0d28bf097c3a8f40eceee823c943340b6e355283 Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Sat, 25 Jan 2014 11:14:41 +0000 Subject: [PATCH] PlistSupport: Unify ARCMigrate / StaticAnalyzer plist writers 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 | 109 +++++++++++++++++++ lib/ARCMigrate/PlistReporter.cpp | 83 +------------- lib/StaticAnalyzer/Core/PlistDiagnostics.cpp | 79 +------------- 3 files changed, 117 insertions(+), 154 deletions(-) create mode 100644 include/clang/Basic/PlistSupport.h diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h new file mode 100644 index 0000000000..e410aa3b37 --- /dev/null +++ b/include/clang/Basic/PlistSupport.h @@ -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 FIDMap; + +static const char *PlistHeader = + "\n" + "\n" + "\n"; + +static void AddFID(FIDMap &FIDs, SmallVectorImpl &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(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) << "\n"; + Indent(o, indent) << " line" + << Loc.getExpansionLineNumber() << "\n"; + Indent(o, indent) << " col" + << Loc.getExpansionColumnNumber() + offset + << "\n"; + Indent(o, indent) << " file" << GetFID(FM, SM, Loc) + << "\n"; + Indent(o, indent) << "\n"; +} + +static inline void EmitRange(raw_ostream &o, const SourceManager &SM, + const LangOptions &LangOpts, CharSourceRange R, + const FIDMap &FM, unsigned indent) { + Indent(o, indent) << "\n"; + EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1); + EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange()); + Indent(o, indent) << "\n"; +} + +static raw_ostream &EmitString(raw_ostream &o, StringRef s) { + o << ""; + for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) { + char c = *I; + switch (c) { + default: + o << c; + break; + case '&': + o << "&"; + break; + case '<': + o << "<"; + break; + case '>': + o << ">"; + break; + case '\'': + o << "'"; + break; + case '\"': + o << """; + break; + } + } + o << ""; + return o; +} +} diff --git a/lib/ARCMigrate/PlistReporter.cpp b/lib/ARCMigrate/PlistReporter.cpp index 144ba2e398..433f41c517 100644 --- a/lib/ARCMigrate/PlistReporter.cpp +++ b/lib/ARCMigrate/PlistReporter.cpp @@ -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 FIDMap; - -static void AddFID(FIDMap &FIDs, SmallVectorImpl &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(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) << "\n"; - Indent(o, indent) << " line" - << Loc.getExpansionLineNumber() << "\n"; - Indent(o, indent) << " col" - << Loc.getExpansionColumnNumber() + offset << "\n"; - Indent(o, indent) << " file" - << GetFID(FM, SM, Loc) << "\n"; - Indent(o, indent) << "\n"; -} - -static void EmitRange(raw_ostream& o, const SourceManager &SM, - const LangOptions &LangOpts, - CharSourceRange R, const FIDMap &FM, - unsigned indent) { - Indent(o, indent) << "\n"; - EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent+1); - EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent+1, R.isTokenRange()); - Indent(o, indent) << "\n"; -} - -static raw_ostream& EmitString(raw_ostream& o, - StringRef s) { - o << ""; - for (StringRef::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) { - char c = *I; - switch (c) { - default: o << c; break; - case '&': o << "&"; break; - case '<': o << "<"; break; - case '>': o << ">"; break; - case '\'': o << "'"; break; - case '\"': o << """; break; - } - } - o << ""; - return o; -} - void arcmt::writeARCDiagsToPlist(const std::string &outPath, ArrayRef diags, SourceManager &SM, @@ -123,10 +47,7 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath, } // Write the plist header. - o << "\n" - "\n" - "\n"; + o << PlistHeader; // Write the root object: a containing... // - "files", an mapping from FIDs to file names diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index 5dca811722..1a40f5e582 100644 --- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -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" @@ -21,13 +22,9 @@ #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 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 &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(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) << "\n"; - Indent(o, indent) << " line" - << Loc.getExpansionLineNumber() << "\n"; - Indent(o, indent) << " col" - << Loc.getExpansionColumnNumber() + offset << "\n"; - Indent(o, indent) << " file" - << GetFID(FM, SM, Loc) << "\n"; - Indent(o, indent) << "\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) << "\n"; } -static raw_ostream &EmitString(raw_ostream &o, StringRef s) { - o << ""; - for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) { - char c = *I; - switch (c) { - default: o << c; break; - case '&': o << "&"; break; - case '<': o << "<"; break; - case '>': o << ">"; break; - case '\'': o << "'"; break; - case '\"': o << """; break; - } - } - o << ""; - 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 Ranges = piece->getRanges(); for (ArrayRef::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 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 << "\n" - "\n" - "\n"; + o << PlistHeader; // Write the root object: a containing... // - "clang_version", the string representation of clang version -- 2.40.0