17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/StringMap.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/DynamicLibrary.h"
21#include "llvm/Support/Path.h"
22#include "llvm/Support/raw_ostream.h"
27using namespace checker_registry;
28using llvm::sys::DynamicLibrary;
54 :
Data(
Data), Diags(Diags), AnOpts(AnOpts) {
58#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
59 addChecker(register##CLASS, shouldRegister##CLASS, FULLNAME, HELPTEXT, \
63#define PACKAGE(FULLNAME) addPackage(FULLNAME);
65#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
72 for (
const std::string &Plugin : Plugins) {
76 DynamicLibrary::getPermanentLibrary(Plugin.c_str(), &ErrorMsg);
78 Diags.
Report(diag::err_fe_unable_to_load_plugin) << Plugin << ErrorMsg;
83 const char *PluginAPIVersion =
static_cast<const char *
>(
84 Lib.getAddressOfSymbol(
"clang_analyzerAPIVersionString"));
87 Diags.
Report(diag::warn_incompatible_analyzer_plugin_api)
88 << llvm::sys::path::filename(Plugin);
89 Diags.
Report(diag::note_incompatible_analyzer_plugin_api)
96 RegisterPluginCheckerFn RegisterPluginCheckers =
97 reinterpret_cast<RegisterPluginCheckerFn
>(
98 Lib.getAddressOfSymbol(
"clang_registerCheckers"));
99 if (RegisterPluginCheckers)
100 RegisterPluginCheckers(*
this);
107 for (
const auto &Fn : CheckerRegistrationFns)
117#define GET_CHECKER_DEPENDENCIES
119#define CHECKER_DEPENDENCY(FULLNAME, DEPENDENCY) \
120 addDependency(FULLNAME, DEPENDENCY);
122#define GET_CHECKER_WEAK_DEPENDENCIES
124#define CHECKER_WEAK_DEPENDENCY(FULLNAME, DEPENDENCY) \
125 addWeakDependency(FULLNAME, DEPENDENCY);
127#define GET_CHECKER_OPTIONS
128#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, \
129 DEVELOPMENT_STATUS, IS_HIDDEN) \
130 addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, \
131 DEVELOPMENT_STATUS, IS_HIDDEN);
133#define GET_PACKAGE_OPTIONS
134#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, \
135 DEVELOPMENT_STATUS, IS_HIDDEN) \
136 addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, \
137 DEVELOPMENT_STATUS, IS_HIDDEN);
139#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
140#undef CHECKER_DEPENDENCY
141#undef GET_CHECKER_DEPENDENCIES
142#undef CHECKER_WEAK_DEPENDENCY
143#undef GET_CHECKER_WEAK_DEPENDENCIES
145#undef GET_CHECKER_OPTIONS
147#undef GET_PACKAGE_OPTIONS
149 resolveDependencies<true>();
150 resolveDependencies<false>();
153 for (
auto &DepPair :
Data.Dependencies) {
154 for (
auto &WeakDepPair :
Data.WeakDependencies) {
158 assert(WeakDepPair != DepPair &&
159 "A checker cannot strong and weak depend on the same checker!");
160 assert(WeakDepPair.first != DepPair.second &&
161 "A strong dependency mustn't have weak dependencies!");
162 assert(WeakDepPair.second != DepPair.second &&
163 "A strong dependency mustn't be a weak dependency as well!");
168 resolveCheckerAndPackageOptions();
174 Data.getMutableCheckersForCmdLineArg(Opt.first);
176 if (CheckerForCmdLineArg.begin() == CheckerForCmdLineArg.end()) {
177 Diags.
Report(diag::err_unknown_analyzer_checker_or_package) << Opt.first;
178 Diags.
Report(diag::note_suggest_disabling_all_checkers);
181 for (
CheckerInfo &checker : CheckerForCmdLineArg) {
182 checker.State = Opt.second ? StateFromCmdLine::State_Enabled
183 : StateFromCmdLine::State_Disabled;
193template <
typename IsEnabledFn>
197 IsEnabledFn IsEnabled);
200template <
typename IsEnabledFn>
212 return !
Checker->isDisabled(Mgr);
220 IsEnabledFromCmdLine)) {
226 Tmp.insert(Deps.begin(), Deps.end());
247 IsEnabledFromCmdLine)) {
254 Data.EnabledCheckers.set_union(Deps);
259template <
typename IsEnabledFn>
263 IsEnabledFn IsEnabled) {
266 if (!IsEnabled(Dependency))
273 Ret.insert(Dependency);
279template <
typename IsEnabledFn>
283 IsEnabledFn IsEnabled) {