diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 190 |
1 files changed, 76 insertions, 114 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index 0700bd08959..37bbcb4219f 100644 --- a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -51,7 +51,7 @@ AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) { UserModeKind AnalyzerOptions::getUserMode() { if (!UserMode.hasValue()) { - UserMode = getOptionAsString("mode", "deep"); + UserMode = getStringOption("mode", "deep"); } auto K = llvm::StringSwitch<llvm::Optional<UserModeKind>>(*UserMode) @@ -65,7 +65,7 @@ UserModeKind AnalyzerOptions::getUserMode() { ExplorationStrategyKind AnalyzerOptions::getExplorationStrategy() { if (!ExplorationStrategy.hasValue()) { - ExplorationStrategy = getOptionAsString("exploration_strategy", + ExplorationStrategy = getStringOption("exploration_strategy", "unexplored_first_queue"); } auto K = @@ -90,10 +90,10 @@ IPAKind AnalyzerOptions::getIPAMode() { if (!IPAMode.hasValue()) { switch (getUserMode()) { case UMK_Shallow: - IPAMode = getOptionAsString("ipa", "inlining"); + IPAMode = getStringOption("ipa", "inlining"); break; case UMK_Deep: - IPAMode = getOptionAsString("ipa", "dynamic-bifurcate"); + IPAMode = getStringOption("ipa", "dynamic-bifurcate"); break; } } @@ -112,7 +112,7 @@ IPAKind AnalyzerOptions::getIPAMode() { bool AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind Param) { if (!CXXMemberInliningMode.hasValue()) { - CXXMemberInliningMode = getOptionAsString("c++-inlining", "destructors"); + CXXMemberInliningMode = getStringOption("c++-inlining", "destructors"); } if (getIPAMode() < IPAK_Inlining) @@ -132,14 +132,62 @@ AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind Param) { return *K >= Param; } -static StringRef toString(bool b) { return b ? "true" : "false"; } +StringRef AnalyzerOptions::getStringOption(StringRef OptionName, + StringRef DefaultVal) { + return Config.insert({OptionName, DefaultVal}).first->second; +} + +static StringRef toString(bool B) { return (B ? "true" : "false"); } + +template <typename T> +static StringRef toString(T) = delete; + +void AnalyzerOptions::initOption(Optional<StringRef> &V, StringRef Name, + StringRef DefaultVal) { + if (V.hasValue()) + return; + + V = getStringOption(Name, DefaultVal); +} -StringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName, - StringRef OptionName, - StringRef Default, - bool SearchInParents) { +void AnalyzerOptions::initOption(Optional<bool> &V, StringRef Name, + bool DefaultVal) { + if (V.hasValue()) + return; + + // 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. + V = llvm::StringSwitch<bool>(getStringOption(Name, toString(DefaultVal))) + .Case("true", true) + .Case("false", false) + .Default(DefaultVal); +} + +void AnalyzerOptions::initOption(Optional<unsigned> &V, StringRef Name, + unsigned DefaultVal) { + if (V.hasValue()) + return; + + V = DefaultVal; + bool HasFailed = getStringOption(Name, std::to_string(DefaultVal)) + .getAsInteger(10, *V); + assert(!HasFailed && "analyzer-config option should be numeric"); + (void)HasFailed; +} + +StringRef AnalyzerOptions::getCheckerStringOption(StringRef OptionName, + StringRef DefaultVal, + const CheckerBase *C, + bool SearchInParents) const { + assert(C); // Search for a package option if the option for the checker is not specified // and search in parents is enabled. + StringRef CheckerName = C->getTagDescription(); + + assert(!CheckerName.empty() && + "Empty checker name! Make sure the checker object (including it's " + "bases!) if fully initialized before calling this function!"); ConfigTable::const_iterator E = Config.end(); do { ConfigTable::const_iterator I = @@ -148,127 +196,41 @@ StringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName, return StringRef(I->getValue()); size_t Pos = CheckerName.rfind('.'); if (Pos == StringRef::npos) - return Default; + return DefaultVal; CheckerName = CheckerName.substr(0, Pos); } while (!CheckerName.empty() && SearchInParents); - return Default; + return DefaultVal; } -bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal, - const CheckerBase *C, - bool SearchInParents) { +bool AnalyzerOptions::getCheckerBooleanOption(StringRef Name, bool DefaultVal, + const CheckerBase *C, + bool SearchInParents) const { // 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. - StringRef Default = toString(DefaultVal); - StringRef V = - C ? getCheckerOption(C->getTagDescription(), Name, Default, - SearchInParents) - : getOptionAsString(Name, Default); - return llvm::StringSwitch<bool>(V) + assert(C); + return llvm::StringSwitch<bool>( + getCheckerStringOption(Name, toString(DefaultVal), C, SearchInParents)) .Case("true", true) .Case("false", false) .Default(DefaultVal); } -bool AnalyzerOptions::getBooleanOption(Optional<bool> &V, StringRef Name, - bool DefaultVal, const CheckerBase *C, - bool SearchInParents) { - if (!V.hasValue()) - V = getBooleanOption(Name, DefaultVal, C, SearchInParents); - return V.getValue(); -} - -int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal, +int AnalyzerOptions::getCheckerIntegerOption(StringRef Name, int DefaultVal, const CheckerBase *C, - bool SearchInParents) { - SmallString<10> StrBuf; - llvm::raw_svector_ostream OS(StrBuf); - OS << DefaultVal; - - StringRef V = C ? getCheckerOption(C->getTagDescription(), Name, OS.str(), - SearchInParents) - : getOptionAsString(Name, OS.str()); - - int Res = DefaultVal; - bool b = V.getAsInteger(10, Res); - assert(!b && "analyzer-config option should be numeric"); - (void)b; - return Res; -} - -unsigned AnalyzerOptions::getOptionAsUInt(Optional<unsigned> &V, StringRef Name, - unsigned DefaultVal, - const CheckerBase *C, - bool SearchInParents) { - if (!V.hasValue()) - V = getOptionAsInteger(Name, DefaultVal, C, SearchInParents); - return V.getValue(); -} - -StringRef AnalyzerOptions::getOptionAsString(StringRef Name, - StringRef DefaultVal, - const CheckerBase *C, - bool SearchInParents) { - return C ? getCheckerOption(C->getTagDescription(), Name, DefaultVal, - SearchInParents) - : StringRef( - Config.insert(std::make_pair(Name, DefaultVal)).first->second); -} - -StringRef AnalyzerOptions::getOptionAsString(Optional<StringRef> &V, - StringRef Name, - StringRef DefaultVal, - const ento::CheckerBase *C, - bool SearchInParents) { - if (!V.hasValue()) - V = getOptionAsString(Name, DefaultVal, C, SearchInParents); - return V.getValue(); -} - -static bool getOption(AnalyzerOptions &A, Optional<bool> &V, StringRef Name, - bool DefaultVal) { - return A.getBooleanOption(V, Name, DefaultVal); + bool SearchInParents) const { + int Ret = DefaultVal; + bool HasFailed = getCheckerStringOption(Name, std::to_string(DefaultVal), C, + SearchInParents) + .getAsInteger(10, Ret); + assert(!HasFailed && "analyzer-config option should be numeric"); + (void)HasFailed; + return Ret; } -static unsigned getOption(AnalyzerOptions &A, Optional<unsigned> &V, - StringRef Name, unsigned DefaultVal) { - return A.getOptionAsUInt(V, Name, DefaultVal); -} - -static StringRef getOption(AnalyzerOptions &A, Optional<StringRef> &V, - StringRef Name, StringRef DefaultVal) { - return A.getOptionAsString(V, Name, DefaultVal); -} - -#define ANALYZER_OPTION_GEN_FN(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL, \ - CREATE_FN) \ -TYPE AnalyzerOptions::CREATE_FN() { \ - return getOption(*this, NAME, CMDFLAG, DEFAULT_VAL); \ -} - -#define ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE( \ - TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL, DEEP_VAL, CREATE_FN) \ -TYPE AnalyzerOptions::CREATE_FN() { \ - switch (getUserMode()) { \ - case UMK_Shallow: \ - return getOption(*this, NAME, CMDFLAG, SHALLOW_VAL); \ - case UMK_Deep: \ - return getOption(*this, NAME, CMDFLAG, DEEP_VAL); \ - } \ - \ - llvm_unreachable("Unknown usermode!"); \ - return {}; \ -} - -#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" - -#undef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE -#undef ANALYZER_OPTION_WITH_FN - StringRef AnalyzerOptions::getCTUDir() { if (!CTUDir.hasValue()) { - CTUDir = getOptionAsString("ctu-dir", ""); + CTUDir = getStringOption("ctu-dir", ""); if (!llvm::sys::fs::is_directory(*CTUDir)) CTUDir = ""; } |