Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:10

0001 //===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // Contains the logic for parsing the TableGen file Checkers.td, and parsing the
0010 // specific invocation of the analyzer (which checker/package is enabled, values
0011 // of their options, etc). This is in the frontend library because checker
0012 // registry functions are called from here but are defined in the dependent
0013 // library libStaticAnalyzerCheckers, but the actual data structure that holds
0014 // the parsed information is in the Core library.
0015 //
0016 //===----------------------------------------------------------------------===//
0017 
0018 #ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H
0019 #define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H
0020 
0021 #include "clang/Basic/LLVM.h"
0022 #include "clang/StaticAnalyzer/Core/CheckerRegistryData.h"
0023 #include "llvm/ADT/StringRef.h"
0024 
0025 // FIXME: move this information to an HTML file in docs/.
0026 // At the very least, a checker plugin is a dynamic library that exports
0027 // clang_analyzerAPIVersionString. This should be defined as follows:
0028 //
0029 //   extern "C"
0030 //   const char clang_analyzerAPIVersionString[] =
0031 //     CLANG_ANALYZER_API_VERSION_STRING;
0032 //
0033 // This is used to check whether the current version of the analyzer is known to
0034 // be incompatible with a plugin. Plugins with incompatible version strings,
0035 // or without a version string at all, will not be loaded.
0036 //
0037 // To add a custom checker to the analyzer, the plugin must also define the
0038 // function clang_registerCheckers. For example:
0039 //
0040 //    extern "C"
0041 //    void clang_registerCheckers (CheckerRegistry &registry) {
0042 //      registry.addChecker<MainCallChecker>("example.MainCallChecker",
0043 //        "Disallows calls to functions called main");
0044 //    }
0045 //
0046 // The first method argument is the full name of the checker, including its
0047 // enclosing package. By convention, the registered name of a checker is the
0048 // name of the associated class (the template argument).
0049 // The second method argument is a short human-readable description of the
0050 // checker.
0051 //
0052 // The clang_registerCheckers function may add any number of checkers to the
0053 // registry. If any checkers require additional initialization, use the three-
0054 // argument form of CheckerRegistry::addChecker.
0055 //
0056 // To load a checker plugin, specify the full path to the dynamic library as
0057 // the argument to the -load option in the cc1 frontend. You can then enable
0058 // your custom checker using the -analyzer-checker:
0059 //
0060 //   clang -cc1 -load </path/to/plugin.dylib> -analyze
0061 //     -analyzer-checker=<example.MainCallChecker>
0062 //
0063 // For a complete working example, see examples/analyzer-plugin.
0064 
0065 #ifndef CLANG_ANALYZER_API_VERSION_STRING
0066 // FIXME: The Clang version string is not particularly granular;
0067 // the analyzer infrastructure can change a lot between releases.
0068 // Unfortunately, this string has to be statically embedded in each plugin,
0069 // so we can't just use the functions defined in Version.h.
0070 #include "clang/Basic/Version.h"
0071 #define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING
0072 #endif
0073 
0074 namespace clang {
0075 
0076 class AnalyzerOptions;
0077 class DiagnosticsEngine;
0078 
0079 namespace ento {
0080 
0081 class CheckerManager;
0082 
0083 /// Manages a set of available checkers for running a static analysis.
0084 /// The checkers are organized into packages by full name, where including
0085 /// a package will recursively include all subpackages and checkers within it.
0086 /// For example, the checker "core.builtin.NoReturnFunctionChecker" will be
0087 /// included if initializeManager() is called with an option of "core",
0088 /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
0089 class CheckerRegistry {
0090 public:
0091   CheckerRegistry(CheckerRegistryData &Data, ArrayRef<std::string> Plugins,
0092                   DiagnosticsEngine &Diags, AnalyzerOptions &AnOpts,
0093                   ArrayRef<std::function<void(CheckerRegistry &)>>
0094                       CheckerRegistrationFns = {});
0095 
0096   /// Collects all enabled checkers in the field EnabledCheckers. It preserves
0097   /// the order of insertion, as dependencies have to be enabled before the
0098   /// checkers that depend on them.
0099   void initializeRegistry(const CheckerManager &Mgr);
0100 
0101 
0102 private:
0103   /// Default initialization function for checkers -- since CheckerManager
0104   /// includes this header, we need to make it a template parameter, and since
0105   /// the checker must be a template parameter as well, we can't put this in the
0106   /// cpp file.
0107   template <typename MGR, typename T> static void initializeManager(MGR &mgr) {
0108     mgr.template registerChecker<T>();
0109   }
0110 
0111   template <typename T> static bool returnTrue(const CheckerManager &mgr) {
0112     return true;
0113   }
0114 
0115 public:
0116   /// Adds a checker to the registry. Use this non-templated overload when your
0117   /// checker requires custom initialization.
0118   void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction sfn,
0119                   StringRef FullName, StringRef Desc, StringRef DocsUri,
0120                   bool IsHidden);
0121 
0122   /// Adds a checker to the registry. Use this templated overload when your
0123   /// checker does not require any custom initialization.
0124   /// This function isn't really needed and probably causes more headaches than
0125   /// the tiny convenience that it provides, but external plugins might use it,
0126   /// and there isn't a strong incentive to remove it.
0127   template <class T>
0128   void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri,
0129                   bool IsHidden = false) {
0130     // Avoid MSVC's Compiler Error C2276:
0131     // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
0132     addChecker(&CheckerRegistry::initializeManager<CheckerManager, T>,
0133                &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri,
0134                IsHidden);
0135   }
0136 
0137   /// Makes the checker with the full name \p fullName depend on the checker
0138   /// called \p dependency.
0139   void addDependency(StringRef FullName, StringRef Dependency);
0140 
0141   /// Makes the checker with the full name \p fullName weak depend on the
0142   /// checker called \p dependency.
0143   void addWeakDependency(StringRef FullName, StringRef Dependency);
0144 
0145   /// Registers an option to a given checker. A checker option will always have
0146   /// the following format:
0147   ///   CheckerFullName:OptionName=Value
0148   /// And can be specified from the command line like this:
0149   ///   -analyzer-config CheckerFullName:OptionName=Value
0150   ///
0151   /// Options for unknown checkers, or unknown options for a given checker, or
0152   /// invalid value types for that given option are reported as an error in
0153   /// non-compatibility mode.
0154   void addCheckerOption(StringRef OptionType, StringRef CheckerFullName,
0155                         StringRef OptionName, StringRef DefaultValStr,
0156                         StringRef Description, StringRef DevelopmentStatus,
0157                         bool IsHidden = false);
0158 
0159   /// Adds a package to the registry.
0160   void addPackage(StringRef FullName);
0161 
0162   /// Registers an option to a given package. A package option will always have
0163   /// the following format:
0164   ///   PackageFullName:OptionName=Value
0165   /// And can be specified from the command line like this:
0166   ///   -analyzer-config PackageFullName:OptionName=Value
0167   ///
0168   /// Options for unknown packages, or unknown options for a given package, or
0169   /// invalid value types for that given option are reported as an error in
0170   /// non-compatibility mode.
0171   void addPackageOption(StringRef OptionType, StringRef PackageFullName,
0172                         StringRef OptionName, StringRef DefaultValStr,
0173                         StringRef Description, StringRef DevelopmentStatus,
0174                         bool IsHidden = false);
0175 
0176   // FIXME: This *really* should be added to the frontend flag descriptions.
0177   /// Initializes a CheckerManager by calling the initialization functions for
0178   /// all checkers specified by the given CheckerOptInfo list. The order of this
0179   /// list is significant; later options can be used to reverse earlier ones.
0180   /// This can be used to exclude certain checkers in an included package.
0181   void initializeManager(CheckerManager &CheckerMgr) const;
0182 
0183   /// Check if every option corresponds to a specific checker or package.
0184   void validateCheckerOptions() const;
0185 
0186 private:
0187   template <bool IsWeak> void resolveDependencies();
0188   void resolveCheckerAndPackageOptions();
0189 
0190   CheckerRegistryData &Data;
0191 
0192   DiagnosticsEngine &Diags;
0193   AnalyzerOptions &AnOpts;
0194 };
0195 
0196 } // namespace ento
0197 } // namespace clang
0198 
0199 #endif // LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H