1 //===- AnalyzerOptions.cpp - Analysis Engine Options ----------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains special accessors for analyzer configuration options
11 // with string representations.
13 //===----------------------------------------------------------------------===//
15 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
16 #include "clang/StaticAnalyzer/Core/Checker.h"
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/FileSystem.h"
23 #include "llvm/Support/raw_ostream.h"
29 using namespace clang;
33 std::vector<StringRef>
34 AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) {
35 static const StringRef StaticAnalyzerChecks[] = {
37 #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \
39 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
43 std::vector<StringRef> Result;
44 for (StringRef CheckName : StaticAnalyzerChecks) {
45 if (!CheckName.startswith("debug.") &&
46 (IncludeExperimental || !CheckName.startswith("alpha.")))
47 Result.push_back(CheckName);
52 ExplorationStrategyKind
53 AnalyzerOptions::getExplorationStrategy() const {
55 llvm::StringSwitch<llvm::Optional<ExplorationStrategyKind>>(
57 .Case("dfs", ExplorationStrategyKind::DFS)
58 .Case("bfs", ExplorationStrategyKind::BFS)
59 .Case("unexplored_first",
60 ExplorationStrategyKind::UnexploredFirst)
61 .Case("unexplored_first_queue",
62 ExplorationStrategyKind::UnexploredFirstQueue)
63 .Case("unexplored_first_location_queue",
64 ExplorationStrategyKind::UnexploredFirstLocationQueue)
65 .Case("bfs_block_dfs_contents",
66 ExplorationStrategyKind::BFSBlockDFSContents)
68 assert(K.hasValue() && "User mode is invalid.");
72 IPAKind AnalyzerOptions::getIPAMode() const {
73 auto K = llvm::StringSwitch<llvm::Optional<IPAKind>>(IPAMode)
74 .Case("none", IPAK_None)
75 .Case("basic-inlining", IPAK_BasicInlining)
76 .Case("inlining", IPAK_Inlining)
77 .Case("dynamic", IPAK_DynamicDispatch)
78 .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)
80 assert(K.hasValue() && "IPA Mode is invalid.");
86 AnalyzerOptions::mayInlineCXXMemberFunction(
87 CXXInlineableMemberKind Param) const {
88 if (getIPAMode() < IPAK_Inlining)
92 llvm::StringSwitch<llvm::Optional<CXXInlineableMemberKind>>(
93 CXXMemberInliningMode)
94 .Case("constructors", CIMK_Constructors)
95 .Case("destructors", CIMK_Destructors)
96 .Case("methods", CIMK_MemberFunctions)
97 .Case("none", CIMK_None)
100 assert(K.hasValue() && "Invalid c++ member function inlining mode.");
105 StringRef AnalyzerOptions::getCheckerStringOption(StringRef OptionName,
106 StringRef DefaultVal,
107 const CheckerBase *C,
108 bool SearchInParents) const {
110 // Search for a package option if the option for the checker is not specified
111 // and search in parents is enabled.
112 StringRef CheckerName = C->getTagDescription();
114 assert(!CheckerName.empty() &&
115 "Empty checker name! Make sure the checker object (including it's "
116 "bases!) if fully initialized before calling this function!");
117 ConfigTable::const_iterator E = Config.end();
119 ConfigTable::const_iterator I =
120 Config.find((Twine(CheckerName) + ":" + OptionName).str());
122 return StringRef(I->getValue());
123 size_t Pos = CheckerName.rfind('.');
124 if (Pos == StringRef::npos)
126 CheckerName = CheckerName.substr(0, Pos);
127 } while (!CheckerName.empty() && SearchInParents);
131 bool AnalyzerOptions::getCheckerBooleanOption(StringRef Name, bool DefaultVal,
132 const CheckerBase *C,
133 bool SearchInParents) const {
134 // FIXME: We should emit a warning here if the value is something other than
135 // "true", "false", or the empty string (meaning the default value),
136 // but the AnalyzerOptions doesn't have access to a diagnostic engine.
138 return llvm::StringSwitch<bool>(
139 getCheckerStringOption(Name, DefaultVal ? "true" : "false", C,
142 .Case("false", false)
143 .Default(DefaultVal);
146 int AnalyzerOptions::getCheckerIntegerOption(StringRef Name, int DefaultVal,
147 const CheckerBase *C,
148 bool SearchInParents) const {
149 int Ret = DefaultVal;
150 bool HasFailed = getCheckerStringOption(Name, std::to_string(DefaultVal), C,
152 .getAsInteger(10, Ret);
153 assert(!HasFailed && "analyzer-config option should be numeric");