Author: Jonas Devlieghere Date: 2020-03-23T12:09:24-07:00 New Revision: 56abcfad70ee679ad95ab41d934491ebcaebdf7d
URL: https://github.com/llvm/llvm-project/commit/56abcfad70ee679ad95ab41d934491ebcaebdf7d DIFF: https://github.com/llvm/llvm-project/commit/56abcfad70ee679ad95ab41d934491ebcaebdf7d.diff LOG: Revert "[analyzer][NFC] Tie CheckerRegistry to CheckerManager, allow CheckerManager to be constructed for non-analysis purposes" Temporarily reverting this patch because it breaks the modules build. Added: clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp Modified: clang/include/clang/StaticAnalyzer/Core/CheckerManager.h clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp clang/lib/StaticAnalyzer/Core/CheckerManager.cpp clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp Removed: clang/include/clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h clang/lib/StaticAnalyzer/Frontend/AnalyzerHelpFlags.cpp ################################################################################ diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index 6faf0f2e0afd..4454d7603b27 100644 --- a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -14,11 +14,9 @@ #define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H #include "clang/Analysis/ProgramPoint.h" -#include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" -#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -42,6 +40,7 @@ class BugReporter; class CallEvent; class CheckerBase; class CheckerContext; +class CheckerRegistry; class ExplodedGraph; class ExplodedNode; class ExplodedNodeSet; @@ -122,42 +121,14 @@ enum class ObjCMessageVisitKind { }; class CheckerManager { - ASTContext *Context; + ASTContext &Context; const LangOptions LangOpts; AnalyzerOptions &AOptions; CheckerNameRef CurrentCheckerName; - DiagnosticsEngine &Diags; - CheckerRegistry Registry; public: - CheckerManager( - ASTContext &Context, AnalyzerOptions &AOptions, - ArrayRef<std::string> plugins, - ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns) - : Context(&Context), LangOpts(Context.getLangOpts()), AOptions(AOptions), - Diags(Context.getDiagnostics()), - Registry(plugins, Context.getDiagnostics(), AOptions, - checkerRegistrationFns) { - Registry.initializeRegistry(*this); - Registry.initializeManager(*this); - finishedCheckerRegistration(); - } - - /// Constructs a CheckerManager that ignores all non TblGen-generated - /// checkers. Useful for unit testing, unless the checker infrastructure - /// itself is tested. CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions) - : CheckerManager(Context, AOptions, {}, {}) {} - - /// Constructs a CheckerManager without requiring an AST. No checker - /// registration will take place. Only useful for retrieving the - /// CheckerRegistry and print for help flags where the AST is unavalaible. - CheckerManager(AnalyzerOptions &AOptions, const LangOptions &LangOpts, - DiagnosticsEngine &Diags, ArrayRef<std::string> plugins) - : LangOpts(LangOpts), AOptions(AOptions), Diags(Diags), - Registry(plugins, Diags, AOptions) { - Registry.initializeRegistry(*this); - } + : Context(Context), LangOpts(Context.getLangOpts()), AOptions(AOptions) {} ~CheckerManager(); @@ -170,12 +141,7 @@ class CheckerManager { const LangOptions &getLangOpts() const { return LangOpts; } AnalyzerOptions &getAnalyzerOptions() const { return AOptions; } - const CheckerRegistry &getCheckerRegistry() const { return Registry; } - DiagnosticsEngine &getDiagnostics() const { return Diags; } - ASTContext &getASTContext() const { - assert(Context); - return *Context; - } + ASTContext &getASTContext() const { return Context; } /// Emits an error through a DiagnosticsEngine about an invalid user supplied /// checker option value. diff --git a/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h index bcc29a60ad70..2d24e6a9586b 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h @@ -55,7 +55,7 @@ class AnalysisASTConsumer : public ASTConsumer { std::unique_ptr<AnalysisASTConsumer> CreateAnalysisConsumer(CompilerInstance &CI); -} // namespace ento +} // end GR namespace } // end clang namespace diff --git a/clang/include/clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h b/clang/include/clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h deleted file mode 100644 index a30c241e1350..000000000000 --- a/clang/include/clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h +++ /dev/null @@ -1,30 +0,0 @@ -//===-- AnalyzerHelpFlags.h - Query functions for --help flags --*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_ANALYZERHELPFLAGS_H -#define LLVM_CLANG_STATICANALYZER_FRONTEND_ANALYZERHELPFLAGS_H - -namespace llvm { -class raw_ostream; -} // namespace llvm - -namespace clang { - -class CompilerInstance; - -namespace ento { - -void printCheckerHelp(llvm::raw_ostream &OS, CompilerInstance &CI); -void printEnabledCheckerList(llvm::raw_ostream &OS, CompilerInstance &CI); -void printAnalyzerConfigList(llvm::raw_ostream &OS); -void printCheckerConfigList(llvm::raw_ostream &OS, CompilerInstance &CI); - -} // namespace ento -} // namespace clang - -#endif diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h new file mode 100644 index 000000000000..52a534499002 --- /dev/null +++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h @@ -0,0 +1,38 @@ +//===-- CheckerRegistration.h - Checker Registration Function ---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H +#define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H + +#include "clang/AST/ASTContext.h" +#include "clang/Basic/LLVM.h" +#include <functional> +#include <memory> +#include <string> + +namespace clang { + class AnalyzerOptions; + class LangOptions; + class DiagnosticsEngine; + +namespace ento { + class CheckerManager; + class CheckerRegistry; + + std::unique_ptr<CheckerManager> createCheckerManager( + ASTContext &context, + AnalyzerOptions &opts, + ArrayRef<std::string> plugins, + ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns, + DiagnosticsEngine &diags); + +} // end ento namespace + +} // end namespace clang + +#endif diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index dde2409ed72c..8830542f27d8 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H #include "clang/Basic/LLVM.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -73,8 +74,6 @@ class LangOptions; namespace ento { -class CheckerManager; - /// Manages a set of available checkers for running a static analysis. /// The checkers are organized into packages by full name, where including /// a package will recursively include all subpackages and checkers within it. @@ -84,15 +83,10 @@ class CheckerManager; class CheckerRegistry { public: CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags, - AnalyzerOptions &AnOpts, + AnalyzerOptions &AnOpts, const LangOptions &LangOpts, ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns = {}); - /// Collects all enabled checkers in the field EnabledCheckers. It preserves - /// the order of insertion, as dependencies have to be enabled before the - /// checkers that depend on them. - void initializeRegistry(const CheckerManager &Mgr); - /// Initialization functions perform any necessary setup for a checker. /// They should include a call to CheckerManager::registerChecker. using InitializationFunction = void (*)(CheckerManager &); @@ -211,20 +205,14 @@ class CheckerRegistry { using PackageInfoList = llvm::SmallVector<PackageInfo, 0>; -private: - /// Default initialization function for checkers -- since CheckerManager - /// includes this header, we need to make it a template parameter, and since - /// the checker must be a template parameter as well, we can't put this in the - /// cpp file. - template <typename MGR, typename T> static void initializeManager(MGR &mgr) { - mgr.template registerChecker<T>(); + template <typename T> static void addToCheckerMgr(CheckerManager &mgr) { + mgr.registerChecker<T>(); } - template <typename T> static bool returnTrue(const LangOptions &) { + static bool returnTrue(const LangOptions &LO) { return true; } -public: /// Adds a checker to the registry. Use this non-templated overload when your /// checker requires custom initialization. void addChecker(InitializationFunction Fn, ShouldRegisterFunction sfn, @@ -233,16 +221,13 @@ class CheckerRegistry { /// Adds a checker to the registry. Use this templated overload when your /// checker does not require any custom initialization. - /// This function isn't really needed and probably causes more headaches than - /// the tiny convenience that it provides, but external plugins might use it, - /// and there isn't a strong incentive to remove it. template <class T> void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri, bool IsHidden = false) { // Avoid MSVC's Compiler Error C2276: // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx - addChecker(&initializeManager<CheckerManager, T>, &returnTrue<T>, FullName, - Desc, DocsUri, IsHidden); + addChecker(&CheckerRegistry::addToCheckerMgr<T>, + &CheckerRegistry::returnTrue, FullName, Desc, DocsUri, IsHidden); } /// Makes the checker with the full name \p fullName depends on the checker @@ -278,7 +263,7 @@ class CheckerRegistry { void addPackageOption(StringRef OptionType, StringRef PackageFullName, StringRef OptionName, StringRef DefaultValStr, StringRef Description, StringRef DevelopmentStatus, - bool IsHidden = false); + bool IsHidden = false); // FIXME: This *really* should be added to the frontend flag descriptions. /// Initializes a CheckerManager by calling the initialization functions for @@ -298,6 +283,11 @@ class CheckerRegistry { void printCheckerOptionList(raw_ostream &Out) const; private: + /// Collect all enabled checkers. The returned container preserves the order + /// of insertion, as dependencies have to be enabled before the checkers that + /// depend on them. + CheckerInfoSet getEnabledCheckers() const; + /// Return an iterator range of mutable CheckerInfos \p CmdLineArg applies to. /// For example, it'll return the checkers for the core package, if /// \p CmdLineArg is "core". @@ -324,7 +314,7 @@ class CheckerRegistry { DiagnosticsEngine &Diags; AnalyzerOptions &AnOpts; - CheckerInfoSet EnabledCheckers; + const LangOptions &LangOpts; }; } // namespace ento diff --git a/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h index 6b6a395a1884..878b65a1b143 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -51,7 +51,22 @@ class ParseModelFileAction : public ASTFrontendAction { llvm::StringMap<Stmt *> &Bodies; }; -} // namespace ento +void printCheckerHelp(raw_ostream &OS, + ArrayRef<std::string> plugins, + AnalyzerOptions &opts, + DiagnosticsEngine &diags, + const LangOptions &LangOpts); +void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins, + AnalyzerOptions &opts, + DiagnosticsEngine &diags, + const LangOptions &LangOpts); +void printAnalyzerConfigList(raw_ostream &OS); +void printCheckerConfigList(raw_ostream &OS, ArrayRef<std::string> plugins, + AnalyzerOptions &opts, + DiagnosticsEngine &diags, + const LangOptions &LangOpts); + +} // end GR namespace } // end namespace clang diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index ab7a1e32e301..70735ab2d7b2 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -23,7 +23,6 @@ #include "clang/Frontend/Utils.h" #include "clang/FrontendTool/Utils.h" #include "clang/Rewrite/Frontend/FrontendActions.h" -#include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h" #include "clang/StaticAnalyzer/Frontend/FrontendActions.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" @@ -244,24 +243,35 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) { // These should happen AFTER plugins have been loaded! AnalyzerOptions &AnOpts = *Clang->getAnalyzerOpts(); - // Honor -analyzer-checker-help and -analyzer-checker-help-hidden. if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha || AnOpts.ShowCheckerHelpDeveloper) { - ento::printCheckerHelp(llvm::outs(), *Clang); + ento::printCheckerHelp(llvm::outs(), + Clang->getFrontendOpts().Plugins, + AnOpts, + Clang->getDiagnostics(), + Clang->getLangOpts()); return true; } // Honor -analyzer-checker-option-help. if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList || AnOpts.ShowCheckerOptionDeveloperList) { - ento::printCheckerConfigList(llvm::outs(), *Clang); + ento::printCheckerConfigList(llvm::outs(), + Clang->getFrontendOpts().Plugins, + *Clang->getAnalyzerOpts(), + Clang->getDiagnostics(), + Clang->getLangOpts()); return true; } // Honor -analyzer-list-enabled-checkers. if (AnOpts.ShowEnabledCheckerList) { - ento::printEnabledCheckerList(llvm::outs(), *Clang); + ento::printEnabledCheckerList(llvm::outs(), + Clang->getFrontendOpts().Plugins, + AnOpts, + Clang->getDiagnostics(), + Clang->getLangOpts()); return true; } diff --git a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp index 081a31009235..ce5e4a46d3e2 100644 --- a/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp @@ -64,9 +64,10 @@ void CheckerManager::reportInvalidCheckerOptionValue( const CheckerBase *C, StringRef OptionName, StringRef ExpectedValueDesc) const { - getDiagnostics().Report(diag::err_analyzer_checker_option_invalid_input) - << (llvm::Twine() + C->getTagDescription() + ":" + OptionName).str() - << ExpectedValueDesc; + Context.getDiagnostics() + .Report(diag::err_analyzer_checker_option_invalid_input) + << (llvm::Twine() + C->getTagDescription() + ":" + OptionName).str() + << ExpectedValueDesc; } //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 1ef6c477bba5..a908aede68bb 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -33,6 +33,7 @@ #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" +#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h" #include "clang/Tooling/Core/Replacement.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/PostOrderIterator.h" @@ -347,8 +348,8 @@ class AnalysisConsumer : public AnalysisASTConsumer, void Initialize(ASTContext &Context) override { Ctx = &Context; - checkerMgr = std::make_unique<CheckerManager>(*Ctx, *Opts, Plugins, - CheckerRegistrationFns); + checkerMgr = createCheckerManager( + *Ctx, *Opts, Plugins, CheckerRegistrationFns, PP.getDiagnostics()); Mgr = std::make_unique<AnalysisManager>(*Ctx, PP, PathConsumers, CreateStoreMgr, CreateConstraintMgr, diff --git a/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt b/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt index 055878aee0a5..6f1151ab0c11 100644 --- a/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Frontend/CMakeLists.txt @@ -6,7 +6,7 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangStaticAnalyzerFrontend AnalysisConsumer.cpp - AnalyzerHelpFlags.cpp + CheckerRegistration.cpp CheckerRegistry.cpp FrontendActions.cpp ModelConsumer.cpp diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalyzerHelpFlags.cpp b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp similarity index 69% rename from clang/lib/StaticAnalyzer/Frontend/AnalyzerHelpFlags.cpp rename to clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp index d589e69bdf34..f4f06e32cd1d 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalyzerHelpFlags.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp @@ -10,9 +10,8 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h" +#include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h" #include "clang/Basic/Diagnostic.h" -#include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" @@ -25,34 +24,53 @@ using namespace clang; using namespace ento; -void ento::printCheckerHelp(raw_ostream &out, CompilerInstance &CI) { - out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n"; - out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n"; +std::unique_ptr<CheckerManager> ento::createCheckerManager( + ASTContext &context, + AnalyzerOptions &opts, + ArrayRef<std::string> plugins, + ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns, + DiagnosticsEngine &diags) { + auto checkerMgr = std::make_unique<CheckerManager>(context, opts); - auto CheckerMgr = std::make_unique<CheckerManager>( - *CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(), - CI.getFrontendOpts().Plugins); + CheckerRegistry allCheckers(plugins, diags, opts, context.getLangOpts(), + checkerRegistrationFns); - CheckerMgr->getCheckerRegistry().printCheckerWithDescList(out); -} + allCheckers.initializeManager(*checkerMgr); + allCheckers.validateCheckerOptions(); + checkerMgr->finishedCheckerRegistration(); -void ento::printEnabledCheckerList(raw_ostream &out, CompilerInstance &CI) { - out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n"; + return checkerMgr; +} - auto CheckerMgr = std::make_unique<CheckerManager>( - *CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(), - CI.getFrontendOpts().Plugins); +void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins, + AnalyzerOptions &anopts, + DiagnosticsEngine &diags, + const LangOptions &langOpts) { + out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n"; + out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n"; - CheckerMgr->getCheckerRegistry().printEnabledCheckerList(out); + CheckerRegistry(plugins, diags, anopts, langOpts) + .printCheckerWithDescList(out); } -void ento::printCheckerConfigList(raw_ostream &out, CompilerInstance &CI) { +void ento::printEnabledCheckerList(raw_ostream &out, + ArrayRef<std::string> plugins, + AnalyzerOptions &anopts, + DiagnosticsEngine &diags, + const LangOptions &langOpts) { + out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n"; - auto CheckerMgr = std::make_unique<CheckerManager>( - *CI.getAnalyzerOpts(), CI.getLangOpts(), CI.getDiagnostics(), - CI.getFrontendOpts().Plugins); + CheckerRegistry(plugins, diags, anopts, langOpts) + .printEnabledCheckerList(out); +} - CheckerMgr->getCheckerRegistry().printCheckerOptionList(out); +void ento::printCheckerConfigList(raw_ostream &OS, + ArrayRef<std::string> plugins, + AnalyzerOptions &opts, + DiagnosticsEngine &diags, + const LangOptions &LangOpts) { + CheckerRegistry(plugins, diags, opts, LangOpts) + .printCheckerOptionList(OS); } void ento::printAnalyzerConfigList(raw_ostream &out) { diff --git a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp index db09ca4e625e..4af204474494 100644 --- a/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp @@ -109,9 +109,9 @@ CheckerRegistry::getMutableCheckersForCmdLineArg(StringRef CmdLineArg) { CheckerRegistry::CheckerRegistry( ArrayRef<std::string> Plugins, DiagnosticsEngine &Diags, - AnalyzerOptions &AnOpts, + AnalyzerOptions &AnOpts, const LangOptions &LangOpts, ArrayRef<std::function<void(CheckerRegistry &)>> CheckerRegistrationFns) - : Diags(Diags), AnOpts(AnOpts) { + : Diags(Diags), AnOpts(AnOpts), LangOpts(LangOpts) { // Register builtin checkers. #define GET_CHECKERS @@ -179,16 +179,12 @@ CheckerRegistry::CheckerRegistry( addDependency(FULLNAME, DEPENDENCY); #define GET_CHECKER_OPTIONS -#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, \ - DEVELOPMENT_STATUS, IS_HIDDEN) \ - addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, \ - DEVELOPMENT_STATUS, IS_HIDDEN); +#define CHECKER_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, DEVELOPMENT_STATUS, IS_HIDDEN) \ + addCheckerOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, DEVELOPMENT_STATUS, IS_HIDDEN); #define GET_PACKAGE_OPTIONS -#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, \ - DEVELOPMENT_STATUS, IS_HIDDEN) \ - addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, \ - DEVELOPMENT_STATUS, IS_HIDDEN); +#define PACKAGE_OPTION(TYPE, FULLNAME, CMDFLAG, DESC, DEFAULT_VAL, DEVELOPMENT_STATUS, IS_HIDDEN) \ + addPackageOption(TYPE, FULLNAME, CMDFLAG, DEFAULT_VAL, DESC, DEVELOPMENT_STATUS, IS_HIDDEN); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER_DEPENDENCY @@ -217,53 +213,24 @@ CheckerRegistry::CheckerRegistry( : StateFromCmdLine::State_Disabled; } } - validateCheckerOptions(); -} - -/// Collects dependenies in \p enabledCheckers. Return None on failure. -LLVM_NODISCARD -static llvm::Optional<CheckerRegistry::CheckerInfoSet> -collectDependencies(const CheckerRegistry::CheckerInfo &checker, - const CheckerManager &Mgr); - -void CheckerRegistry::initializeRegistry(const CheckerManager &Mgr) { - for (const CheckerInfo &Checker : Checkers) { - if (!Checker.isEnabled(Mgr.getLangOpts())) - continue; - - // Recursively enable its dependencies. - llvm::Optional<CheckerInfoSet> Deps = collectDependencies(Checker, Mgr); - - if (!Deps) { - // If we failed to enable any of the dependencies, don't enable this - // checker. - continue; - } - - // Note that set_union also preserves the order of insertion. - EnabledCheckers.set_union(*Deps); - - // Enable the checker. - EnabledCheckers.insert(&Checker); - } } /// Collects dependencies in \p ret, returns false on failure. static bool collectDependenciesImpl(const CheckerRegistry::ConstCheckerInfoList &Deps, - const CheckerManager &Mgr, + const LangOptions &LO, CheckerRegistry::CheckerInfoSet &Ret); /// Collects dependenies in \p enabledCheckers. Return None on failure. LLVM_NODISCARD static llvm::Optional<CheckerRegistry::CheckerInfoSet> collectDependencies(const CheckerRegistry::CheckerInfo &checker, - const CheckerManager &Mgr) { + const LangOptions &LO) { CheckerRegistry::CheckerInfoSet Ret; // Add dependencies to the enabled checkers only if all of them can be // enabled. - if (!collectDependenciesImpl(checker.Dependencies, Mgr, Ret)) + if (!collectDependenciesImpl(checker.Dependencies, LO, Ret)) return None; return Ret; @@ -271,16 +238,16 @@ collectDependencies(const CheckerRegistry::CheckerInfo &checker, static bool collectDependenciesImpl(const CheckerRegistry::ConstCheckerInfoList &Deps, - const CheckerManager &Mgr, + const LangOptions &LO, CheckerRegistry::CheckerInfoSet &Ret) { for (const CheckerRegistry::CheckerInfo *Dependency : Deps) { - if (Dependency->isDisabled(Mgr.getLangOpts())) + if (Dependency->isDisabled(LO)) return false; // Collect dependencies recursively. - if (!collectDependenciesImpl(Dependency->Dependencies, Mgr, Ret)) + if (!collectDependenciesImpl(Dependency->Dependencies, LO, Ret)) return false; Ret.insert(Dependency); @@ -289,6 +256,34 @@ collectDependenciesImpl(const CheckerRegistry::ConstCheckerInfoList &Deps, return true; } +CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers() const { + + CheckerInfoSet EnabledCheckers; + + for (const CheckerInfo &Checker : Checkers) { + if (!Checker.isEnabled(LangOpts)) + continue; + + // Recursively enable its dependencies. + llvm::Optional<CheckerInfoSet> Deps = + collectDependencies(Checker, LangOpts); + + if (!Deps) { + // If we failed to enable any of the dependencies, don't enable this + // checker. + continue; + } + + // Note that set_union also preserves the order of insertion. + EnabledCheckers.set_union(*Deps); + + // Enable the checker. + EnabledCheckers.insert(&Checker); + } + + return EnabledCheckers; +} + void CheckerRegistry::resolveDependencies() { for (const std::pair<StringRef, StringRef> &Entry : Dependencies) { auto CheckerIt = binaryFind(Checkers, Entry.first); @@ -303,6 +298,8 @@ void CheckerRegistry::resolveDependencies() { CheckerIt->Dependencies.emplace_back(&*DependencyIt); } + + Dependencies.clear(); } void CheckerRegistry::addDependency(StringRef FullName, StringRef Dependency) { @@ -381,12 +378,14 @@ void CheckerRegistry::resolveCheckerAndPackageOptions() { insertOptionToCollection(CheckerOptEntry.first, Checkers, CheckerOptEntry.second, AnOpts, Diags); } + CheckerOptions.clear(); for (const std::pair<StringRef, CmdLineOption> &PackageOptEntry : PackageOptions) { insertOptionToCollection(PackageOptEntry.first, Packages, PackageOptEntry.second, AnOpts, Diags); } + PackageOptions.clear(); } void CheckerRegistry::addPackage(StringRef FullName) { @@ -433,8 +432,11 @@ void CheckerRegistry::addCheckerOption(StringRef OptionType, } void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const { + // Collect checkers enabled by the options. + CheckerInfoSet enabledCheckers = getEnabledCheckers(); + // Initialize the CheckerManager with all enabled checkers. - for (const auto *Checker : EnabledCheckers) { + for (const auto *Checker : enabledCheckers) { CheckerMgr.setCurrentCheckerName(CheckerNameRef(Checker->FullName)); Checker->Initialize(CheckerMgr); } @@ -503,10 +505,6 @@ void CheckerRegistry::validateCheckerOptions() const { } } -//===----------------------------------------------------------------------===// -// Printing functions. -//===----------------------------------------------------------------------===// - void CheckerRegistry::printCheckerWithDescList(raw_ostream &Out, size_t MaxNameChars) const { // FIXME: Print available packages. @@ -558,6 +556,9 @@ void CheckerRegistry::printCheckerWithDescList(raw_ostream &Out, } void CheckerRegistry::printEnabledCheckerList(raw_ostream &Out) const { + // Collect checkers enabled by the options. + CheckerInfoSet EnabledCheckers = getEnabledCheckers(); + for (const auto *i : EnabledCheckers) Out << i->FullName << '\n'; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits