17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/ADT/SetVector.h" 19 #include "llvm/ADT/StringMap.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/Support/DynamicLibrary.h" 22 #include "llvm/Support/Path.h" 23 #include "llvm/Support/raw_ostream.h" 26 using namespace clang;
28 using llvm::sys::DynamicLibrary;
45 #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI) \ 46 addChecker(register##CLASS, FULLNAME, HELPTEXT, DOC_URI); 47 #include "clang/StaticAnalyzer/Checkers/Checkers.inc" 55 DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err);
57 diags.
Report(diag::err_fe_unable_to_load_plugin) << *i << err;
62 const char *pluginAPIVersion =
63 (
const char *) lib.getAddressOfSymbol(
"clang_analyzerAPIVersionString");
65 Diags.
Report(diag::warn_incompatible_analyzer_plugin_api)
66 << llvm::sys::path::filename(*i);
67 Diags.
Report(diag::note_incompatible_analyzer_plugin_api)
76 "clang_registerCheckers");
77 if (registerPluginCheckers)
78 registerPluginCheckers(*
this);
85 const CheckerRegistry::CheckerInfo &b) {
86 return a.FullName < b.FullName;
89 static bool isInPackage(
const CheckerRegistry::CheckerInfo &checker,
90 StringRef packageName) {
92 if (!checker.FullName.startswith(packageName))
96 if (checker.FullName.size() == packageName.size())
109 assert(std::is_sorted(Checkers.begin(), Checkers.end(),
checkerNameLT) &&
110 "In order to efficiently gather checkers, this function expects them " 111 "to be already sorted!");
114 const auto end = Checkers.cend();
118 CheckerRegistry::CheckerInfo packageInfo(
nullptr, opt.first,
"",
"");
119 auto firstRelatedChecker =
120 std::lower_bound(Checkers.cbegin(), end, packageInfo,
checkerNameLT);
122 if (firstRelatedChecker == end ||
124 Diags.
Report(diag::err_unknown_analyzer_checker) << opt.first;
125 Diags.
Report(diag::note_suggest_disabling_all_checkers);
133 llvm::StringMap<size_t>::const_iterator packageSize =
134 Packages.find(opt.first);
135 if (packageSize != Packages.end())
136 size = packageSize->getValue();
139 for (
auto lastRelatedChecker = firstRelatedChecker+size;
140 firstRelatedChecker != lastRelatedChecker; ++firstRelatedChecker)
142 enabledCheckers.insert(&*firstRelatedChecker);
144 enabledCheckers.remove(&*firstRelatedChecker);
147 return enabledCheckers;
151 StringRef Desc, StringRef DocsUri) {
152 Checkers.emplace_back(Fn, Name, Desc, DocsUri);
155 StringRef packageName, leafName;
157 while (!leafName.empty()) {
158 Packages[packageName] += 1;
163 void CheckerRegistry::initializeManager(CheckerManager &checkerMgr,
172 for (
const auto *i : enabledCheckers) {
173 checkerMgr.setCurrentCheckName(CheckName(i->FullName));
174 i->Initialize(checkerMgr);
180 for (
const auto &config : opts.
Config) {
181 size_t pos = config.getKey().find(
':');
182 if (pos == StringRef::npos)
185 bool hasChecker =
false;
186 StringRef checkerName = config.getKey().substr(0, pos);
187 for (
const auto &checker : Checkers) {
188 if (checker.FullName.startswith(checkerName) &&
189 (checker.FullName.size() == pos || checker.FullName[pos] ==
'.')) {
195 Diags.
Report(diag::err_unknown_analyzer_checker) << checkerName;
200 size_t maxNameChars)
const {
208 out <<
"CHECKERS:\n";
211 size_t optionFieldWidth = 0;
212 for (
const auto &i : Checkers) {
215 size_t nameLength = i.FullName.size();
216 if (nameLength <= maxNameChars)
217 optionFieldWidth =
std::max(optionFieldWidth, nameLength);
220 const size_t initialPad = 2;
221 for (
const auto &i : Checkers) {
222 out.indent(initialPad) << i.FullName;
224 int pad = optionFieldWidth - i.FullName.size();
229 pad = optionFieldWidth + initialPad;
231 out.indent(pad + 2) << i.Desc;
245 for (
const auto *i : enabledCheckers)
246 out << i->FullName <<
'\n';
llvm::SetVector< const CheckerRegistry::CheckerInfo * > CheckerInfoSet
void printList(raw_ostream &out, const AnalyzerOptions &opts) const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
#define CLANG_ANALYZER_API_VERSION_STRING
static bool isCompatibleAPIVersion(const char *versionString)
CheckerRegistry(ArrayRef< std::string > plugins, DiagnosticsEngine &diags)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
Concrete class used by the front-end to report problems and issues.
Defines the Diagnostic-related interfaces.
std::vector< std::pair< std::string, bool > > CheckersControlList
Pair of checker name and enable/disable.
__INTPTR_TYPE__ intptr_t
A signed integer type with the property that any valid pointer to void can be converted to this type...
void(*)(CheckerRegistry &) RegisterCheckersFn
void validateCheckerOptions(const AnalyzerOptions &opts) const
Check if every option corresponds to a specific checker or package.
void addChecker(InitializationFunction Fn, StringRef FullName, StringRef Desc, StringRef DocsUri)
Adds a checker to the registry.
ConfigTable Config
A key-value table of use-specified configuration values.
Dataflow Directional Tag Classes.
void(*)(CheckerManager &) InitializationFunction
Initialization functions perform any necessary setup for a checker.
static bool checkerNameLT(const CheckerRegistry::CheckerInfo &a, const CheckerRegistry::CheckerInfo &b)
Stores options for the analyzer from the command line.
void printHelp(raw_ostream &out, size_t maxNameChars=30) const
Prints the name and description of all checkers in this registry.
__DEVICE__ int max(int __a, int __b)
static bool isInPackage(const CheckerRegistry::CheckerInfo &checker, StringRef packageName)
static constexpr char PackageSeparator