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 
74 namespace clang {
75 
76 class AnalyzerOptions;
77 class DiagnosticsEngine;
78 
79 namespace ento {
80 
81 class 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".
90 public:
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 
102 private:
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 
115 public:
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 
186 private:
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:193
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.
CheckerRegistry(CheckerRegistryData &Data, ArrayRef< std::string > Plugins, DiagnosticsEngine &Diags, AnalyzerOptions &AnOpts, ArrayRef< std::function< void(CheckerRegistry &)>> CheckerRegistrationFns={})
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.