Skip to content

Commit 04bfbf1

Browse files
committed
Provide a simplified interface for plugins defining checkers
1 parent 84eb5af commit 04bfbf1

File tree

4 files changed

+38
-51
lines changed

4 files changed

+38
-51
lines changed

clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,18 @@
3939
//
4040
// extern "C"
4141
// void clang_registerCheckers(CheckerRegistry &Registry) {
42-
// Registry.addChecker(
43-
// registerMainCallChecker,
44-
// shouldRegisterMainCallChecker,
42+
// Registry.addChecker<MainCallChecker>(
4543
// "example.MainCallChecker",
46-
// "MainCallChecker",
47-
// "Example Description",
48-
// "example.mychecker.documentation.nonexistent.html",
49-
// /*isHidden=*/ false);
44+
// "Example Description");
5045
// }
5146
//
52-
// The first two arguments are the registration handling functions, which
53-
// in a simple case look like
47+
// The first argument of this templated method is the full name of the checker
48+
// (including its package), while the second argument is a short description
49+
// that is printed by `-analyzer-checker-help`.
5450
//
55-
// void registerMainCallChecker(CheckerManager &Mgr) {
56-
// Mgr.registerChecker<MainCallChecker>();
57-
// }
58-
//
59-
// bool shouldRegisterMainCallChecker(const CheckerManager &) {
60-
// return true;
61-
// }
62-
//
63-
// The third argument is the full name of the checker (including its package),
64-
// the fourth name is the internal DebugName (by convention, the name of the
65-
// class), the fifth argument is a short documentation, the sixth argument is
66-
// an url to a documentation page, and the seventh argument should be false for
67-
// normal user-facing checkers.
51+
// If a checker requires custom registration functions (e.g. checker option
52+
// handling) use the non-templated variant of `addChecker` that takes two
53+
// callback functions as the first two parameters.
6854
//
6955
// To load a checker plugin, specify the full path to the dynamic library as
7056
// the argument to the -load option in the cc1 frontend. You can then enable
@@ -73,7 +59,7 @@
7359
// clang -cc1 -load </path/to/plugin.dylib> -analyze
7460
// -analyzer-checker=<example.MainCallChecker>
7561
//
76-
// For a complete example, see clang/lib/Analysis/plugins/SampleAnalyzer
62+
// For complete examples, see clang/lib/Analysis/plugins/SampleAnalyzer
7763

7864
#ifndef CLANG_ANALYZER_API_VERSION_STRING
7965
// FIXME: The Clang version string is not particularly granular;
@@ -125,20 +111,34 @@ class CheckerRegistry {
125111
return true;
126112
}
127113

128-
public:
129-
/// Adds a checker to the registry. Use this non-templated overload when your
130-
/// checker requires custom initialization.
114+
/// Adds a checker to the registry. This private, most general variant is
115+
/// intended for loading the checker definitions from `Checkers.td`.
116+
/// FIXME: DocsUri is never loaded from the checker registry.
131117
void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction Sfn,
132118
StringRef FullName, StringRef DebugName, StringRef Desc,
133119
StringRef DocsUri, bool IsHidden);
134120

121+
public:
122+
/// Adds a checker to the registry. Use this for a checker defined in a
123+
/// plugin if it requires custom registration functions.
124+
void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction Sfn,
125+
StringRef FullName, StringRef Desc, bool IsHidden = false) {
126+
addChecker(Fn, Sfn, FullName, "CheckerFromPlugin", Desc, "", IsHidden);
127+
}
128+
129+
/// Adds a checker to the registry. Use this for a checker defined in a
130+
/// plugin if it doesn't require custom registration functions.
131+
template <class T>
132+
void addChecker(StringRef FullName, StringRef Desc, bool IsHidden = false) {
133+
addChecker(&CheckerRegistry::initializeManager<CheckerManager, T>,
134+
&CheckerRegistry::returnTrue<T>, FullName, Desc,
135+
/*IsHidden=*/IsHidden);
136+
}
137+
135138
/// Add a mock checker to the registry for testing purposes, without
136139
/// specifying metadata that is not relevant in simple tests.
137140
template <class T> void addMockChecker(StringRef FullName) {
138-
addChecker(&CheckerRegistry::initializeManager<CheckerManager, T>,
139-
&CheckerRegistry::returnTrue<T>, FullName,
140-
/*DebugName=*/"TestChecker", /*Desc=*/"", /*DocsUri=*/"",
141-
/*IsHidden=*/false);
141+
addChecker<T>(FullName, "");
142142
}
143143

