Skip to content

Commit b0be2ab

Browse files
committedDec 15, 2018
[analyzer][NFC] Merge ClangCheckerRegistry to CheckerRegistry
Now that CheckerRegistry lies in Frontend, we can finally eliminate ClangCheckerRegistry. Fortunately, this also provides us with a DiagnosticsEngine, so I went ahead and removed some parameters from it's methods. Differential Revision: https://reviews.llvm.org/D54437 llvm-svn: 349280
1 parent 22163d8 commit b0be2ab

File tree

5 files changed

+86
-109
lines changed

5 files changed

+86
-109
lines changed
 

Diff for: ‎clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ namespace ento {
8181
/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
8282
class CheckerRegistry {
8383
public:
84+
CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags);
85+
8486
/// Initialization functions perform any necessary setup for a checker.
8587
/// They should include a call to CheckerManager::registerChecker.
8688
using InitializationFunction = void (*)(CheckerManager &);
@@ -122,25 +124,23 @@ class CheckerRegistry {
122124
/// all checkers specified by the given CheckerOptInfo list. The order of this
123125
/// list is significant; later options can be used to reverse earlier ones.
124126
/// This can be used to exclude certain checkers in an included package.
125-
void initializeManager(CheckerManager &mgr, const AnalyzerOptions &Opts,
126-
DiagnosticsEngine &diags) const;
127+
void initializeManager(CheckerManager &mgr,
128+
const AnalyzerOptions &Opts) const;
127129

128130
/// Check if every option corresponds to a specific checker or package.
129-
void validateCheckerOptions(const AnalyzerOptions &opts,
130-
DiagnosticsEngine &diags) const;
131+
void validateCheckerOptions(const AnalyzerOptions &opts) const;
131132

132133
/// Prints the name and description of all checkers in this registry.
133134
/// This output is not intended to be machine-parseable.
134135
void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
135-
void printList(raw_ostream &out, const AnalyzerOptions &opts,
136-
DiagnosticsEngine &diags) const;
136+
void printList(raw_ostream &out, const AnalyzerOptions &opts) const;
137137

138138
private:
139-
CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts,
140-
DiagnosticsEngine &diags) const;
139+
CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts) const;
141140

142141
mutable CheckerInfoList Checkers;
143142
mutable llvm::StringMap<size_t> Packages;
143+
DiagnosticsEngine &Diags;
144144
};
145145

146146
} // namespace ento

Diff for: ‎clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ class ParseModelFileAction : public ASTFrontendAction {
5252
llvm::StringMap<Stmt *> &Bodies;
5353
};
5454

55-
void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
55+
void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins,
56+
DiagnosticsEngine &diags);
5657
void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins,
5758
const AnalyzerOptions &opts,
5859
DiagnosticsEngine &diags);

Diff for: ‎clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
238238
// Honor -analyzer-checker-help.
239239
// This should happen AFTER plugins have been loaded!
240240
if (Clang->getAnalyzerOpts()->ShowCheckerHelp) {
241-
ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins);
241+
ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins,
242+
Clang->getDiagnostics());
242243
return true;
243244
}
244245

Diff for: ‎clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp

+7-86
Original file line numberDiff line numberDiff line change
@@ -16,95 +16,15 @@
1616
#include "clang/Frontend/FrontendDiagnostic.h"
1717
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
1818
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
19-
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
2019
#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
2120
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
2221
#include "llvm/ADT/SmallVector.h"
23-
#include "llvm/Support/DynamicLibrary.h"
2422
#include "llvm/Support/FormattedStream.h"
25-
#include "llvm/Support/Path.h"
2623
#include "llvm/Support/raw_ostream.h"
2724
#include <memory>
2825

