]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / StaticAnalyzer / Core / AnalyzerOptions.cpp
1 //===- AnalyzerOptions.cpp - Analysis Engine Options ----------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains special accessors for analyzer configuration options
11 // with string representations.
12 //
13 //===----------------------------------------------------------------------===//
14
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"
24 #include <cassert>
25 #include <cstddef>
26 #include <utility>
27 #include <vector>
28
29 using namespace clang;
30 using namespace ento;
31 using namespace llvm;
32
33 std::vector<StringRef>
34 AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) {
35   static const StringRef StaticAnalyzerChecks[] = {
36 #define GET_CHECKERS
37 #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI)                            \
38   FULLNAME,
39 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
40 #undef CHECKER
41 #undef GET_CHECKERS
42   };
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);
48   }
49   return Result;
50 }
51
52 ExplorationStrategyKind
53 AnalyzerOptions::getExplorationStrategy() const {
54   auto K =
55     llvm::StringSwitch<llvm::Optional<ExplorationStrategyKind>>(
56                                                             ExplorationStrategy)
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)
67           .Default(None);
68   assert(K.hasValue() && "User mode is invalid.");
69   return K.getValue();
70 }
71
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)
79           .Default(None);
80   assert(K.hasValue() && "IPA Mode is invalid.");
81
82   return K.getValue();
83 }
84
85 bool
86 AnalyzerOptions::mayInlineCXXMemberFunction(
87                                           CXXInlineableMemberKind Param) const {
88   if (getIPAMode() < IPAK_Inlining)
89     return false;
90
91   auto K =
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)
98     .Default(None);
99
100   assert(K.hasValue() && "Invalid c++ member function inlining mode.");
101
102   return *K >= Param;
103 }
104
105 StringRef AnalyzerOptions::getCheckerStringOption(StringRef OptionName,
106                                                   StringRef DefaultVal,
107                                                   const CheckerBase *C,
108                                                   bool SearchInParents) const {
109   assert(C);
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();
113
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();
118   do {
119     ConfigTable::const_iterator I =
120         Config.find((Twine(CheckerName) + ":" + OptionName).str());
121     if (I != E)
122       return StringRef(I->getValue());
123     size_t Pos = CheckerName.rfind('.');
124     if (Pos == StringRef::npos)
125       return DefaultVal;
126     CheckerName = CheckerName.substr(0, Pos);
127   } while (!CheckerName.empty() && SearchInParents);
128   return DefaultVal;
129 }
130
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.
137   assert(C);
138   return llvm::StringSwitch<bool>(
139       getCheckerStringOption(Name, DefaultVal ? "true" : "false", C,
140                              SearchInParents))
141       .Case("true", true)
142       .Case("false", false)
143       .Default(DefaultVal);
144 }
145
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,
151                                           SearchInParents)
152                      .getAsInteger(10, Ret);
153   assert(!HasFailed && "analyzer-config option should be numeric");
154   (void)HasFailed;
155   return Ret;
156 }