1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | #ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H |
10 | #define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H |
11 | |
12 | #include "clang/Basic/LLVM.h" |
13 | #include "clang/StaticAnalyzer/Core/CheckerManager.h" |
14 | #include "llvm/ADT/StringMap.h" |
15 | #include "llvm/ADT/StringRef.h" |
16 | #include <cstddef> |
17 | #include <vector> |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | #ifndef CLANG_ANALYZER_API_VERSION_STRING |
60 | |
61 | |
62 | |
63 | |
64 | #include "clang/Basic/Version.h" |
65 | #define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING |
66 | #endif |
67 | |
68 | namespace clang { |
69 | |
70 | class AnalyzerOptions; |
71 | class DiagnosticsEngine; |
72 | class LangOptions; |
73 | |
74 | namespace ento { |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | class CheckerRegistry { |
83 | public: |
84 | CheckerRegistry( |
85 | ArrayRef<std::string> plugins, DiagnosticsEngine &diags, |
86 | AnalyzerOptions &AnOpts, const LangOptions &LangOpts, |
87 | ArrayRef<std::function<void(CheckerRegistry &)>> |
88 | checkerRegistrationFns = {}); |
89 | |
90 | |
91 | |
92 | using InitializationFunction = void (*)(CheckerManager &); |
93 | using ShouldRegisterFunction = bool (*)(const LangOptions &); |
94 | |
95 | struct CheckerInfo; |
96 | |
97 | using CheckerInfoList = std::vector<CheckerInfo>; |
98 | using CheckerInfoListRange = llvm::iterator_range<CheckerInfoList::iterator>; |
99 | using ConstCheckerInfoList = llvm::SmallVector<const CheckerInfo *, 0>; |
100 | using CheckerInfoSet = llvm::SetVector<const CheckerInfo *>; |
101 | |
102 | struct CheckerInfo { |
103 | enum class StateFromCmdLine { |
104 | |
105 | State_Unspecified, |
106 | |
107 | State_Disabled, |
108 | |
109 | State_Enabled |
110 | }; |
111 | |
112 | InitializationFunction Initialize; |
113 | ShouldRegisterFunction ShouldRegister; |
114 | StringRef FullName; |
115 | StringRef Desc; |
116 | StringRef DocumentationUri; |
117 | StateFromCmdLine State = StateFromCmdLine::State_Unspecified; |
118 | |
119 | ConstCheckerInfoList Dependencies; |
120 | |
121 | bool isEnabled(const LangOptions &LO) const { |
122 | return State == StateFromCmdLine::State_Enabled && ShouldRegister(LO); |
123 | } |
124 | |
125 | bool isDisabled(const LangOptions &LO) const { |
126 | return State == StateFromCmdLine::State_Disabled && ShouldRegister(LO); |
127 | } |
128 | |
129 | CheckerInfo(InitializationFunction Fn, ShouldRegisterFunction sfn, |
130 | StringRef Name, StringRef Desc, StringRef DocsUri) |
131 | : Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc), |
132 | DocumentationUri(DocsUri) {} |
133 | }; |
134 | |
135 | using StateFromCmdLine = CheckerInfo::StateFromCmdLine; |
136 | |
137 | private: |
138 | template <typename T> |
139 | static void initializeManager(CheckerManager &mgr) { |
140 | mgr.registerChecker<T>(); |
141 | } |
142 | |
143 | |
144 | template <typename T> |
145 | static bool returnTrue(const LangOptions &LO) { |
146 | return true; |
147 | } |
148 | |
149 | public: |
150 | |
151 | |
152 | void addChecker(InitializationFunction Fn, ShouldRegisterFunction sfn, |
153 | StringRef FullName, StringRef Desc, StringRef DocsUri); |
154 | |
155 | |
156 | |
157 | template <class T> |
158 | void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri) { |
159 | |
160 | |
161 | addChecker(&CheckerRegistry::initializeManager<T>, |
162 | &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri); |
163 | } |
164 | |
165 | |
166 | |
167 | void addDependency(StringRef fullName, StringRef dependency) { |
168 | auto CheckerThatNeedsDeps = |
169 | [&fullName](const CheckerInfo &Chk) { return Chk.FullName == fullName; }; |
170 | auto Dependency = |
171 | [&dependency](const CheckerInfo &Chk) { |
172 | return Chk.FullName == dependency; |
173 | }; |
174 | |
175 | auto CheckerIt = llvm::find_if(Checkers, CheckerThatNeedsDeps); |
176 | (0) . __assert_fail ("CheckerIt != Checkers.end() && \"Failed to find the checker while attempting to set up it's \" \"dependencies!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h", 178, __PRETTY_FUNCTION__))" file_link="../../../../../include/assert.h.html#88" macro="true">assert(CheckerIt != Checkers.end() && |
177 | (0) . __assert_fail ("CheckerIt != Checkers.end() && \"Failed to find the checker while attempting to set up it's \" \"dependencies!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h", 178, __PRETTY_FUNCTION__))" file_link="../../../../../include/assert.h.html#88" macro="true"> "Failed to find the checker while attempting to set up it's " |
178 | (0) . __assert_fail ("CheckerIt != Checkers.end() && \"Failed to find the checker while attempting to set up it's \" \"dependencies!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h", 178, __PRETTY_FUNCTION__))" file_link="../../../../../include/assert.h.html#88" macro="true"> "dependencies!"); |
179 | |
180 | auto DependencyIt = llvm::find_if(Checkers, Dependency); |
181 | (0) . __assert_fail ("DependencyIt != Checkers.end() && \"Failed to find the dependency of a checker!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h", 182, __PRETTY_FUNCTION__))" file_link="../../../../../include/assert.h.html#88" macro="true">assert(DependencyIt != Checkers.end() && |
182 | (0) . __assert_fail ("DependencyIt != Checkers.end() && \"Failed to find the dependency of a checker!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h", 182, __PRETTY_FUNCTION__))" file_link="../../../../../include/assert.h.html#88" macro="true"> "Failed to find the dependency of a checker!"); |
183 | |
184 | CheckerIt->Dependencies.push_back(&*DependencyIt); |
185 | } |
186 | |
187 | |
188 | |
189 | |
190 | |
191 | |
192 | void initializeManager(CheckerManager &mgr) const; |
193 | |
194 | |
195 | void validateCheckerOptions() const; |
196 | |
197 | |
198 | |
199 | void printHelp(raw_ostream &out, size_t maxNameChars = 30) const; |
200 | void printList(raw_ostream &out) const; |
201 | |
202 | private: |
203 | |
204 | |
205 | |
206 | CheckerInfoSet getEnabledCheckers() const; |
207 | |
208 | |
209 | |
210 | |
211 | CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg); |
212 | |
213 | CheckerInfoList Checkers; |
214 | llvm::StringMap<size_t> Packages; |
215 | |
216 | DiagnosticsEngine &Diags; |
217 | AnalyzerOptions &AnOpts; |
218 | const LangOptions &LangOpts; |
219 | }; |
220 | |
221 | } |
222 | |
223 | } |
224 | |
225 | #endif |
226 | |