2926
using namespace clang;
3027
using namespace ento;
31-
using llvm::sys::DynamicLibrary;
32-
33-
namespace {
34-
class ClangCheckerRegistry : public CheckerRegistry {
35-
typedef void (*RegisterCheckersFn)(CheckerRegistry &);
36-
37-
static bool isCompatibleAPIVersion(const char *versionString);
38-
static void warnIncompatible(DiagnosticsEngine *diags, StringRef pluginPath,
39-
const char *pluginAPIVersion);
40-
41-
public:
42-
ClangCheckerRegistry(ArrayRef<std::string> plugins,
43-
DiagnosticsEngine *diags = nullptr);
44-
};
45-
46-
} // end anonymous namespace
47-
48-
ClangCheckerRegistry::ClangCheckerRegistry(ArrayRef<std::string> plugins,
49-
DiagnosticsEngine *diags) {
50-
#define GET_CHECKERS
51-
#define CHECKER(FULLNAME, CLASS, HELPTEXT) \
52-
addChecker(register##CLASS, FULLNAME, HELPTEXT);
53-
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
54-
#undef CHECKER
55-
#undef GET_CHECKERS
56-
57-
for (ArrayRef<std::string>::iterator i = plugins.begin(), e = plugins.end();
58-
i != e; ++i) {
59-
// Get access to the plugin.
60-
std::string err;
61-
DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err);
62-
if (!lib.isValid()) {
63-
diags->Report(diag::err_fe_unable_to_load_plugin) << *i << err;
64-
continue;
65-
}
66-
67-
// See if it's compatible with this build of clang.
68-
const char *pluginAPIVersion =
69-
(const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString");
70-
if (!isCompatibleAPIVersion(pluginAPIVersion)) {
71-
warnIncompatible(diags, *i, pluginAPIVersion);
72-
continue;
73-
}
74-
75-
// Register its checkers.
76-
RegisterCheckersFn registerPluginCheckers =
77-
(RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol(
78-
"clang_registerCheckers");
79-
if (registerPluginCheckers)
80-
registerPluginCheckers(*this);
81-
}
82-
}
83-
84-
bool ClangCheckerRegistry::isCompatibleAPIVersion(const char *versionString) {
85-
// If the version string is null, it's not an analyzer plugin.
86-
if (!versionString)
87-
return false;
88-
89-
// For now, none of the static analyzer API is considered stable.
90-
// Versions must match exactly.
91-
return strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0;
92-
}
93-
94-
void ClangCheckerRegistry::warnIncompatible(DiagnosticsEngine *diags,
95-
StringRef pluginPath,
96-
const char *pluginAPIVersion) {
97-
if (!diags)
98-
return;
99-
if (!pluginAPIVersion)
100-
return;
101-
102-
diags->Report(diag::warn_incompatible_analyzer_plugin_api)
103-
<< llvm::sys::path::filename(pluginPath);
104-
diags->Report(diag::note_incompatible_analyzer_plugin_api)
105-
<< CLANG_ANALYZER_API_VERSION_STRING
106-
<< pluginAPIVersion;
107-
}
10828

10929
std::unique_ptr<CheckerManager> ento::createCheckerManager(
11030
ASTContext &context,
@@ -114,23 +34,24 @@ std::unique_ptr<CheckerManager> ento::createCheckerManager(
11434
DiagnosticsEngine &diags) {
11535
auto checkerMgr = llvm::make_unique<CheckerManager>(context, opts);
11636

117-
ClangCheckerRegistry allCheckers(plugins, &diags);
37+
CheckerRegistry allCheckers(plugins, diags);
11838

11939
for (const auto &Fn : checkerRegistrationFns)
12040
Fn(allCheckers);
12141

122-
allCheckers.initializeManager(*checkerMgr, opts, diags);
123-
allCheckers.validateCheckerOptions(opts, diags);
42+
allCheckers.initializeManager(*checkerMgr, opts);
43+
allCheckers.validateCheckerOptions(opts);
12444
checkerMgr->finishedCheckerRegistration();
12545

12646
return checkerMgr;
12747
}
12848

129-
void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins) {
49+
void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins,
50+
DiagnosticsEngine &diags) {
13051
out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
13152
out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";
13253

133-
ClangCheckerRegistry(plugins).printHelp(out);
54+
CheckerRegistry(plugins, diags).printHelp(out);
13455
}
13556

13657
void ento::printEnabledCheckerList(raw_ostream &out,
@@ -139,7 +60,7 @@ void ento::printEnabledCheckerList(raw_ostream &out,
13960
DiagnosticsEngine &diags) {
14061
out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";
14162

142-
ClangCheckerRegistry(plugins).printList(out, opts, diags);
63+
CheckerRegistry(plugins, diags).printList(out, opts);
14364
}
14465

14566
void ento::printAnalyzerConfigList(raw_ostream &out) {

Diff for: ‎clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp

+67-13
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,74 @@
1010
#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
1111
#include "clang/Basic/Diagnostic.h"
1212
#include "clang/Basic/LLVM.h"
13+
#include "clang/Frontend/FrontendDiagnostic.h"
14+
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
1315
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
1416
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
1517
#include "llvm/ADT/STLExtras.h"
1618
#include "llvm/ADT/SetVector.h"
1719
#include "llvm/ADT/StringMap.h"
1820
#include "llvm/ADT/StringRef.h"
21+
#include "llvm/Support/DynamicLibrary.h"
22+
#include "llvm/Support/Path.h"
1923
#include "llvm/Support/raw_ostream.h"
2024
#include <algorithm>
2125

2226
using namespace clang;
2327
using namespace ento;
28+
using llvm::sys::DynamicLibrary;
29+
30+
using RegisterCheckersFn = void (*)(CheckerRegistry &);
31+
32+
static bool isCompatibleAPIVersion(const char *versionString) {
33+
// If the version string is null, it's not an analyzer plugin.
34+
if (!versionString)
35+
return false;
36+
37+
// For now, none of the static analyzer API is considered stable.
38+
// Versions must match exactly.
39+
return strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0;
40+
}
41+
42+
CheckerRegistry::CheckerRegistry(ArrayRef<std::string> plugins,
43+
DiagnosticsEngine &diags) : Diags(diags) {
44+
#define GET_CHECKERS
45+
#define CHECKER(FULLNAME, CLASS, HELPTEXT) \
46+
addChecker(register##CLASS, FULLNAME, HELPTEXT);
47+
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
48+
#undef CHECKER
49+
#undef GET_CHECKERS
50+
51+
for (ArrayRef<std::string>::iterator i = plugins.begin(), e = plugins.end();
52+
i != e; ++i) {
53+
// Get access to the plugin.
54+
std::string err;
55+
DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err);
56+
if (!lib.isValid()) {
57+
diags.Report(diag::err_fe_unable_to_load_plugin) << *i << err;
58+
continue;
59+
}
60+
61+
// See if it's compatible with this build of clang.
62+
const char *pluginAPIVersion =
63+
(const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString");
64+
if (!isCompatibleAPIVersion(pluginAPIVersion)) {
65+
Diags.Report(diag::warn_incompatible_analyzer_plugin_api)
66+
<< llvm::sys::path::filename(*i);
67+
Diags.Report(diag::note_incompatible_analyzer_plugin_api)
68+
<< CLANG_ANALYZER_API_VERSION_STRING
69+
<< pluginAPIVersion;
70+
continue;
71+
}
72+
73+
// Register its checkers.
74+
RegisterCheckersFn registerPluginCheckers =
75+
(RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol(
76+
"clang_registerCheckers");
77+
if (registerPluginCheckers)
78+
registerPluginCheckers(*this);
79+
}
80+
}
2481

2582
static constexpr char PackageSeparator = '.';
2683

@@ -47,8 +104,7 @@ static bool isInPackage(const CheckerRegistry::CheckerInfo &checker,
47104
}
48105

49106
CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers(
50-
const AnalyzerOptions &Opts,
51-
DiagnosticsEngine &diags) const {
107+
const AnalyzerOptions &Opts) const {
52108

53109
assert(std::is_sorted(Checkers.begin(), Checkers.end(), checkerNameLT) &&
54110
"In order to efficiently gather checkers, this function expects them "
@@ -65,8 +121,8 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers(
65121

66122
if (firstRelatedChecker == end ||
67123
!isInPackage(*firstRelatedChecker, opt.first)) {
68-
diags.Report(diag::err_unknown_analyzer_checker) << opt.first;
69-
diags.Report(diag::note_suggest_disabling_all_checkers);
124+
Diags.Report(diag::err_unknown_analyzer_checker) << opt.first;
125+
Diags.Report(diag::note_suggest_disabling_all_checkers);
70126
return {};
71127
}
72128

@@ -105,13 +161,12 @@ void CheckerRegistry::addChecker(InitializationFunction fn, StringRef name,
105161
}
106162

107163
void CheckerRegistry::initializeManager(CheckerManager &checkerMgr,
108-
const AnalyzerOptions &Opts,
109-
DiagnosticsEngine &diags) const {
164+
const AnalyzerOptions &Opts) const {
110165
// Sort checkers for efficient collection.
111166
llvm::sort(Checkers, checkerNameLT);
112167

113168
// Collect checkers enabled by the options.
114-
CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts, diags);
169+
CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts);
115170

116171
// Initialize the CheckerManager with all enabled checkers.
117172
for (const auto *i : enabledCheckers) {
@@ -120,8 +175,8 @@ void CheckerRegistry::initializeManager(CheckerManager &checkerMgr,
120175
}
121176
}
122177

123-
void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts,
124-
DiagnosticsEngine &diags) const {
178+
void CheckerRegistry::validateCheckerOptions(
179+
const AnalyzerOptions &opts) const {
125180
for (const auto &config : opts.Config) {
126181
size_t pos = config.getKey().find(':');
127182
if (pos == StringRef::npos)
@@ -137,7 +192,7 @@ void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts,
137192
}
138193
}
139194
if (!hasChecker)
140-
diags.Report(diag::err_unknown_analyzer_checker) << checkerName;
195+
Diags.Report(diag::err_unknown_analyzer_checker) << checkerName;
141196
}
142197
}
143198

@@ -180,13 +235,12 @@ void CheckerRegistry::printHelp(raw_ostream &out,
180235
}
181236

182237
void CheckerRegistry::printList(raw_ostream &out,
183-
const AnalyzerOptions &opts,
184-
DiagnosticsEngine &diags) const {
238+
const AnalyzerOptions &opts) const {
185239
// Sort checkers for efficient collection.
186240
llvm::sort(Checkers, checkerNameLT);
187241

188242
// Collect checkers enabled by the options.
189-
CheckerInfoSet enabledCheckers = getEnabledCheckers(opts, diags);
243+
CheckerInfoSet enabledCheckers = getEnabledCheckers(opts);
190244

191245
for (const auto *i : enabledCheckers)
192246
out << i->FullName << '\n';

0 commit comments

Comments
 (0)
Please sign in to comment.