UMK_Deep = 2
};
+/// Stores options for the analyzer from the command line.
+///
+/// Some options are frontend flags (e.g.: -analyzer-output), but some are
+/// analyzer configuration options, which are preceded by -analyzer-config
+/// (e.g.: -analyzer-config notes-as-events=true).
+///
+/// If you'd like to add a new frontend flag, add it to
+/// include/clang/Driver/CC1Options.td, add a new field to store the value of
+/// that flag in this class, and initialize it in
+/// lib/Frontend/CompilerInvocation.cpp.
+///
+/// If you'd like to add a new non-checker configuration, register it in
+/// include/clang/StaticAnalyzer/Core/AnalyzerOptions.def, and refer to the
+/// top of the file for documentation.
+///
+/// If you'd like to add a new checker option, call getChecker*Option()
+/// whenever.
+///
+/// Some of the options are controlled by raw frontend flags for no good reason,
+/// and should be eventually converted into -analyzer-config flags. New analyzer
+/// options should not be implemented as frontend flags. Frontend flags still
+/// make sense for things that do not affect the actual analysis.
class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
public:
using ConfigTable = llvm::StringMap<std::string>;
#undef ANALYZER_OPTION
#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
- /// A helper function that retrieves option for a given full-qualified
- /// checker name.
- /// Options for checkers can be specified via 'analyzer-config' command-line
- /// option.
- /// Example:
- /// @code-analyzer-config unix.Malloc:OptionName=CheckerOptionValue @endcode
- /// or @code-analyzer-config unix:OptionName=GroupOptionValue @endcode
- /// for groups of checkers.
- /// @param [in] CheckerName Full-qualified checker name, like
- /// alpha.unix.StreamChecker.
- /// @param [in] OptionName Name of the option to get.
- /// @param [in] Default Default value if no option is specified.
- /// @param [in] SearchInParents If set to true and the searched option was not
- /// specified for the given checker the options for the parent packages will
- /// be searched as well. The inner packages take precedence over the outer
- /// ones.
- /// @retval CheckerOptionValue An option for a checker if it was specified.
- /// @retval GroupOptionValue An option for group if it was specified and no
- /// checker-specific options were found. The closer group to checker,
- /// the more priority it has. For example, @c coregroup.subgroup has more
- /// priority than @c coregroup for @c coregroup.subgroup.CheckerName checker.
- /// @retval Default If nor checker option, nor group option was found.
- StringRef getCheckerOption(StringRef CheckerName, StringRef OptionName,
- StringRef Default,
- bool SearchInParents = false);
+ /// Query an option's string value.
+ ///
+ /// If an option value is not provided, returns the given \p DefaultVal.
+ /// @param [in] Name Name for option to retrieve.
+ /// @param [in] DefaultVal Default value returned if no such option was
+ /// specified.
+ StringRef getStringOption(StringRef OptionName, StringRef DefaultVal);
+
+ void initOption(Optional<StringRef> &V, StringRef Name,
+ StringRef DefaultVal);
+ void initOption(Optional<bool> &V, StringRef Name, bool DefaultVal);
+
+ void initOption(Optional<unsigned> &V, StringRef Name,
+ unsigned DefaultVal);
public:
AnalyzerOptions()
: DisableAllChecks(false), ShowCheckerHelp(false),
/// @param [in] Name Name for option to retrieve.
/// @param [in] DefaultVal Default value returned if no such option was
/// specified.
- /// @param [in] C The optional checker parameter that can be used to restrict
- /// the search to the options of this particular checker (and its parents
- /// depending on search mode).
+ /// @param [in] C The checker object the option belongs to. Checker options
+ /// are retrieved in the following format:
+ /// `-analyzer-config <package and checker name>:OptionName=Value.
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
/// ones.
- bool getBooleanOption(StringRef Name, bool DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
+ bool getCheckerBooleanOption(StringRef Name, bool DefaultVal,
+ const ento::CheckerBase *C,
+ bool SearchInParents = false) const;
- /// Variant that accepts a Optional value to cache the result.
- ///
- /// @param [in,out] V Return value storage, returned if parameter contains
- /// an existing valid option, else it is used to store a return value
- /// @param [in] Name Name for option to retrieve.
- /// @param [in] DefaultVal Default value returned if no such option was
- /// specified.
- /// @param [in] C The optional checker parameter that can be used to restrict
- /// the search to the options of this particular checker (and its parents
- /// depending on search mode).
- /// @param [in] SearchInParents If set to true and the searched option was not
- /// specified for the given checker the options for the parent packages will
- /// be searched as well. The inner packages take precedence over the outer
- /// ones.
- bool getBooleanOption(Optional<bool> &V, StringRef Name, bool DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
/// Interprets an option's string value as an integer value.
///
/// @param [in] Name Name for option to retrieve.
/// @param [in] DefaultVal Default value returned if no such option was
/// specified.
- /// @param [in] C The optional checker parameter that can be used to restrict
- /// the search to the options of this particular checker (and its parents
- /// depending on search mode).
+ /// @param [in] C The checker object the option belongs to. Checker options
+ /// are retrieved in the following format:
+ /// `-analyzer-config <package and checker name>:OptionName=Value.
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
/// ones.
- int getOptionAsInteger(StringRef Name, int DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
-
- unsigned getOptionAsUInt(Optional<unsigned> &V, StringRef Name,
- unsigned DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
+ int getCheckerIntegerOption(StringRef Name, int DefaultVal,
+ const ento::CheckerBase *C,
+ bool SearchInParents = false) const;
/// Query an option's string value.
///
/// @param [in] Name Name for option to retrieve.
/// @param [in] DefaultVal Default value returned if no such option was
/// specified.
- /// @param [in] C The optional checker parameter that can be used to restrict
- /// the search to the options of this particular checker (and its parents
- /// depending on search mode).
+ /// @param [in] C The checker object the option belongs to. Checker options
+ /// are retrieved in the following format:
+ /// `-analyzer-config <package and checker name>:OptionName=Value.
/// @param [in] SearchInParents If set to true and the searched option was not
/// specified for the given checker the options for the parent packages will
/// be searched as well. The inner packages take precedence over the outer
/// ones.
- StringRef getOptionAsString(StringRef Name, StringRef DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
-
- StringRef getOptionAsString(Optional<StringRef> &V, StringRef Name,
- StringRef DefaultVal,
- const ento::CheckerBase *C = nullptr,
- bool SearchInParents = false);
+ StringRef getCheckerStringOption(StringRef Name, StringRef DefaultVal,
+ const ento::CheckerBase *C,
+ bool SearchInParents = false) const;
#define ANALYZER_OPTION_GEN_FN(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL, \
- CREATE_FN) \
- TYPE CREATE_FN();
+ CREATE_FN) \
+ TYPE CREATE_FN() { \
+ initOption(NAME, CMDFLAG, DEFAULT_VAL); \
+ return NAME.getValue(); \
+ }
#define ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE( \
TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL, DEEP_VAL, CREATE_FN) \
- TYPE CREATE_FN();
+ TYPE CREATE_FN() { \
+ switch (getUserMode()) { \
+ case UMK_Shallow: \
+ initOption(NAME, CMDFLAG, SHALLOW_VAL); \
+ break; \
+ case UMK_Deep: \
+ initOption(NAME, CMDFLAG, DEEP_VAL); \
+ break; \
+ } \
+ \
+ return NAME.getValue(); \
+ }
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
check::LiveSymbols> {
bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const {
- return Opts.getBooleanOption("*", false, this) ||
- Opts.getBooleanOption(CallbackName, false, this);
+ return Opts.getCheckerBooleanOption("*", false, this) ||
+ Opts.getCheckerBooleanOption(CallbackName, false, this);
}
bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const {
// At this point, every statement in the translation unit has been analyzed by
// the CloneDetector. The only thing left to do is to report the found clones.
- int MinComplexity = Mgr.getAnalyzerOptions().getOptionAsInteger(
+ int MinComplexity = Mgr.getAnalyzerOptions().getCheckerIntegerOption(
"MinimumCloneComplexity", 50, this);
assert(MinComplexity >= 0);
- bool ReportSuspiciousClones = Mgr.getAnalyzerOptions().getBooleanOption(
- "ReportSuspiciousClones", true, this);
+ bool ReportSuspiciousClones = Mgr.getAnalyzerOptions()
+ .getCheckerBooleanOption("ReportSuspiciousClones", true, this);
- bool ReportNormalClones = Mgr.getAnalyzerOptions().getBooleanOption(
+ bool ReportNormalClones = Mgr.getAnalyzerOptions().getCheckerBooleanOption(
"ReportNormalClones", true, this);
- StringRef IgnoredFilesPattern = Mgr.getAnalyzerOptions().getOptionAsString(
- "IgnoredFilesPattern", "", this);
+ StringRef IgnoredFilesPattern = Mgr.getAnalyzerOptions()
+ .getCheckerStringOption("IgnoredFilesPattern", "", this);
// Let the CloneDetector create a list of clones from all the analyzed
// statements. We don't filter for matching variable patterns at this point
NonLocalizedStringChecker *checker =
mgr.registerChecker<NonLocalizedStringChecker>();
checker->IsAggressive =
- mgr.getAnalyzerOptions().getBooleanOption("AggressiveReport", false,
- checker);
+ mgr.getAnalyzerOptions().getCheckerBooleanOption("AggressiveReport",
+ false, checker);
}
void ento::registerEmptyLocalizationContextChecker(CheckerManager &mgr) {
void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
registerCStringCheckerBasic(mgr);
MallocChecker *checker = mgr.registerChecker<MallocChecker>();
- checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption(
+ checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption(
"Optimistic", false, checker);
checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
void ento::registerInnerPointerCheckerAux(CheckerManager &mgr) {
registerCStringCheckerBasic(mgr);
MallocChecker *checker = mgr.registerChecker<MallocChecker>();
- checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption(
+ checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption(
"Optimistic", false, checker);
checker->ChecksEnabled[MallocChecker::CK_InnerPointerChecker] = true;
checker->CheckNames[MallocChecker::CK_InnerPointerChecker] =
void ento::register##name(CheckerManager &mgr) { \
registerCStringCheckerBasic(mgr); \
MallocChecker *checker = mgr.registerChecker<MallocChecker>(); \
- checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption( \
+ checker->IsOptimistic = mgr.getAnalyzerOptions().getCheckerBooleanOption( \
"Optimistic", false, checker); \
checker->ChecksEnabled[MallocChecker::CK_##name] = true; \
checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
MmapWriteExecChecker *Mwec =
mgr.registerChecker<MmapWriteExecChecker>();
Mwec->ProtExecOv =
- mgr.getAnalyzerOptions().getOptionAsInteger("MmapProtExec", 0x04, Mwec);
+ mgr.getAnalyzerOptions()
+ .getCheckerIntegerOption("MmapProtExec", 0x04, Mwec);
Mwec->ProtReadOv =
- mgr.getAnalyzerOptions().getOptionAsInteger("MmapProtRead", 0x01, Mwec);
+ mgr.getAnalyzerOptions()
+ .getCheckerIntegerOption("MmapProtRead", 0x01, Mwec);
}
checker->NeedTracking = checker->NeedTracking || trackingRequired; \
checker->NoDiagnoseCallsToSystemHeaders = \
checker->NoDiagnoseCallsToSystemHeaders || \
- mgr.getAnalyzerOptions().getBooleanOption( \
+ mgr.getAnalyzerOptions().getCheckerBooleanOption( \
"NoDiagnoseCallsToSystemHeaders", false, checker, true); \
}
NumberObjectConversionChecker *Chk =
Mgr.registerChecker<NumberObjectConversionChecker>();
Chk->Pedantic =
- Mgr.getAnalyzerOptions().getBooleanOption("Pedantic", false, Chk);
+ Mgr.getAnalyzerOptions().getCheckerBooleanOption("Pedantic", false, Chk);
}
BugReporter &BRArg) const {
BR = &BRArg;
AllowedPad =
- MGR.getAnalyzerOptions().getOptionAsInteger("AllowedPad", 24, this);
+ MGR.getAnalyzerOptions()
+ .getCheckerIntegerOption("AllowedPad", 24, this);
assert(AllowedPad >= 0 && "AllowedPad option should be non-negative");
// The calls to checkAST* from AnalysisConsumer don't
AnalyzerOptions &Options = Mgr.getAnalyzerOptions();
- Chk->IncludeAllocationLine = Options.getBooleanOption(
+ Chk->IncludeAllocationLine = Options.getCheckerBooleanOption(
"leak-diagnostics-reference-allocation", false, Chk);
- Chk->ShouldCheckOSObjectRetainCount = Options.getBooleanOption(
- "CheckOSObject", true, Chk);
+ Chk->ShouldCheckOSObjectRetainCount = Options.getCheckerBooleanOption(
+ "CheckOSObject", true, Chk);
}
UninitObjCheckerOptions &ChOpts = Chk->Opts;
ChOpts.IsPedantic =
- AnOpts.getBooleanOption("Pedantic", /*DefaultVal*/ false, Chk);
+ AnOpts.getCheckerBooleanOption("Pedantic", /*DefaultVal*/ false, Chk);
ChOpts.ShouldConvertNotesToWarnings =
- AnOpts.getBooleanOption("NotesAsWarnings", /*DefaultVal*/ false, Chk);
- ChOpts.CheckPointeeInitialization = AnOpts.getBooleanOption(
+ AnOpts.getCheckerBooleanOption("NotesAsWarnings", /*DefaultVal*/ false, Chk);
+ ChOpts.CheckPointeeInitialization = AnOpts.getCheckerBooleanOption(
"CheckPointeeInitialization", /*DefaultVal*/ false, Chk);
ChOpts.IgnoredRecordsWithFieldPattern =
- AnOpts.getOptionAsString("IgnoreRecordsWithField",
+ AnOpts.getCheckerStringOption("IgnoreRecordsWithField",
/*DefaultVal*/ "", Chk);
}
VirtualCallChecker *checker = mgr.registerChecker<VirtualCallChecker>();
checker->IsPureOnly =
- mgr.getAnalyzerOptions().getBooleanOption("PureOnly", false, checker);
+ mgr.getAnalyzerOptions().getCheckerBooleanOption("PureOnly", false,
+ checker);
}
UserModeKind AnalyzerOptions::getUserMode() {
if (!UserMode.hasValue()) {
- UserMode = getOptionAsString("mode", "deep");
+ UserMode = getStringOption("mode", "deep");
}
auto K = llvm::StringSwitch<llvm::Optional<UserModeKind>>(*UserMode)
ExplorationStrategyKind
AnalyzerOptions::getExplorationStrategy() {
if (!ExplorationStrategy.hasValue()) {
- ExplorationStrategy = getOptionAsString("exploration_strategy",
+ ExplorationStrategy = getStringOption("exploration_strategy",
"unexplored_first_queue");
}
auto K =
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;
}
}
bool
AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind Param) {
if (!CXXMemberInliningMode.hasValue()) {
- CXXMemberInliningMode = getOptionAsString("c++-inlining", "destructors");
+ CXXMemberInliningMode = getStringOption("c++-inlining", "destructors");
}
if (getIPAMode() < IPAK_Inlining)
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 =
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 = "";
}
// Checker one has Option specified as true. It should read true regardless of
// search mode.
CheckerOneMock CheckerOne;
- EXPECT_TRUE(Opts.getBooleanOption("Option", false, &CheckerOne));
+ EXPECT_TRUE(Opts.getCheckerBooleanOption("Option", false, &CheckerOne));
// The package option is overridden with a checker option.
- EXPECT_TRUE(Opts.getBooleanOption("Option", false, &CheckerOne, true));
+ EXPECT_TRUE(Opts.getCheckerBooleanOption("Option", false, &CheckerOne,
+ true));
// The Outer package option is overridden by the Inner package option. No
// package option is specified.
- EXPECT_TRUE(Opts.getBooleanOption("Option2", false, &CheckerOne, true));
+ EXPECT_TRUE(Opts.getCheckerBooleanOption("Option2", false, &CheckerOne,
+ true));
// No package option is specified and search in packages is turned off. The
// default value should be returned.
- EXPECT_FALSE(Opts.getBooleanOption("Option2", false, &CheckerOne));
- EXPECT_TRUE(Opts.getBooleanOption("Option2", true, &CheckerOne));
+ EXPECT_FALSE(Opts.getCheckerBooleanOption("Option2", false, &CheckerOne));
+ EXPECT_TRUE(Opts.getCheckerBooleanOption("Option2", true, &CheckerOne));
// Checker true has no option specified. It should get the default value when
// search in parents turned off and false when search in parents turned on.
CheckerTwoMock CheckerTwo;
- EXPECT_FALSE(Opts.getBooleanOption("Option", false, &CheckerTwo));
- EXPECT_TRUE(Opts.getBooleanOption("Option", true, &CheckerTwo));
- EXPECT_FALSE(Opts.getBooleanOption("Option", true, &CheckerTwo, true));
+ EXPECT_FALSE(Opts.getCheckerBooleanOption("Option", false, &CheckerTwo));
+ EXPECT_TRUE(Opts.getCheckerBooleanOption("Option", true, &CheckerTwo));
+ EXPECT_FALSE(Opts.getCheckerBooleanOption("Option", true, &CheckerTwo, true));
}
TEST(StaticAnalyzerOptions, StringOptions) {
CheckerOneMock CheckerOne;
EXPECT_TRUE("StringValue" ==
- Opts.getOptionAsString("Option", "DefaultValue", &CheckerOne));
+ Opts.getCheckerStringOption("Option", "DefaultValue", &CheckerOne));
EXPECT_TRUE("DefaultValue" ==
- Opts.getOptionAsString("Option2", "DefaultValue", &CheckerOne));
+ Opts.getCheckerStringOption("Option2", "DefaultValue", &CheckerOne));
}
} // end namespace ento
} // end namespace clang