17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
22 using namespace clang;
26 std::vector<StringRef>
28 static const StringRef StaticAnalyzerChecks[] = {
30 #define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN) \
32 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
36 std::vector<StringRef>
Result;
37 for (StringRef
CheckName : StaticAnalyzerChecks) {
39 (IncludeExperimental || !
CheckName.startswith(
"alpha.")))
46 if (UserMode == UMK_NotSet) {
48 Config.insert(std::make_pair(
"mode",
"deep")).first->second;
49 UserMode = llvm::StringSwitch<UserModeKind>(ModeStr)
50 .Case(
"shallow", UMK_Shallow)
51 .Case(
"deep", UMK_Deep)
53 assert(UserMode != UMK_NotSet &&
"User mode is invalid.");
64 const char *DefaultIPA =
nullptr;
65 UserModeKind HighLevelMode = getUserMode();
66 if (HighLevelMode == UMK_Shallow)
67 DefaultIPA =
"inlining";
68 else if (HighLevelMode == UMK_Deep)
69 DefaultIPA =
"dynamic-bifurcate";
74 Config.insert(std::make_pair(
"ipa", DefaultIPA)).first->second;
75 IPAKind IPAConfig = llvm::StringSwitch<IPAKind>(ModeStr)
82 assert(IPAConfig !=
IPAK_NotSet &&
"IPA Mode is invalid.");
96 if (!CXXMemberInliningMode) {
97 static const char *ModeKey =
"c++-inlining";
100 Config.insert(std::make_pair(ModeKey,
"destructors")).first->second;
105 MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr)
119 return CXXMemberInliningMode >= K;
122 static StringRef
toString(
bool b) {
return b ?
"true" :
"false"; }
124 StringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName,
125 StringRef OptionName,
127 bool SearchInParents) {
130 ConfigTable::const_iterator
E = Config.end();
132 ConfigTable::const_iterator
I =
133 Config.find((Twine(CheckerName) +
":" + OptionName).str());
135 return StringRef(I->getValue());
136 size_t Pos = CheckerName.rfind(
'.');
137 if (Pos == StringRef::npos)
139 CheckerName = CheckerName.substr(0, Pos);
140 }
while (!CheckerName.empty() && SearchInParents);
146 bool SearchInParents) {
150 StringRef Default =
toString(DefaultVal);
154 : StringRef(Config.insert(std::make_pair(Name, Default)).first->second);
155 return llvm::StringSwitch<bool>(V)
157 .Case(
"false",
false)
158 .Default(DefaultVal);
163 bool SearchInParents) {
165 V = getBooleanOption(Name, DefaultVal, C, SearchInParents);
170 return getBooleanOption(IncludeTemporaryDtorsInCFG,
171 "cfg-temporary-dtors",
176 return getBooleanOption(IncludeImplicitDtorsInCFG,
177 "cfg-implicit-dtors",
182 return getBooleanOption(IncludeLifetimeInCFG,
"cfg-lifetime",
187 return getBooleanOption(InlineCXXStandardLibrary,
188 "c++-stdlib-inlining",
193 return getBooleanOption(InlineTemplateFunctions,
194 "c++-template-inlining",
199 return getBooleanOption(InlineCXXAllocator,
200 "c++-allocator-inlining",
205 return getBooleanOption(InlineCXXContainerMethods,
206 "c++-container-inlining",
211 return getBooleanOption(InlineCXXSharedPtrDtor,
212 "c++-shared_ptr-inlining",
218 return getBooleanOption(ObjCInliningMode,
224 return getBooleanOption(SuppressNullReturnPaths,
225 "suppress-null-return-paths",
230 return getBooleanOption(AvoidSuppressingNullArgumentPaths,
231 "avoid-suppressing-null-argument-paths",
236 return getBooleanOption(SuppressInlinedDefensiveChecks,
237 "suppress-inlined-defensive-checks",
242 return getBooleanOption(SuppressFromCXXStandardLibrary,
243 "suppress-c++-stdlib",
248 return getBooleanOption(ReportIssuesInMainSourceFile,
249 "report-in-main-source-file",
255 return getBooleanOption(StableReportFilename,
256 "stable-report-filename",
262 bool SearchInParents) {
264 llvm::raw_svector_ostream OS(StrBuf);
269 : StringRef(Config.insert(std::make_pair(Name, OS.str()))
272 int Res = DefaultVal;
273 bool b = V.getAsInteger(10, Res);
274 assert(!b &&
"analyzer-config option should be numeric");
280 StringRef DefaultVal,
282 bool SearchInParents) {
286 Config.insert(std::make_pair(Name, DefaultVal)).first->second);
290 if (!AlwaysInlineSize.hasValue())
291 AlwaysInlineSize = getOptionAsInteger(
"ipa-always-inline-size", 3);
292 return AlwaysInlineSize.getValue();
296 if (!MaxInlinableSize.hasValue()) {
298 int DefaultValue = 0;
299 UserModeKind HighLevelMode = getUserMode();
300 switch (HighLevelMode) {
302 llvm_unreachable(
"Invalid mode.");
311 MaxInlinableSize = getOptionAsInteger(
"max-inlinable-size", DefaultValue);
313 return MaxInlinableSize.getValue();
317 if (!GraphTrimInterval.hasValue())
318 GraphTrimInterval = getOptionAsInteger(
"graph-trim-interval", 1000);
319 return GraphTrimInterval.getValue();
323 if (!MaxTimesInlineLarge.hasValue())
324 MaxTimesInlineLarge = getOptionAsInteger(
"max-times-inline-large", 32);
325 return MaxTimesInlineLarge.getValue();
329 if (!MinCFGSizeTreatFunctionsAsLarge.hasValue())
330 MinCFGSizeTreatFunctionsAsLarge = getOptionAsInteger(
331 "min-cfg-size-treat-functions-as-large", 14);
332 return MinCFGSizeTreatFunctionsAsLarge.getValue();
336 if (!MaxNodesPerTopLevelFunction.hasValue()) {
337 int DefaultValue = 0;
338 UserModeKind HighLevelMode = getUserMode();
339 switch (HighLevelMode) {
341 llvm_unreachable(
"Invalid mode.");
343 DefaultValue = 75000;
346 DefaultValue = 225000;
349 MaxNodesPerTopLevelFunction = getOptionAsInteger(
"max-nodes", DefaultValue);
351 return MaxNodesPerTopLevelFunction.getValue();
355 return getBooleanOption(
"faux-bodies",
true);
359 return getBooleanOption(
"prune-paths",
true);
363 return getBooleanOption(
"cfg-conditional-static-initializers",
true);
367 if (!InlineLambdas.hasValue())
368 InlineLambdas = getBooleanOption(
"inline-lambdas",
true);
369 return InlineLambdas.getValue();
373 if (!WidenLoops.hasValue())
374 WidenLoops = getBooleanOption(
"widen-loops",
false);
375 return WidenLoops.getValue();
379 if (!DisplayNotesAsEvents.hasValue())
380 DisplayNotesAsEvents =
381 getBooleanOption(
"notes-as-events",
false);
382 return DisplayNotesAsEvents.getValue();
Inline C functions and blocks when their definitions are available.
bool shouldDisplayNotesAsEvents()
Returns true if the bug reporter should transparently treat extra note diagnostic pieces as event dia...
IPAKind
Describes the different modes of inter-procedural analysis.
bool shouldSuppressNullReturnPaths()
Returns whether or not paths that go through null returns should be suppressed.
bool shouldPrunePaths()
Returns whether irrelevant parts of a bug report path should be pruned out of the final output...
bool shouldAvoidSuppressingNullArgumentPaths()
Returns whether a bug report should not be suppressed if its path includes a call with a null argumen...
bool shouldWidenLoops()
Returns true if the analysis should try to widen loops.
Perform only intra-procedural analysis.
A dummy mode in which no C++ inlining is enabled.
bool mayInlineTemplateFunctions()
Returns whether or not templated functions may be considered for inlining.
Inline callees(C, C++, ObjC) when their definitions are available.
StringRef getOptionAsString(StringRef Name, StringRef DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Query an option's string value.
StringRef getTagDescription() const override
bool mayInlineCXXContainerMethods()
Returns whether or not methods of C++ container objects may be considered for inlining.
static std::vector< StringRef > getRegisteredCheckers(bool IncludeExperimental=false)
bool includeLifetimeInCFG()
Returns whether or not end-of-lifetime information should be included in the CFG. ...
unsigned getMinCFGSizeTreatFunctionsAsLarge()
Returns the number of basic blocks a function needs to have to be considered large for the 'max-times...
detail::InMemoryDirectory::const_iterator I
unsigned getMaxInlinableSize()
UserModeKind getUserMode()
Retrieves and sets the UserMode.
bool shouldSuppressInlinedDefensiveChecks()
Returns whether or not diagnostics containing inlined defensive NULL checks should be suppressed...
bool shouldWriteStableReportFilename()
Returns whether or not the report filename should be random or not.
IPAKind getIPAMode()
Returns the inter-procedural analysis mode.
Refers to regular member function and operator calls.
bool mayInlineObjCMethod()
Returns true if ObjectiveC inlining is enabled, false otherwise.
bool shouldConditionalizeStaticInitializers()
Returns true if 'static' initializers should be in conditional logic in the CFG.
Refers to constructors (implicit or explicit).
Enable inlining of dynamically dispatched methods.
bool getBooleanOption(StringRef Name, bool DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Interprets an option's string value as a boolean.
unsigned getAlwaysInlineSize()
unsigned getMaxNodesPerTopLevelFunction()
Returns the maximum number of nodes the analyzer can generate while exploring a top level function (f...
bool mayInlineCXXStandardLibrary()
Returns whether or not C++ standard library functions may be considered for inlining.
Refers to destructors (implicit or explicit).
unsigned getGraphTrimInterval()
Returns how often nodes in the ExplodedGraph should be recycled to save memory.
detail::InMemoryDirectory::const_iterator E
bool includeTemporaryDtorsInCFG()
Returns whether or not the destructors for C++ temporary objects should be included in the CFG...
bool shouldSuppressFromCXXStandardLibrary()
Returns whether or not diagnostics reported within the C++ standard library should be suppressed...
bool includeImplicitDtorsInCFG()
Returns whether or not implicit destructors for C++ objects should be included in the CFG...
bool shouldSynthesizeBodies()
Returns true if the analyzer engine should synthesize fake bodies for well-known functions.
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K)
Returns the option controlling which C++ member functions will be considered for inlining.
unsigned getMaxTimesInlineLarge()
Returns the maximum times a large function could be inlined.
CXXInlineableMemberKind
Describes the different kinds of C++ member functions which can be considered for inlining by the ana...
int getOptionAsInteger(StringRef Name, int DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Interprets an option's string value as an integer value.
bool mayInlineCXXAllocator()
Returns whether or not allocator call may be considered for inlining.
Enable inlining of dynamically dispatched methods, bifurcate paths when exact type info is unavailabl...
bool mayInlineCXXSharedPtrDtor()
Returns whether or not the destructor of C++ 'shared_ptr' may be considered for inlining.
bool shouldReportIssuesInMainSourceFile()
Returns whether or not the diagnostic report should be always reported in the main source file and no...
bool shouldInlineLambdas()
Returns true if lambdas should be inlined.
static StringRef toString(bool b)