144144
/// Makes the checker with the full name \p fullName depend on the checker

clang/lib/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ bool shouldRegisterMyChecker(const CheckerManager &mgr) { return true; }
3131
// Register plugin!
3232
extern "C" void clang_registerCheckers(CheckerRegistry &Registry) {
3333
Registry.addChecker(registerMyChecker, shouldRegisterMyChecker,
34-
"example.MyChecker", "MyChecker", "Example Description",
35-
"example.mychecker.documentation.nonexistent.html",
36-
/*isHidden*/ false);
34+
"example.MyChecker", "Example Description");
3735

3836
Registry.addCheckerOption(/*OptionType*/ "bool",
3937
/*CheckerFullName*/ "example.MyChecker",

clang/lib/Analysis/plugins/SampleAnalyzer/MainCallChecker.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,6 @@ class MainCallChecker : public Checker<check::PreStmt<CallExpr>> {
1717
public:
1818
void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
1919
};
20-
21-
void registerMainCallChecker(CheckerManager &Mgr) {
22-
Mgr.registerChecker<MainCallChecker>();
23-
}
24-
25-
bool shouldRegisterMainCallChecker(const CheckerManager &) { return true; }
2620
} // end anonymous namespace
2721

2822
void MainCallChecker::checkPreStmt(const CallExpr *CE,
@@ -52,11 +46,8 @@ void MainCallChecker::checkPreStmt(const CallExpr *CE,
5246

5347
// Register plugin!
5448
extern "C" void clang_registerCheckers(CheckerRegistry &Registry) {
55-
Registry.addChecker(registerMainCallChecker, shouldRegisterMainCallChecker,
56-
"example.MainCallChecker", "MainCallChecker",
57-
"Example Description",
58-
"example.mychecker.documentation.nonexistent.html",
59-
/*isHidden=*/false);
49+
Registry.addChecker<MainCallChecker>("example.MainCallChecker",
50+
"Example Description");
6051
}
6152

6253
extern "C" const char clang_analyzerAPIVersionString[] =

clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,9 @@ bool shouldRegisterCheckerRegistrationOrderPrinter(const CheckerManager &mgr) {
116116
}
117117

118118
void addCheckerRegistrationOrderPrinter(CheckerRegistry &Registry) {
119-
Registry.addChecker(
120-
registerCheckerRegistrationOrderPrinter,
121-
shouldRegisterCheckerRegistrationOrderPrinter, "test.RegistrationOrder",
122-
"CheckerRegistrationOrderPrinter", "Description", "", false);
119+
Registry.addChecker(registerCheckerRegistrationOrderPrinter,
120+
shouldRegisterCheckerRegistrationOrderPrinter,
121+
"test.RegistrationOrder", "Description");
123122
}
124123

125124
#define UNITTEST_CHECKER(CHECKER_NAME, DIAG_MSG) \
@@ -137,8 +136,7 @@ void addCheckerRegistrationOrderPrinter(CheckerRegistry &Registry) {
137136
} \
138137
void add##CHECKER_NAME(CheckerRegistry &Registry) { \
139138
Registry.addChecker(register##CHECKER_NAME, shouldRegister##CHECKER_NAME, \
140-
"test." #CHECKER_NAME, #CHECKER_NAME, "Description", \
141-
"", false); \
139+
"test." #CHECKER_NAME, "Description"); \
142140
}
143141

144142
UNITTEST_CHECKER(StrongDep, "Strong")
@@ -155,7 +153,7 @@ void addDep(AnalysisASTConsumer &AnalysisConsumer,
155153
{"test.RegistrationOrder", true}};
156154
AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
157155
Registry.addChecker(registerStrongDep, shouldRegisterStrongFALSE,
158-
"test.Strong", "StrongDep", "Description", "", false);
156+
"test.Strong", "Description");
159157
addStrongDep(Registry);
160158
addDep(Registry);
161159
addCheckerRegistrationOrderPrinter(Registry);

0 commit comments

Comments
 (0)