clang 19.0.0git
CheckerRegistry.h
Go to the documentation of this file.
1//===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Contains the logic for parsing the TableGen file Checkers.td, and parsing the
10// specific invocation of the analyzer (which checker/package is enabled, values
11// of their options, etc). This is in the frontend library because checker
12// registry functions are called from here but are defined in the dependent
13// library libStaticAnalyzerCheckers, but the actual data structure that holds
14// the parsed information is in the Core library.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H
19#define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H
20
21#include "clang/Basic/LLVM.h"
23#include "llvm/ADT/StringRef.h"
24
25// FIXME: move this information to an HTML file in docs/.
26// At the very least, a checker plugin is a dynamic library that exports
27// clang_analyzerAPIVersionString. This should be defined as follows:
28//
29// extern "C"
30// const char clang_analyzerAPIVersionString[] =
31// CLANG_ANALYZER_API_VERSION_STRING;
32//
33// This is used to check whether the current version of the analyzer is known to
34// be incompatible with a plugin. Plugins with incompatible version strings,
35// or without a version string at all, will not be loaded.
36//
37// To add a custom checker to the analyzer, the plugin must also define the
38// function clang_registerCheckers. For example:
39//
40// extern "C"
41// void clang_registerCheckers (CheckerRegistry &registry) {
42// registry.addChecker<MainCallChecker>("example.MainCallChecker",
43// "Disallows calls to functions called main");
44// }
45//
46// The first method argument is the full name of the checker, including its
47// enclosing package. By convention, the registered name of a checker is the
48// name of the associated class (the template argument).
49// The second method argument is a short human-readable description of the
50// checker.
51//
52// The clang_registerCheckers function may add any number of checkers to the
53// registry. If any checkers require additional initialization, use the three-
54// argument form of CheckerRegistry::addChecker.
55//
56// To load a checker plugin, specify the full path to the dynamic library as
57// the argument to the -load option in the cc1 frontend. You can then enable
58// your custom checker using the -analyzer-checker:
59//
60// clang -cc1 -load </path/to/plugin.dylib> -analyze
61// -analyzer-checker=<example.MainCallChecker>
62//
63// For a complete working example, see examples/analyzer-plugin.
64
65#ifndef CLANG_ANALYZER_API_VERSION_STRING
66// FIXME: The Clang version string is not particularly granular;
67// the analyzer infrastructure can change a lot between releases.
68// Unfortunately, this string has to be statically embedded in each plugin,
69// so we can't just use the functions defined in Version.h.
70#include "clang/Basic/Version.h"
71#define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING
72#endif
73
74namespace clang {
75
76class AnalyzerOptions;
77class DiagnosticsEngine;
78
79namespace ento {
80
81class CheckerManager;
82
83/// Manages a set of available checkers for running a static analysis.
84/// The checkers are organized into packages by full name, where including
85/// a package will recursively include all subpackages and checkers within it.
86/// For example, the checker "core.builtin.NoReturnFunctionChecker" will be
87/// included if initializeManager() is called with an option of "core",
88/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
90public:
92 DiagnosticsEngine &Diags, AnalyzerOptions &AnOpts,
93 ArrayRef<std::function<void(CheckerRegistry &)>>
94 CheckerRegistrationFns = {});
95
96 /// Collects all enabled checkers in the field EnabledCheckers. It preserves
97 /// the order of insertion, as dependencies have to be enabled before the
98 /// checkers that depend on them.
99 void initializeRegistry(const CheckerManager &Mgr);
100
101
102private:
103 /// Default initialization function for checkers -- since CheckerManager
104 /// includes this header, we need to make it a template parameter, and since
105 /// the checker must be a template parameter as well, we can't put this in the
106 /// cpp file.
107 template <typename MGR, typename T> static void initializeManager(MGR &mgr) {
108 mgr.template registerChecker<T>();
109 }
110
111 template <typename T> static bool returnTrue(const CheckerManager &mgr) {
112 return true;
113 }
114
115public:
116 /// Adds a checker to the registry. Use this non-templated overload when your
117 /// checker requires custom initialization.
119 StringRef FullName, StringRef Desc, StringRef DocsUri,
120 bool IsHidden);
121
122 /// Adds a checker to the registry. Use this templated overload when your
123 /// checker does not require any custom initialization.
124 /// This function isn't really needed and probably causes more headaches than
125 /// the tiny convenience that it provides, but external plugins might use it,
126 /// and there isn't a strong incentive to remove it.
127 template <class T>
128 void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri,
129 bool IsHidden = false) {
130 // Avoid MSVC's Compiler Error C2276:
131 // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
132 addChecker(&CheckerRegistry::initializeManager<CheckerManager, T>,
133 &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri,
134 IsHidden);
135 }
136
137 /// Makes the checker with the full name \p fullName depend on the checker
138 /// called \p dependency.
139 void addDependency(StringRef FullName, StringRef Dependency);
140
141 /// Makes the checker with the full name \p fullName weak depend on the
142 /// checker called \p dependency.
143 void addWeakDependency(StringRef FullName, StringRef Dependency);
144
145 /// Registers an option to a given checker. A checker option will always have
146 /// the following format:
147 /// CheckerFullName:OptionName=Value
148 /// And can be specified from the command line like this:
149 /// -analyzer-config CheckerFullName:OptionName=Value
150 ///
151 /// Options for unknown checkers, or unknown options for a given checker, or
152 /// invalid value types for that given option are reported as an error in
153 /// non-compatibility mode.
154 void addCheckerOption(StringRef OptionType, StringRef CheckerFullName,
155 StringRef OptionName, StringRef DefaultValStr,
156 StringRef Description, StringRef DevelopmentStatus,
157 bool IsHidden = false);
158
159 /// Adds a package to the registry.
160 void addPackage(StringRef FullName);
161
162 /// Registers an option to a given package. A package option will always have
163 /// the following format:
164 /// PackageFullName:OptionName=Value
165 /// And can be specified from the command line like this:
166 /// -analyzer-config PackageFullName:OptionName=Value
167 ///
168 /// Options for unknown packages, or unknown options for a given package, or
169 /// invalid value types for that given option are reported as an error in
170 /// non-compatibility mode.
171 void addPackageOption(StringRef OptionType, StringRef PackageFullName,
172 StringRef OptionName, StringRef DefaultValStr,
173 StringRef Description, StringRef DevelopmentStatus,
174 bool IsHidden = false);
175
176 // FIXME: This *really* should be added to the frontend flag descriptions.
177 /// Initializes a CheckerManager by calling the initialization functions for
178 /// all checkers specified by the given CheckerOptInfo list. The order of this
179 /// list is significant; later options can be used to reverse earlier ones.
180 /// This can be used to exclude certain checkers in an included package.
181 void initializeManager(CheckerManager &CheckerMgr) const;
182
183 /// Check if every option corresponds to a specific checker or package.
184 void validateCheckerOptions() const;
185
186private:
187 template <bool IsWeak> void resolveDependencies();
188 void resolveCheckerAndPackageOptions();
189
191
192 DiagnosticsEngine &Diags;
193 AnalyzerOptions &AnOpts;
194};
195
196} // namespace ento
197} // namespace clang
198
199#endif // LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
const char * Data
Defines version macros and version-related utility functions for Clang.
Stores options for the analyzer from the command line.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
Manages a set of available checkers for running a static analysis.
void addCheckerOption(StringRef OptionType, StringRef CheckerFullName, StringRef OptionName, StringRef DefaultValStr, StringRef Description, StringRef DevelopmentStatus, bool IsHidden=false)
Registers an option to a given checker.
void addWeakDependency(StringRef FullName, StringRef Dependency)
Makes the checker with the full name fullName weak depend on the checker called dependency.
void addPackageOption(StringRef OptionType, StringRef PackageFullName, StringRef OptionName, StringRef DefaultValStr, StringRef Description, StringRef DevelopmentStatus, bool IsHidden=false)
Registers an option to a given package.
void initializeRegistry(const CheckerManager &Mgr)
Collects all enabled checkers in the field EnabledCheckers.
void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction sfn, StringRef FullName, StringRef Desc, StringRef DocsUri, bool IsHidden)
Adds a checker to the registry.
void addPackage(StringRef FullName)
Adds a package to the registry.
void validateCheckerOptions() const
Check if every option corresponds to a specific checker or package.
void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri, bool IsHidden=false)
Adds a checker to the registry.
void addDependency(StringRef FullName, StringRef Dependency)
Makes the checker with the full name fullName depend on the checker called dependency.
bool(*)(const CheckerManager &) ShouldRegisterFunction
void(*)(CheckerManager &) RegisterCheckerFn
Initialization functions perform any necessary setup for a checker.
The JSON file list parser is used to communicate input to InstallAPI.