diff --git a/clang/Driver/Analyses.def b/clang/Driver/Analyses.def index 0661a4e9463d..1f702cc0e9c2 100644 --- a/clang/Driver/Analyses.def +++ b/clang/Driver/Analyses.def @@ -15,10 +15,6 @@ #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) #endif -#ifndef ANALYSIS_STORE -#define ANALYSIS_STORE(NAME, CMDFLAG, DESC) -#endif - ANALYSIS(CFGDump, "cfg-dump", "Display Control-Flow Graphs", Code) @@ -52,8 +48,22 @@ ANALYSIS(CheckerCFRef, "checker-cfref", "Run the [Core] Foundation reference count checker", Code) +#ifndef ANALYSIS_STORE +#define ANALYSIS_STORE(NAME, CMDFLAG, DESC) +#endif + ANALYSIS_STORE(BasicStore, "basic", "Use basic analyzer store") ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store") +#ifndef ANALYSIS_DIAGNOSTICS +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) +#endif + +ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", CreateHTMLDiagnosticClient) +ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", CreatePlistDiagnosticClient) + #undef ANALYSIS #undef ANALYSIS_STORE +#undef ANALYSIS_DIAGNOSTICS + + diff --git a/clang/Driver/AnalysisConsumer.cpp b/clang/Driver/AnalysisConsumer.cpp index aa78337ae001..5f338c8af53d 100644 --- a/clang/Driver/AnalysisConsumer.cpp +++ b/clang/Driver/AnalysisConsumer.cpp @@ -75,20 +75,21 @@ namespace { llvm::OwningPtr PD; bool AnalyzeAll; AnalysisStores SM; + AnalysisDiagClients DC; AnalysisConsumer(Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, const LangOptions& lopts, const std::string& fname, const std::string& htmldir, - AnalysisStores sm, + AnalysisStores sm, AnalysisDiagClients dc, bool visgraphviz, bool visubi, bool trim, bool analyzeAll) : VisGraphviz(visgraphviz), VisUbigraph(visubi), TrimGraph(trim), LOpts(lopts), Diags(diags), Ctx(0), PP(pp), PPF(ppf), HTMLDir(htmldir), FName(fname), - AnalyzeAll(analyzeAll), SM(sm) {} + AnalyzeAll(analyzeAll), SM(sm), DC(dc) {} void addCodeAction(CodeAction action) { FunctionActions.push_back(action); @@ -165,9 +166,14 @@ case NAME##Model: return Create##NAME##Manager; } virtual PathDiagnosticClient* getPathDiagnosticClient() { - if (C.PD.get() == 0 && !C.HTMLDir.empty()) - C.PD.reset(CreateHTMLDiagnosticClient(C.HTMLDir, C.PP, C.PPF)); - + if (C.PD.get() == 0 && !C.HTMLDir.empty()) { + switch (C.DC) { + default: +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)\ +case PD_##NAME: C.PD.reset(CREATEFN(C.HTMLDir, C.PP, C.PPF)); break; +#include "Analyses.def" + } + } return C.PD.get(); } @@ -449,6 +455,7 @@ static void ActionWarnObjCMethSigs(AnalysisManager& mgr) { ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End, AnalysisStores SM, + AnalysisDiagClients DC, Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, const LangOptions& lopts, @@ -459,7 +466,7 @@ ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End, bool analyzeAll) { llvm::OwningPtr - C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir, SM, + C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir, SM, DC, VisGraphviz, VisUbi, trim, analyzeAll)); for ( ; Beg != End ; ++Beg) diff --git a/clang/Driver/AnalysisConsumer.h b/clang/Driver/AnalysisConsumer.h index 420714fd60bf..27c8e6e07ab0 100644 --- a/clang/Driver/AnalysisConsumer.h +++ b/clang/Driver/AnalysisConsumer.h @@ -27,9 +27,15 @@ enum AnalysisStores { #include "Analyses.def" NumStores }; + +enum AnalysisDiagClients { +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME, +#include "Analyses.def" +NUM_ANALYSIS_DIAG_CLIENTS +}; ASTConsumer* CreateAnalysisConsumer(Analyses* Beg, Analyses* End, - AnalysisStores SM, + AnalysisStores SM, AnalysisDiagClients DC, Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, const LangOptions& lopts, diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index 4d5e6bef313a..5fc86a775996 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -220,6 +220,15 @@ clEnumValN(NAME##Model, "analyzer-store-" CMDFLAG, DESC), #include "Analyses.def" clEnumValEnd)); +static llvm::cl::opt +AnalysisDiagOpt(llvm::cl::desc("SCA Output Options:"), + llvm::cl::init(PD_HTML), + llvm::cl::values( +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN)\ +clEnumValN(PD_##NAME, "analyzer-output-" CMDFLAG, DESC), +#include "Analyses.def" +clEnumValEnd)); + //===----------------------------------------------------------------------===// // Language Options //===----------------------------------------------------------------------===// @@ -1224,7 +1233,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile, assert (!AnalysisList.empty()); return CreateAnalysisConsumer(&AnalysisList[0], &AnalysisList[0]+AnalysisList.size(), - AnalysisStoreOpt, + AnalysisStoreOpt, AnalysisDiagOpt, Diag, PP, PPF, LangOpts, AnalyzeSpecificFunction, OutputFile, VisualizeEGDot, VisualizeEGUbi, diff --git a/clang/include/clang/Driver/PathDiagnosticClients.h b/clang/include/clang/Driver/PathDiagnosticClients.h index 78457bd76d21..b227bbb03a2a 100644 --- a/clang/include/clang/Driver/PathDiagnosticClients.h +++ b/clang/include/clang/Driver/PathDiagnosticClients.h @@ -26,7 +26,9 @@ PathDiagnosticClient* CreateHTMLDiagnosticClient(const std::string& prefix, Preprocessor* PP, PreprocessorFactory* PPF); -PathDiagnosticClient* CreatePlistDiagnosticClient(const std::string& prefix); +PathDiagnosticClient* CreatePlistDiagnosticClient(const std::string& prefix, + Preprocessor* PP, + PreprocessorFactory* PPF); } #endif diff --git a/clang/lib/Driver/PlistDiagnostics.cpp b/clang/lib/Driver/PlistDiagnostics.cpp index fe8022c7c172..500524157e57 100644 --- a/clang/lib/Driver/PlistDiagnostics.cpp +++ b/clang/lib/Driver/PlistDiagnostics.cpp @@ -24,6 +24,11 @@ using namespace clang; typedef llvm::DenseMap FIDMap; +namespace clang { + class Preprocessor; + class PreprocessorFactory; +} + namespace { class VISIBILITY_HIDDEN PlistDiagnostics : public PathDiagnosticClient { llvm::sys::Path Directory, FilePrefix; @@ -40,7 +45,9 @@ PlistDiagnostics::PlistDiagnostics(const std::string& prefix) FilePrefix.appendComponent("report"); // All Plist files begin with "report" } -PathDiagnosticClient* clang::CreatePlistDiagnosticClient(const std::string& s) { +PathDiagnosticClient* +clang::CreatePlistDiagnosticClient(const std::string& s, + Preprocessor*, PreprocessorFactory*) { return new PlistDiagnostics(s); } @@ -118,7 +125,7 @@ static void ReportDiag(llvm::raw_ostream& o, const PathDiagnosticPiece& P, // Output the text. Indent(o, indent) << "message\n"; - Indent(o, indent) << "" << P.getString() << ""; + Indent(o, indent) << "" << P.getString() << "\n"; // Output the hint. Indent(o, indent) << "displayhint\n"; @@ -222,9 +229,9 @@ void PlistDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) { o << " \n"; // Output the bug type and bug category. - o << " description" << D->getDescription() << "\n" - " category" << D->getCategory() << "\n"; + o << " description\n " << D->getDescription() << "\n" + " category\n " << D->getCategory() << "\n"; // Finish. - o << "\n"; + o << "\n"; }