From e71b85feb0a2df9273b1b488f5b40279369a6255 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 19 May 2009 10:18:02 +0000 Subject: [PATCH] Move analysis command-line options out of AnalysisConsumer.cpp into clang-cc.cpp. With this commit, all of the clang-cc command-line options are defined in clang-cc.cpp. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72107 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/clang-cc/AnalysisConsumer.cpp | 148 ++++++---------------------- tools/clang-cc/AnalysisConsumer.h | 3 +- tools/clang-cc/clang-cc.cpp | 102 ++++++++++++++++++- 3 files changed, 133 insertions(+), 120 deletions(-) diff --git a/tools/clang-cc/AnalysisConsumer.cpp b/tools/clang-cc/AnalysisConsumer.cpp index bc6d4b6fa4..ce65776c5a 100644 --- a/tools/clang-cc/AnalysisConsumer.cpp +++ b/tools/clang-cc/AnalysisConsumer.cpp @@ -40,101 +40,6 @@ using namespace clang; static ExplodedNodeImpl::Auditor* CreateUbiViz(); -//===----------------------------------------------------------------------===// -// Analyzer Options: available analyses. -//===----------------------------------------------------------------------===// - -static llvm::cl::list -AnalysisList(llvm::cl::desc("Source Code Analysis - Checks and Analyses"), -llvm::cl::values( -#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\ -clEnumValN(NAME, CMDFLAG, DESC), -#include "Analyses.def" -clEnumValEnd)); - -//===----------------------------------------------------------------------===// -// Analyzer Options: store model. -//===----------------------------------------------------------------------===// - -static llvm::cl::opt -AnalysisStoreOpt("analyzer-store", - llvm::cl::desc("Source Code Analysis - Abstract Memory Store Models"), - llvm::cl::init(BasicStoreModel), - llvm::cl::values( -#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)\ -clEnumValN(NAME##Model, CMDFLAG, DESC), -#include "Analyses.def" -clEnumValEnd)); - -//===----------------------------------------------------------------------===// -// Analyzer Options: constraint engines. -//===----------------------------------------------------------------------===// - -static llvm::cl::opt -AnalysisConstraintsOpt("analyzer-constraints", - llvm::cl::desc("Source Code Analysis - Symbolic Constraint Engines"), - llvm::cl::init(RangeConstraintsModel), - llvm::cl::values( -#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)\ -clEnumValN(NAME##Model, CMDFLAG, DESC), -#include "Analyses.def" -clEnumValEnd)); - -//===----------------------------------------------------------------------===// -// Analyzer Options: diagnostic clients. -//===----------------------------------------------------------------------===// - -static llvm::cl::opt -AnalysisDiagOpt("analyzer-output", - llvm::cl::desc("Source Code Analysis - Output Options"), - llvm::cl::init(PD_HTML), - llvm::cl::values( -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE)\ -clEnumValN(PD_##NAME, CMDFLAG, DESC), -#include "Analyses.def" -clEnumValEnd)); - -//===----------------------------------------------------------------------===// -// Misc. fun options. -//===----------------------------------------------------------------------===// - -static llvm::cl::opt -VisualizeEGDot("analyzer-viz-egraph-graphviz", - llvm::cl::desc("Display exploded graph using GraphViz")); - -static llvm::cl::opt -VisualizeEGUbi("analyzer-viz-egraph-ubigraph", - llvm::cl::desc("Display exploded graph using Ubigraph")); - -static llvm::cl::opt -AnalyzeAll("analyzer-opt-analyze-headers", - llvm::cl::desc("Force the static analyzer to analyze " - "functions defined in header files")); - -static llvm::cl::opt -AnalyzerDisplayProgress("analyzer-display-progress", - llvm::cl::desc("Emit verbose output about the analyzer's progress.")); - -static llvm::cl::opt -PurgeDead("analyzer-purge-dead", - llvm::cl::init(true), - llvm::cl::desc("Remove dead symbols, bindings, and constraints before" - " processing a statement.")); - -static llvm::cl::opt -EagerlyAssume("analyzer-eagerly-assume", - llvm::cl::init(false), - llvm::cl::desc("Eagerly assume the truth/falseness of some " - "symbolic constraints.")); - -static llvm::cl::opt -AnalyzeSpecificFunction("analyze-function", - llvm::cl::desc("Run analysis on specific function")); - -static llvm::cl::opt -TrimGraph("trim-egraph", - llvm::cl::desc("Only show error-related paths in the analysis graph")); - //===----------------------------------------------------------------------===// // Basic type definitions. //===----------------------------------------------------------------------===// @@ -164,15 +69,17 @@ namespace { Preprocessor* PP; PreprocessorFactory* PPF; const std::string OutDir; + AnalyzerOptions Opts; llvm::OwningPtr PD; AnalysisConsumer(Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, const LangOptions& lopts, - const std::string& outdir) + const std::string& outdir, + const AnalyzerOptions& opts) : LOpts(lopts), Diags(diags), Ctx(0), PP(pp), PPF(ppf), - OutDir(outdir) {} + OutDir(outdir), Opts(opts) {} void addCodeAction(CodeAction action) { FunctionActions.push_back(action); @@ -279,7 +186,7 @@ namespace { virtual PathDiagnosticClient* getPathDiagnosticClient() { if (C.PD.get() == 0 && !C.OutDir.empty()) { - switch (AnalysisDiagOpt) { + switch (C.Opts.AnalysisDiagOpt) { default: #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\ case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break; @@ -302,15 +209,19 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break; return liveness.get(); } - bool shouldVisualizeGraphviz() const { return VisualizeEGDot; } + bool shouldVisualizeGraphviz() const { return C.Opts.VisualizeEGDot; } - bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; } + bool shouldVisualizeUbigraph() const { return C.Opts.VisualizeEGUbi; } bool shouldVisualize() const { - return VisualizeEGDot || VisualizeEGUbi; + return C.Opts.VisualizeEGDot || C.Opts.VisualizeEGUbi; } - bool shouldTrimGraph() const { return TrimGraph; } + bool shouldTrimGraph() const { return C.Opts.TrimGraph; } + + bool shouldPurgeDead() const { return C.Opts.PurgeDead; } + + bool shouldEagerlyAssume() const { return C.Opts.EagerlyAssume; } void DisplayFunction() { @@ -339,7 +250,7 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break; CreateStoreMgr = ManagerRegistry::StoreMgrCreator; } else { - switch (AnalysisStoreOpt) { + switch (C.Opts.AnalysisStoreOpt) { default: assert(0 && "Unknown store manager."); #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN) \ @@ -351,7 +262,7 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break; if (ManagerRegistry::ConstraintMgrCreator != 0) CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator; else { - switch (AnalysisConstraintsOpt) { + switch (C.Opts.AnalysisConstraintsOpt) { default: assert(0 && "Unknown store manager."); #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN) \ @@ -363,7 +274,7 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.OutDir, C.PP, C.PPF)); break; // Some DiagnosticClients should be created all the time instead of // lazily. Create those now. - switch (AnalysisDiagOpt) { + switch (C.Opts.AnalysisDiagOpt) { default: break; #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\ case PD_##NAME: if (AUTOCREATE) getPathDiagnosticClient(); break; @@ -392,8 +303,8 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) { case Decl::Function: { FunctionDecl* FD = cast(D); - if (AnalyzeSpecificFunction.size() > 0 && - AnalyzeSpecificFunction != FD->getIdentifier()->getName()) + if (Opts.AnalyzeSpecificFunction.size() > 0 && + Opts.AnalyzeSpecificFunction != FD->getIdentifier()->getName()) break; Stmt* Body = FD->getBody(*Ctx); @@ -404,8 +315,8 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) { case Decl::ObjCMethod: { ObjCMethodDecl* MD = cast(D); - if (AnalyzeSpecificFunction.size() > 0 && - AnalyzeSpecificFunction != MD->getSelector().getAsString()) + if (Opts.AnalyzeSpecificFunction.size() > 0 && + Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString()) return; Stmt* Body = MD->getBody(); @@ -421,7 +332,7 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) { void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) { if(!TranslationUnitActions.empty()) { - AnalysisManager mgr(*this, AnalyzerDisplayProgress); + AnalysisManager mgr(*this, Opts.AnalyzerDisplayProgress); for (Actions::iterator I = TranslationUnitActions.begin(), E = TranslationUnitActions.end(); I != E; ++I) (*I)(mgr); @@ -451,12 +362,13 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions& actions) { // Don't run the actions on declarations in header files unless // otherwise specified. - if (!AnalyzeAll && !Ctx->getSourceManager().isFromMainFile(D->getLocation())) + if (!Opts.AnalyzeAll && + !Ctx->getSourceManager().isFromMainFile(D->getLocation())) return; // Create an AnalysisManager that will manage the state for analyzing // this method/function. - AnalysisManager mgr(*this, D, Body, AnalyzerDisplayProgress); + AnalysisManager mgr(*this, D, Body, Opts.AnalyzerDisplayProgress); // Dispatch on the actions. for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I) @@ -494,7 +406,7 @@ static void ActionGRExprEngine(AnalysisManager& mgr, GRTransferFuncs* tf, if (!L) return; GRExprEngine Eng(*mgr.getCFG(), *mgr.getCodeDecl(), mgr.getContext(), *L, mgr, - PurgeDead, EagerlyAssume, + mgr.shouldPurgeDead(), mgr.shouldEagerlyAssume(), mgr.getStoreManagerCreator(), mgr.getConstraintManagerCreator()); @@ -611,13 +523,15 @@ static void ActionWarnObjCMethSigs(AnalysisManager& mgr) { ASTConsumer* clang::CreateAnalysisConsumer(Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, const LangOptions& lopts, - const std::string& OutDir) { + const std::string& OutDir, + const AnalyzerOptions& Opts) { llvm::OwningPtr C(new AnalysisConsumer(diags, pp, ppf, - lopts, OutDir)); + lopts, OutDir, + Opts)); - for (unsigned i = 0; i < AnalysisList.size(); ++i) - switch (AnalysisList[i]) { + for (unsigned i = 0; i < Opts.AnalysisList.size(); ++i) + switch (Opts.AnalysisList[i]) { #define ANALYSIS(NAME, CMD, DESC, SCOPE)\ case NAME:\ C->add ## SCOPE ## Action(&Action ## NAME);\ diff --git a/tools/clang-cc/AnalysisConsumer.h b/tools/clang-cc/AnalysisConsumer.h index acf0ac3591..ce87883384 100644 --- a/tools/clang-cc/AnalysisConsumer.h +++ b/tools/clang-cc/AnalysisConsumer.h @@ -73,6 +73,7 @@ struct AnalyzerOptions { ASTConsumer* CreateAnalysisConsumer(Diagnostic &diags, Preprocessor *pp, PreprocessorFactory *ppf, const LangOptions &lopts, - const std::string &output); + const std::string &output, + const AnalyzerOptions& Opts); } diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index 51b3ffda27..8b665a34c4 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -1543,6 +1543,102 @@ PhonyDependencyTarget("MP", llvm::cl::desc("Create phony target for each dependency " "(other than main file)")); +//===----------------------------------------------------------------------===// +// Analysis options +//===----------------------------------------------------------------------===// + +static llvm::cl::list +AnalysisList(llvm::cl::desc("Source Code Analysis - Checks and Analyses"), +llvm::cl::values( +#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\ +clEnumValN(NAME, CMDFLAG, DESC), +#include "Analyses.def" +clEnumValEnd)); + +static llvm::cl::opt +AnalysisStoreOpt("analyzer-store", + llvm::cl::desc("Source Code Analysis - Abstract Memory Store Models"), + llvm::cl::init(BasicStoreModel), + llvm::cl::values( +#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)\ +clEnumValN(NAME##Model, CMDFLAG, DESC), +#include "Analyses.def" +clEnumValEnd)); + +static llvm::cl::opt +AnalysisConstraintsOpt("analyzer-constraints", + llvm::cl::desc("Source Code Analysis - Symbolic Constraint Engines"), + llvm::cl::init(RangeConstraintsModel), + llvm::cl::values( +#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN)\ +clEnumValN(NAME##Model, CMDFLAG, DESC), +#include "Analyses.def" +clEnumValEnd)); + +static llvm::cl::opt +AnalysisDiagOpt("analyzer-output", + llvm::cl::desc("Source Code Analysis - Output Options"), + llvm::cl::init(PD_HTML), + llvm::cl::values( +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE)\ +clEnumValN(PD_##NAME, CMDFLAG, DESC), +#include "Analyses.def" +clEnumValEnd)); + +static llvm::cl::opt +VisualizeEGDot("analyzer-viz-egraph-graphviz", + llvm::cl::desc("Display exploded graph using GraphViz")); + +static llvm::cl::opt +VisualizeEGUbi("analyzer-viz-egraph-ubigraph", + llvm::cl::desc("Display exploded graph using Ubigraph")); + +static llvm::cl::opt +AnalyzeAll("analyzer-opt-analyze-headers", + llvm::cl::desc("Force the static analyzer to analyze " + "functions defined in header files")); + +static llvm::cl::opt +AnalyzerDisplayProgress("analyzer-display-progress", + llvm::cl::desc("Emit verbose output about the analyzer's progress.")); + +static llvm::cl::opt +PurgeDead("analyzer-purge-dead", + llvm::cl::init(true), + llvm::cl::desc("Remove dead symbols, bindings, and constraints before" + " processing a statement.")); + +static llvm::cl::opt +EagerlyAssume("analyzer-eagerly-assume", + llvm::cl::init(false), + llvm::cl::desc("Eagerly assume the truth/falseness of some " + "symbolic constraints.")); + +static llvm::cl::opt +AnalyzeSpecificFunction("analyze-function", + llvm::cl::desc("Run analysis on specific function")); + +static llvm::cl::opt +TrimGraph("trim-egraph", + llvm::cl::desc("Only show error-related paths in the analysis graph")); + +static AnalyzerOptions ReadAnalyzerOptions() { + AnalyzerOptions Opts; + Opts.AnalysisList = AnalysisList; + Opts.AnalysisStoreOpt = AnalysisStoreOpt; + Opts.AnalysisConstraintsOpt = AnalysisConstraintsOpt; + Opts.AnalysisDiagOpt = AnalysisDiagOpt; + Opts.VisualizeEGDot = VisualizeEGDot; + Opts.VisualizeEGUbi = VisualizeEGUbi; + Opts.AnalyzeAll = AnalyzeAll; + Opts.AnalyzerDisplayProgress = AnalyzerDisplayProgress; + Opts.PurgeDead = PurgeDead; + Opts.EagerlyAssume = EagerlyAssume; + Opts.AnalyzeSpecificFunction = AnalyzeSpecificFunction; + Opts.TrimGraph = TrimGraph; + return Opts; +} + //===----------------------------------------------------------------------===// // -dump-build-information Stuff //===----------------------------------------------------------------------===// @@ -1755,10 +1851,12 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, PP.getLangOptions())); break; - case RunAnalysis: + case RunAnalysis: { Consumer.reset(CreateAnalysisConsumer(PP.getDiagnostics(), &PP, &PPF, - PP.getLangOptions(), OutputFile)); + PP.getLangOptions(), OutputFile, + ReadAnalyzerOptions())); break; + } case DumpRawTokens: { llvm::TimeRegion Timer(ClangFrontendTimer); -- 2.40.0