diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index cec31e199306..9ff5c223ea3b 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -25,6 +25,70 @@ def target_feature : Separate<"-target-feature">, def triple : Separate<"-triple">, HelpText<"Specify target triple (e.g. i686-apple-darwin9)">; +// Analyzer Options + +def analysis_CFGDump : Flag<"-cfg-dump">, + HelpText<"Display Control-Flow Graphs">; +def analysis_CFGView : Flag<"-cfg-view">, + HelpText<"View Control-Flow Graphs using GraphViz">; +def analysis_DisplayLiveVariables : Flag<"-dump-live-variables">, + HelpText<"Print results of live variable analysis">; +def analysis_SecuritySyntacticChecks : Flag<"-warn-security-syntactic">, + HelpText<"Perform quick security checks that require no data flow">; +def analysis_WarnDeadStores : Flag<"-warn-dead-stores">, + HelpText<"Warn about stores to dead variables">; +def analysis_WarnUninitVals : Flag<"-warn-uninit-values">, + HelpText<"Warn about uses of uninitialized variables">; +def analysis_WarnObjCMethSigs : Flag<"-warn-objc-methodsigs">, + HelpText<"Warn about Objective-C method signatures with type incompatibilities">; +def analysis_WarnObjCDealloc : Flag<"-warn-objc-missing-dealloc">, + HelpText<"Warn about Objective-C classes that lack a correct implementation of -dealloc">; +def analysis_WarnObjCUnusedIvars : Flag<"-warn-objc-unused-ivars">, + HelpText<"Warn about private ivars that are never used">; +def analysis_CheckerCFRef : Flag<"-checker-cfref">, + HelpText<"Run the [Core] Foundation reference count checker">; +def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">, + HelpText<"Warn about unintended use of sizeof() on pointer expressions">; +def analysis_InlineCall : Flag<"-inline-call">, + HelpText<"Experimental transfer function inling callees when its definition is available.">; + +def analyzer_store : Separate<"-analyzer-store">, + HelpText<"Source Code Analysis - Abstract Memory Store Models">; +def analyzer_store_EQ : Joined<"-analyzer-store=">, Alias; + +def analyzer_constraints : Separate<"-analyzer-constraints">, + HelpText<"Source Code Analysis - Symbolic Constraint Engines">; +def analyzer_constraints_EQ : Joined<"-analyzer-constraints=">, + Alias; + +def analyzer_output : Separate<"-analyzer-output">, + HelpText<"Source Code Analysis - Output Options">; +def analyzer_output_EQ : Joined<"-analyzer-output=">, + Alias; + +def analyzer_opt_analyze_headers : Flag<"-analyzer-opt-analyze-headers">, + HelpText<"Force the static analyzer to analyze functions defined in header files">; +def analyzer_display_progress : Flag<"-analyzer-display-progress">, + HelpText<"Emit verbose output about the analyzer's progress">; +def analyzer_experimental_checks : Flag<"-analyzer-experimental-checks">, + HelpText<"Use experimental path-sensitive checks">; +def analyzer_experimental_internal_checks : + Flag<"-analyzer-experimental-internal-checks">, + HelpText<"Use new default path-sensitive checks currently in testing">; +def analyze_function : Separate<"-analyze-function">, + HelpText<"Run analysis on specific function">; +def analyze_function_EQ : Joined<"-analyze-function=">, Alias; +def analyzer_eagerly_assume : Flag<"-analyzer-eagerly-assume">, + HelpText<"Eagerly assume the truth/falseness of some symbolic constraints">; +def analyzer_no_purge_dead : Flag<"-analyzer-no-purge-dead">, + HelpText<"Don't remove dead symbols, bindings, and constraints before processing a statement">; +def trim_egraph : Flag<"-trim-egraph">, + HelpText<"Only show error-related paths in the analysis graph">; +def analyzer_viz_egraph_graphviz : Flag<"-analyzer-viz-egraph-graphviz">, + HelpText<"Display exploded graph using GraphViz">; +def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">, + HelpText<"Display exploded graph using Ubigraph">; + // CodeGen Options def disable_llvm_optzns : Flag<"-disable-llvm-optzns">, diff --git a/clang/lib/Driver/CC1Options.cpp b/clang/lib/Driver/CC1Options.cpp index f92ada77fa3c..f49c641c1997 100644 --- a/clang/lib/Driver/CC1Options.cpp +++ b/clang/lib/Driver/CC1Options.cpp @@ -14,6 +14,7 @@ #include "clang/Driver/Option.h" #include "clang/Frontend/CompilerInvocation.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Host.h" @@ -79,6 +80,73 @@ getAllArgValues(ArgList &Args, cc1options::ID ID) { // +static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args) { + Opts.AnalysisList.clear(); +#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) \ + if (Args.hasArg(cc1options::OPT_analysis_##NAME)) \ + Opts.AnalysisList.push_back(NAME); +#include "clang/Frontend/Analyses.def" + + if (Arg *A = Args.getLastArg(cc1options::OPT_analyzer_store)) { + llvm::StringRef Name = A->getValue(Args); + AnalysisStores Value = llvm::StringSwitch(Name) +#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) \ + .Case(CMDFLAG, NAME##Model) +#include "clang/Frontend/Analyses.def" + .Default(NumStores); + // FIXME: Error handling. + if (Value == NumStores) + llvm::errs() << "error: invalid analysis store '" << Name << "'\n"; + else + Opts.AnalysisStoreOpt = Value; + } + + if (Arg *A = Args.getLastArg(cc1options::OPT_analyzer_constraints)) { + llvm::StringRef Name = A->getValue(Args); + AnalysisConstraints Value = llvm::StringSwitch(Name) +#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \ + .Case(CMDFLAG, NAME##Model) +#include "clang/Frontend/Analyses.def" + .Default(NumConstraints); + // FIXME: Error handling. + if (Value == NumConstraints) + llvm::errs() << "error: invalid analysis constraints '" << Name << "'\n"; + else + Opts.AnalysisConstraintsOpt = Value; + } + + if (Arg *A = Args.getLastArg(cc1options::OPT_analyzer_output)) { + llvm::StringRef Name = A->getValue(Args); + AnalysisDiagClients Value = llvm::StringSwitch(Name) +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) \ + .Case(CMDFLAG, PD_##NAME) +#include "clang/Frontend/Analyses.def" + .Default(NUM_ANALYSIS_DIAG_CLIENTS); + // FIXME: Error handling. + if (Value == NUM_ANALYSIS_DIAG_CLIENTS) + llvm::errs() << "error: invalid analysis output '" << Name << "'\n"; + else + Opts.AnalysisDiagOpt = Value; + } + + Opts.VisualizeEGDot = + Args.hasArg(cc1options::OPT_analyzer_viz_egraph_graphviz); + Opts.VisualizeEGUbi = + Args.hasArg(cc1options::OPT_analyzer_viz_egraph_ubigraph); + Opts.AnalyzeAll = Args.hasArg(cc1options::OPT_analyzer_opt_analyze_headers); + Opts.AnalyzerDisplayProgress = + Args.hasArg(cc1options::OPT_analyzer_display_progress); + Opts.PurgeDead = !Args.hasArg(cc1options::OPT_analyzer_no_purge_dead); + Opts.EagerlyAssume = Args.hasArg(cc1options::OPT_analyzer_eagerly_assume); + Opts.AnalyzeSpecificFunction = + getLastArgValue(Args, cc1options::OPT_analyze_function); + Opts.EnableExperimentalChecks = + Args.hasArg(cc1options::OPT_analyzer_experimental_checks); + Opts.EnableExperimentalInternalChecks = + Args.hasArg(cc1options::OPT_analyzer_experimental_internal_checks); + Opts.TrimGraph = Args.hasArg(cc1options::OPT_trim_egraph); +} + static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args) { // -Os implies -O2 if (Args.hasArg(cc1options::OPT_Os)) @@ -160,6 +228,7 @@ void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, << " value )\n"; } + ParseAnalyzerArgs(Res.getAnalyzerOpts(), *InputArgs); ParseCodeGenArgs(Res.getCodeGenOpts(), *InputArgs); ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *InputArgs); ParseTargetArgs(Res.getTargetOpts(), *InputArgs); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index eecd97684a56..f55922dd8314 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -17,7 +17,7 @@ static const char *getAnalysisName(Analyses Kind) { default: llvm::llvm_unreachable("Unknown analysis store!"); #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\ - case NAME: return CMDFLAG; + case NAME: return "-" CMDFLAG; #include "clang/Frontend/Analyses.def" } } @@ -89,7 +89,7 @@ static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts, if (Opts.EnableExperimentalChecks) Res.push_back("-analyzer-experimental-checks"); if (Opts.EnableExperimentalInternalChecks) - Res.push_back("-analyzer-experimental-internal-checls"); + Res.push_back("-analyzer-experimental-internal-checks"); } static void CodeGenOptsToArgs(const CodeGenOptions &Opts, diff --git a/clang/tools/clang-cc/Options.cpp b/clang/tools/clang-cc/Options.cpp index 95c81a513f90..87b88f3279e9 100644 --- a/clang/tools/clang-cc/Options.cpp +++ b/clang/tools/clang-cc/Options.cpp @@ -81,7 +81,7 @@ 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")); @@ -93,7 +93,7 @@ AnalyzerExperimentalChecks("analyzer-experimental-checks", static llvm::cl::opt AnalyzerExperimentalInternalChecks("analyzer-experimental-internal-checks", llvm::cl::desc("Use new default path-sensitive checks currently in testing")); - + static llvm::cl::opt AnalyzeSpecificFunction("analyze-function", llvm::cl::desc("Run analysis on specific function"));