diff options
Diffstat (limited to 'clang/lib/Frontend/CompilerInvocation.cpp')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index f511fdcd87a..f90e9300cd4 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -181,6 +181,9 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, } } +static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, + DiagnosticsEngine &Diags); + static void getAllNoBuiltinFuncValues(ArgList &Args, std::vector<std::string> &Funcs) { SmallVector<const char *, 8> Values; @@ -343,6 +346,8 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, } } + parseAnalyzerConfigs(Opts, Diags); + llvm::raw_string_ostream os(Opts.FullCompilerInvocation); for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) { if (i != 0) @@ -354,6 +359,64 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, return Success; } +static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config, + StringRef OptionName, StringRef DefaultVal) { + return Config.insert({OptionName, DefaultVal}).first->second; +} + +static void initOption(AnalyzerOptions::ConfigTable &Config, + StringRef &OptionField, StringRef Name, + StringRef DefaultVal) { + OptionField = getStringOption(Config, Name, DefaultVal); +} + +static void initOption(AnalyzerOptions::ConfigTable &Config, + bool &OptionField, StringRef Name, bool DefaultVal) { + // FIXME: We should emit a warning here if the value is something other than + // "true", "false", or the empty string (meaning the default value), + // but the AnalyzerOptions doesn't have access to a diagnostic engine. + OptionField = llvm::StringSwitch<bool>(getStringOption(Config, Name, + (DefaultVal ? "true" : "false"))) + .Case("true", true) + .Case("false", false) + .Default(DefaultVal); +} + +static void initOption(AnalyzerOptions::ConfigTable &Config, + unsigned &OptionField, StringRef Name, + unsigned DefaultVal) { + OptionField = DefaultVal; + bool HasFailed = getStringOption(Config, Name, std::to_string(DefaultVal)) + .getAsInteger(10, OptionField); + assert(!HasFailed && "analyzer-config option should be numeric"); + (void)HasFailed; +} + +static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, + DiagnosticsEngine &Diags) { + // TODO: Emit warnings for incorrect options. + // TODO: There's no need to store the entire configtable, it'd be plenty + // enough tostore checker options. + +#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ + initOption(AnOpts.Config, AnOpts.NAME, CMDFLAG, DEFAULT_VAL); \ + +#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \ + SHALLOW_VAL, DEEP_VAL) \ + switch (AnOpts.getUserMode()) { \ + case UMK_Shallow: \ + initOption(AnOpts.Config, AnOpts.NAME, CMDFLAG, SHALLOW_VAL); \ + break; \ + case UMK_Deep: \ + initOption(AnOpts.Config, AnOpts.NAME, CMDFLAG, DEEP_VAL); \ + break; \ + } \ + +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" +#undef ANALYZER_OPTION +#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE +} + static bool ParseMigratorArgs(MigratorOptions &Opts, ArgList &Args) { Opts.NoNSAllocReallocError = Args.hasArg(OPT_migrator_no_nsalloc_error); Opts.NoFinalizeRemoval = Args.hasArg(OPT_migrator_no_finalize_removal); |