summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp98
1 files changed, 84 insertions, 14 deletions
diff --git a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
index 8f1c87a92ee..f1ee454f632 100644
--- a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
@@ -45,6 +45,7 @@ template <class T> struct FullNameLT {
}
};
+using PackageNameLT = FullNameLT<CheckerRegistry::PackageInfo>;
using CheckerNameLT = FullNameLT<CheckerRegistry::CheckerInfo>;
} // end of anonymous namespace
@@ -118,6 +119,9 @@ CheckerRegistry::CheckerRegistry(
addChecker(register##CLASS, shouldRegister##CLASS, FULLNAME, HELPTEXT, \
DOC_URI);
+#define GET_PACKAGES
+#define PACKAGE(FULLNAME) addPackage(FULLNAME);
+
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER
#undef GET_CHECKERS
@@ -166,6 +170,7 @@ CheckerRegistry::CheckerRegistry(
// FIXME: Alphabetical sort puts 'experimental' in the middle.
// Would it be better to name it '~experimental' or something else
// that's ASCIIbetically last?
+ llvm::sort(Packages, PackageNameLT{});
llvm::sort(Checkers, CheckerNameLT{});
#define GET_CHECKER_DEPENDENCIES
@@ -173,11 +178,24 @@ CheckerRegistry::CheckerRegistry(
#define CHECKER_DEPENDENCY(FULLNAME, DEPENDENCY) \
addDependency(FULLNAME, DEPENDENCY);
+#define GET_CHECKER_OPTIONS
+#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL) \
+ addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC);
+
+#define GET_PACKAGE_OPTIONS
+#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL) \
+ addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC);
+
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
#undef CHECKER_DEPENDENCY
#undef GET_CHECKER_DEPENDENCIES
+#undef CHECKER_OPTION
+#undef GET_CHECKER_OPTIONS
+#undef PACKAGE_OPTION
+#undef GET_PACKAGE_OPTIONS
resolveDependencies();
+ resolveCheckerAndPackageOptions();
// Parse '-analyzer-checker' and '-analyzer-disable-checker' options from the
// command line.
@@ -266,20 +284,6 @@ CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers() const {
return EnabledCheckers;
}
-void CheckerRegistry::addChecker(InitializationFunction Rfn,
- ShouldRegisterFunction Sfn, StringRef Name,
- StringRef Desc, StringRef DocsUri) {
- Checkers.emplace_back(Rfn, Sfn, Name, Desc, DocsUri);
-
- // Record the presence of the checker in its packages.
- StringRef PackageName, LeafName;
- std::tie(PackageName, LeafName) = Name.rsplit(PackageSeparator);
- while (!LeafName.empty()) {
- PackageSizes[PackageName] += 1;
- std::tie(PackageName, LeafName) = PackageName.rsplit(PackageSeparator);
- }
-}
-
void CheckerRegistry::resolveDependencies() {
for (const std::pair<StringRef, StringRef> &Entry : Dependencies) {
auto CheckerIt = binaryFind(Checkers, Entry.first);
@@ -302,6 +306,72 @@ void CheckerRegistry::addDependency(StringRef FullName, StringRef Dependency) {
Dependencies.emplace_back(FullName, Dependency);
}
+template <class T>
+static void
+insertOptionToCollection(StringRef FullName, T &Collection,
+ const CheckerRegistry::CmdLineOption &&Option) {
+ auto It = binaryFind(Collection, FullName);
+ assert(It != Collection.end() &&
+ "Failed to find the checker while attempting to add a command line "
+ "option to it!");
+
+ It->CmdLineOptions.emplace_back(std::move(Option));
+}
+
+void CheckerRegistry::resolveCheckerAndPackageOptions() {
+ for (const std::pair<StringRef, CmdLineOption> &CheckerOptEntry :
+ CheckerOptions) {
+ insertOptionToCollection(CheckerOptEntry.first, Checkers,
+ std::move(CheckerOptEntry.second));
+ }
+ CheckerOptions.clear();
+
+ for (const std::pair<StringRef, CmdLineOption> &PackageOptEntry :
+ PackageOptions) {
+ insertOptionToCollection(PackageOptEntry.first, Checkers,
+ std::move(PackageOptEntry.second));
+ }
+ PackageOptions.clear();
+}
+
+void CheckerRegistry::addPackage(StringRef FullName) {
+ Packages.emplace_back(PackageInfo(FullName));
+}
+
+void CheckerRegistry::addPackageOption(StringRef OptionType,
+ StringRef PackageFullName,
+ StringRef OptionName,
+ StringRef DefaultValStr,
+ StringRef Description) {
+ PackageOptions.emplace_back(
+ PackageFullName,
+ CmdLineOption{OptionType, OptionName, DefaultValStr, Description});
+}
+
+void CheckerRegistry::addChecker(InitializationFunction Rfn,
+ ShouldRegisterFunction Sfn, StringRef Name,
+ StringRef Desc, StringRef DocsUri) {
+ Checkers.emplace_back(Rfn, Sfn, Name, Desc, DocsUri);
+
+ // Record the presence of the checker in its packages.
+ StringRef PackageName, LeafName;
+ std::tie(PackageName, LeafName) = Name.rsplit(PackageSeparator);
+ while (!LeafName.empty()) {
+ PackageSizes[PackageName] += 1;
+ std::tie(PackageName, LeafName) = PackageName.rsplit(PackageSeparator);
+ }
+}
+
+void CheckerRegistry::addCheckerOption(StringRef OptionType,
+ StringRef CheckerFullName,
+ StringRef OptionName,
+ StringRef DefaultValStr,
+ StringRef Description) {
+ CheckerOptions.emplace_back(
+ CheckerFullName,
+ CmdLineOption{OptionType, OptionName, DefaultValStr, Description});
+}
+
void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const {
// Collect checkers enabled by the options.
CheckerInfoSet enabledCheckers = getEnabledCheckers();
OpenPOWER on IntegriCloud