alexfh created this revision. alexfh added a reviewer: george.karpenkov. Herald added a subscriber: a.sidorin.
Add an extension point to allow registration of statically-linked Clang Static Analyzer checkers that are not a part of the Clang tree. This extension point employs the mechanism used when checkers are registered from dynamically loaded plugins. Repository: rC Clang https://reviews.llvm.org/D45718 Files: include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
Index: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp =================================================================== --- lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp +++ lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -111,16 +111,21 @@ return checkerOpts; } -std::unique_ptr<CheckerManager> -ento::createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts, - ArrayRef<std::string> plugins, - DiagnosticsEngine &diags) { +std::unique_ptr<CheckerManager> ento::createCheckerManager( + AnalyzerOptions &opts, const LangOptions &langOpts, + ArrayRef<std::string> plugins, + ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns, + DiagnosticsEngine &diags) { std::unique_ptr<CheckerManager> checkerMgr( new CheckerManager(langOpts, opts)); SmallVector<CheckerOptInfo, 8> checkerOpts = getCheckerOptList(opts); ClangCheckerRegistry allCheckers(plugins, &diags); + + for (const auto &Fn : checkerRegistrationFns) + Fn(allCheckers); + allCheckers.initializeManager(*checkerMgr, checkerOpts); allCheckers.validateCheckerOptions(opts, diags); checkerMgr->finishedCheckerRegistration(); Index: lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp =================================================================== --- lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -164,6 +164,8 @@ /// Bug Reporter to use while recursively visiting Decls. BugReporter *RecVisitorBR; + std::vector<std::function<void(CheckerRegistry &)>> CheckerRegistrationFns; + public: ASTContext *Ctx; const Preprocessor &PP; @@ -293,8 +295,9 @@ void Initialize(ASTContext &Context) override { Ctx = &Context; - checkerMgr = createCheckerManager(*Opts, PP.getLangOpts(), Plugins, - PP.getDiagnostics()); + checkerMgr = + createCheckerManager(*Opts, PP.getLangOpts(), Plugins, + CheckerRegistrationFns, PP.getDiagnostics()); Mgr = llvm::make_unique<AnalysisManager>( *Ctx, PP.getDiagnostics(), PP.getLangOpts(), PathConsumers, @@ -385,6 +388,10 @@ PathConsumers.push_back(Consumer); } + void AddCheckerRegistrationFn(std::function<void(CheckerRegistry&)> Fn) override { + CheckerRegistrationFns.push_back(std::move(Fn)); + } + private: void storeTopLevelDecls(DeclGroupRef DG); std::string getFunctionName(const Decl *D); Index: include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h =================================================================== --- include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h +++ include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H #include "clang/Basic/LLVM.h" +#include <functional> #include <memory> #include <string> @@ -21,10 +22,13 @@ namespace ento { class CheckerManager; + class CheckerRegistry; - std::unique_ptr<CheckerManager> - createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts, - ArrayRef<std::string> plugins, DiagnosticsEngine &diags); + std::unique_ptr<CheckerManager> createCheckerManager( + AnalyzerOptions &opts, const LangOptions &langOpts, + ArrayRef<std::string> plugins, + ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns, + DiagnosticsEngine &diags); } // end ento namespace Index: include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h =================================================================== --- include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h +++ include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h @@ -17,6 +17,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/Basic/LLVM.h" +#include <functional> #include <memory> namespace clang { @@ -29,10 +30,24 @@ namespace ento { class PathDiagnosticConsumer; class CheckerManager; +class CheckerRegistry; class AnalysisASTConsumer : public ASTConsumer { public: virtual void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) = 0; + + /// This method allows registering statically linked custom checkers that are + /// not a part of the Clang tree. It employs the same mechanism that is used + /// by plugins. + /// + /// Example: + /// + /// Consumer->AddCheckerRegistrationFn([] (CheckerRegistry& Registry) { + /// Registry.addChecker<MyCustomChecker>("example.MyCustomChecker", + /// "Description"); + /// }); + virtual void + AddCheckerRegistrationFn(std::function<void(CheckerRegistry &)> Fn) = 0; }; /// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits