Szelethus created this revision.
Szelethus added reviewers: george.karpenkov, NoQ, xazax.hun.
Herald added subscribers: cfe-commits, dkrupp, donat.nagy, mikhail.ramalho, 
a.sidorin, rnkovacs, szepet, whisperity.

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.


Repository:
  rC Clang

https://reviews.llvm.org/D54437

Files:
  include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
  include/clang/StaticAnalyzer/Frontend/FrontendActions.h
  lib/FrontendTool/ExecuteCompilerInvocation.cpp
  lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
  lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp

Index: lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
===================================================================
--- lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
+++ lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
@@ -10,17 +10,73 @@
 #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 
 using namespace clang;
 using namespace ento;
+using llvm::sys::DynamicLibrary;
+
+using RegisterCheckersFn = void (*)(CheckerRegistry &);
+
+static bool isCompatibleAPIVersion(const char *versionString) {
+  // If the version string is null, it's not an analyzer plugin.
+  if (!versionString)
+    return false;
+
+  // For now, none of the static analyzer API is considered stable.
+  // Versions must match exactly.
+  return strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0;
+}
+
+CheckerRegistry::CheckerRegistry(ArrayRef<std::string> plugins,
+                                 DiagnosticsEngine &diags) : Diags(diags) {
+#define GET_CHECKERS
+#define CHECKER(FULLNAME, CLASS, HELPTEXT)                                     \
+  addChecker(register##CLASS, FULLNAME, HELPTEXT);
+#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
+#undef CHECKER
+#undef GET_CHECKERS
+
+  for (ArrayRef<std::string>::iterator i = plugins.begin(), e = plugins.end();
+       i != e; ++i) {
+    // Get access to the plugin.
+    std::string err;
+    DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err);
+    if (!lib.isValid()) {
+      diags.Report(diag::err_fe_unable_to_load_plugin) << *i << err;
+      continue;
+    }
+
+    // See if it's compatible with this build of clang.
+    const char *pluginAPIVersion =
+      (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString");
+    if (!isCompatibleAPIVersion(pluginAPIVersion)) {
+      Diags.Report(diag::warn_incompatible_analyzer_plugin_api)
+          << llvm::sys::path::filename(*i);
+      Diags.Report(diag::note_incompatible_analyzer_plugin_api)
+          << CLANG_ANALYZER_API_VERSION_STRING
+          << pluginAPIVersion;
+      continue;
+    }
+
+    // Register its checkers.
+    RegisterCheckersFn registerPluginCheckers =
+      (RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol(
+                                                      "clang_registerCheckers");
+    if (registerPluginCheckers)
+      registerPluginCheckers(*this);
+  }
+}
 
 static constexpr char PackageSeparator = '.';
 
@@ -47,8 +103,7 @@
 }
 
 CheckerRegistry::CheckerInfoSet CheckerRegistry::getEnabledCheckers(
-                                              const AnalyzerOptions &Opts,
-                                              DiagnosticsEngine &diags) const {
+                                            const AnalyzerOptions &Opts) const {
 
   assert(std::is_sorted(Checkers.begin(), Checkers.end(), checkerNameLT) &&
          "In order to efficiently gather checkers, this function expects them "
@@ -65,7 +120,7 @@
 
     if (firstRelatedChecker == end ||
         !isInPackage(*firstRelatedChecker, opt.first)) {
-      diags.Report(diag::err_unknown_analyzer_checker) << opt.first;
+      Diags.Report(diag::err_unknown_analyzer_checker) << opt.first;
       return {};
     }
 
@@ -104,23 +159,22 @@
 }
 
 void CheckerRegistry::initializeManager(CheckerManager &checkerMgr,
-                                        const AnalyzerOptions &Opts,
-                                        DiagnosticsEngine &diags) const {
+                                        const AnalyzerOptions &Opts) const {
   // Sort checkers for efficient collection.
   llvm::sort(Checkers, checkerNameLT);
 
   // Collect checkers enabled by the options.
-  CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts, diags);
+  CheckerInfoSet enabledCheckers = getEnabledCheckers(Opts);
 
   // Initialize the CheckerManager with all enabled checkers.
   for (const auto *i : enabledCheckers) {
     checkerMgr.setCurrentCheckName(CheckName(i->FullName));
     i->Initialize(checkerMgr);
   }
 }
 
-void CheckerRegistry::validateCheckerOptions(const AnalyzerOptions &opts,
-                                             DiagnosticsEngine &diags) const {
+void CheckerRegistry::validateCheckerOptions(
+                                            const AnalyzerOptions &opts) const {
   for (const auto &config : opts.Config) {
     size_t pos = config.getKey().find(':');
     if (pos == StringRef::npos)
@@ -136,7 +190,7 @@
       }
     }
     if (!hasChecker)
-      diags.Report(diag::err_unknown_analyzer_checker) << checkerName;
+      Diags.Report(diag::err_unknown_analyzer_checker) << checkerName;
   }
 }
 
@@ -179,13 +233,12 @@
 }
 
 void CheckerRegistry::printList(raw_ostream &out,
-                                const AnalyzerOptions &opts,
-                                DiagnosticsEngine &diags) const {
+                                const AnalyzerOptions &opts) const {
   // Sort checkers for efficient collection.
   llvm::sort(Checkers, checkerNameLT);
 
   // Collect checkers enabled by the options.
-  CheckerInfoSet enabledCheckers = getEnabledCheckers(opts, diags);
+  CheckerInfoSet enabledCheckers = getEnabledCheckers(opts);
 
   for (const auto *i : enabledCheckers)
     out << i->FullName << '\n';
Index: lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
===================================================================
--- lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
+++ lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
@@ -16,95 +16,15 @@
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <memory>
 
 using namespace clang;
 using namespace ento;
-using llvm::sys::DynamicLibrary;
-
-namespace {
-class ClangCheckerRegistry : public CheckerRegistry {
-  typedef void (*RegisterCheckersFn)(CheckerRegistry &);
-
-  static bool isCompatibleAPIVersion(const char *versionString);
-  static void warnIncompatible(DiagnosticsEngine *diags, StringRef pluginPath,
-                               const char *pluginAPIVersion);
-
-public:
-  ClangCheckerRegistry(ArrayRef<std::string> plugins,
-                       DiagnosticsEngine *diags = nullptr);
-};
-
-} // end anonymous namespace
-
-ClangCheckerRegistry::ClangCheckerRegistry(ArrayRef<std::string> plugins,
-                                           DiagnosticsEngine *diags) {
-#define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT)                                     \
-  addChecker(register##CLASS, FULLNAME, HELPTEXT);
-#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
-#undef CHECKER
-#undef GET_CHECKERS
-
-  for (ArrayRef<std::string>::iterator i = plugins.begin(), e = plugins.end();
-       i != e; ++i) {
-    // Get access to the plugin.
-    std::string err;
-    DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(i->c_str(), &err);
-    if (!lib.isValid()) {
-      diags->Report(diag::err_fe_unable_to_load_plugin) << *i << err;
-      continue;
-    }
-
-    // See if it's compatible with this build of clang.
-    const char *pluginAPIVersion =
-      (const char *) lib.getAddressOfSymbol("clang_analyzerAPIVersionString");
-    if (!isCompatibleAPIVersion(pluginAPIVersion)) {
-      warnIncompatible(diags, *i, pluginAPIVersion);
-      continue;
-    }
-
-    // Register its checkers.
-    RegisterCheckersFn registerPluginCheckers =
-      (RegisterCheckersFn) (intptr_t) lib.getAddressOfSymbol(
-                                                      "clang_registerCheckers");
-    if (registerPluginCheckers)
-      registerPluginCheckers(*this);
-  }
-}
-
-bool ClangCheckerRegistry::isCompatibleAPIVersion(const char *versionString) {
-  // If the version string is null, it's not an analyzer plugin.
-  if (!versionString)
-    return false;
-
-  // For now, none of the static analyzer API is considered stable.
-  // Versions must match exactly.
-  return strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0;
-}
-
-void ClangCheckerRegistry::warnIncompatible(DiagnosticsEngine *diags,
-                                            StringRef pluginPath,
-                                            const char *pluginAPIVersion) {
-  if (!diags)
-    return;
-  if (!pluginAPIVersion)
-    return;
-
-  diags->Report(diag::warn_incompatible_analyzer_plugin_api)
-      << llvm::sys::path::filename(pluginPath);
-  diags->Report(diag::note_incompatible_analyzer_plugin_api)
-      << CLANG_ANALYZER_API_VERSION_STRING
-      << pluginAPIVersion;
-}
 
 std::unique_ptr<CheckerManager> ento::createCheckerManager(
     ASTContext &context,
@@ -114,32 +34,33 @@
     DiagnosticsEngine &diags) {
   auto checkerMgr = llvm::make_unique<CheckerManager>(context, opts);
 
-  ClangCheckerRegistry allCheckers(plugins, &diags);
+  CheckerRegistry allCheckers(plugins, diags);
 
   for (const auto &Fn : checkerRegistrationFns)
     Fn(allCheckers);
 
-  allCheckers.initializeManager(*checkerMgr, opts, diags);
-  allCheckers.validateCheckerOptions(opts, diags);
+  allCheckers.initializeManager(*checkerMgr, opts);
+  allCheckers.validateCheckerOptions(opts);
   checkerMgr->finishedCheckerRegistration();
 
   return checkerMgr;
 }
 
-void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins) {
+void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins,
+                            DiagnosticsEngine &diags) {
   out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
   out << "USAGE: -analyzer-checker <CHECKER or PACKAGE,...>\n\n";
 
-  ClangCheckerRegistry(plugins).printHelp(out);
+  CheckerRegistry(plugins, diags).printHelp(out);
 }
 
 void ento::printEnabledCheckerList(raw_ostream &out,
                                    ArrayRef<std::string> plugins,
                                    const AnalyzerOptions &opts,
                                    DiagnosticsEngine &diags) {
   out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";
 
-  ClangCheckerRegistry(plugins).printList(out, opts, diags);
+  CheckerRegistry(plugins, diags).printList(out, opts);
 }
 
 void ento::printAnalyzerConfigList(raw_ostream &out) {
Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp
===================================================================
--- lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -238,7 +238,8 @@
   // Honor -analyzer-checker-help.
   // This should happen AFTER plugins have been loaded!
   if (Clang->getAnalyzerOpts()->ShowCheckerHelp) {
-    ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins);
+    ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins,
+                           Clang->getDiagnostics());
     return true;
   }
 
Index: include/clang/StaticAnalyzer/Frontend/FrontendActions.h
===================================================================
--- include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -52,7 +52,8 @@
   llvm::StringMap<Stmt *> &Bodies;
 };
 
-void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
+void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins,
+                      DiagnosticsEngine &diags);
 void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins,
                              const AnalyzerOptions &opts,
                              DiagnosticsEngine &diags);
Index: include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
===================================================================
--- include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
+++ include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
@@ -81,6 +81,8 @@
 /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
 class CheckerRegistry {
 public:
+  CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags);
+
   /// Initialization functions perform any necessary setup for a checker.
   /// They should include a call to CheckerManager::registerChecker.
   using InitializationFunction = void (*)(CheckerManager &);
@@ -122,25 +124,23 @@
   /// all checkers specified by the given CheckerOptInfo list. The order of this
   /// list is significant; later options can be used to reverse earlier ones.
   /// This can be used to exclude certain checkers in an included package.
-  void initializeManager(CheckerManager &mgr, const AnalyzerOptions &Opts,
-                         DiagnosticsEngine &diags) const;
+  void initializeManager(CheckerManager &mgr,
+                         const AnalyzerOptions &Opts) const;
 
   /// Check if every option corresponds to a specific checker or package.
-  void validateCheckerOptions(const AnalyzerOptions &opts,
-                              DiagnosticsEngine &diags) const;
+  void validateCheckerOptions(const AnalyzerOptions &opts) const;
 
   /// Prints the name and description of all checkers in this registry.
   /// This output is not intended to be machine-parseable.
   void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
-  void printList(raw_ostream &out, const AnalyzerOptions &opts,
-                 DiagnosticsEngine &diags) const;
+  void printList(raw_ostream &out, const AnalyzerOptions &opts) const;
 
 private:
-  CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts,
-                                    DiagnosticsEngine &diags) const;
+  CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts) const;
 
   mutable CheckerInfoList Checkers;
   mutable llvm::StringMap<size_t> Packages;
+  DiagnosticsEngine &Diags;
 };
 
 } // namespace ento
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to