Szelethus created this revision.
Szelethus added reviewers: NoQ, xazax.hun, rnkovacs, Charusso, dcoughlin, 
baloghadamsoftware.
Szelethus added a project: clang.
Herald added subscribers: cfe-commits, gamesh411, dkrupp, donat.nagy, 
mikhail.ramalho, a.sidorin, szepet, whisperity.

Nothing exciting to see here! The new interface allows for more fine tuning 
(register but disable a checker, add custom checker registry functions, etc), 
that was basically the point.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D67335

Files:
  clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
  clang/unittests/StaticAnalyzer/CheckerRegistration.h
  clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp

Index: clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
===================================================================
--- clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
+++ clang/unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp
@@ -6,11 +6,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "CheckerRegistration.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
 #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
 #include "clang/Tooling/Tooling.h"
@@ -20,52 +22,10 @@
 namespace ento {
 namespace {
 
-template <typename CheckerT>
-class TestAction : public ASTFrontendAction {
-  class DiagConsumer : public PathDiagnosticConsumer {
-    llvm::raw_ostream &Output;
-
-  public:
-    DiagConsumer(llvm::raw_ostream &Output) : Output(Output) {}
-    void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                              FilesMade *filesMade) override {
-      for (const auto *PD : Diags)
-        Output << PD->getCheckerName() << ":" << PD->getShortDescription();
-    }
-
-    StringRef getName() const override { return "Test"; }
-  };
-
-  llvm::raw_ostream &DiagsOutput;
-
-public:
-  TestAction(llvm::raw_ostream &DiagsOutput) : DiagsOutput(DiagsOutput) {}
-
-  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
-                                                 StringRef File) override {
-    std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer =
-        CreateAnalysisConsumer(Compiler);
-    AnalysisConsumer->AddDiagnosticConsumer(new DiagConsumer(DiagsOutput));
-    Compiler.getAnalyzerOpts()->CheckersAndPackages = {
-        {"custom.CustomChecker", true}};
-    AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
-      Registry.addChecker<CheckerT>("custom.CustomChecker", "Description", "");
-    });
-    return std::move(AnalysisConsumer);
-  }
-};
-
-template <typename CheckerT>
-bool runCheckerOnCode(const std::string &Code, std::string &Diags) {
-  llvm::raw_string_ostream OS(Diags);
-  return tooling::runToolOnCode(new TestAction<CheckerT>(OS), Code);
-}
-template <typename CheckerT>
-bool runCheckerOnCode(const std::string &Code) {
-  std::string Diags;
-  return runCheckerOnCode<CheckerT>(Code, Diags);
-}
-
+//===----------------------------------------------------------------------===//
+// Just a minimal test for how checker registration works with statically
+// linked, non TableGen generated checkers.
+//===----------------------------------------------------------------------===//
 
 class CustomChecker : public Checker<check::ASTCodeBody> {
 public:
@@ -77,12 +37,25 @@
   }
 };
 
+void addCustomChecker(AnalysisASTConsumer &AnalysisConsumer,
+                      AnalyzerOptions &AnOpts) {
+  AnOpts.CheckersAndPackages = {{"custom.CustomChecker", true}};
+  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
+    Registry.addChecker<CustomChecker>("custom.CustomChecker", "Description",
+                                       "");
+  });
+}
+
 TEST(RegisterCustomCheckers, RegisterChecker) {
   std::string Diags;
-  EXPECT_TRUE(runCheckerOnCode<CustomChecker>("void f() {;}", Diags));
-  EXPECT_EQ(Diags, "custom.CustomChecker:Custom diagnostic description");
+  EXPECT_TRUE(runCheckerOnCode<addCustomChecker>("void f() {;}", Diags));
+  EXPECT_EQ(Diags, "custom.CustomChecker:Custom diagnostic description\n");
 }
 
+//===----------------------------------------------------------------------===//
+// Pretty much the same.
+//===----------------------------------------------------------------------===//
+
 class LocIncDecChecker : public Checker<check::Location> {
 public:
   void checkLocation(SVal Loc, bool IsLoad, const Stmt *S,
@@ -94,11 +67,20 @@
   }
 };
 
+void addLocIncDecChecker(AnalysisASTConsumer &AnalysisConsumer,
+                         AnalyzerOptions &AnOpts) {
+  AnOpts.CheckersAndPackages = {{"test.LocIncDecChecker", true}};
+  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
+    Registry.addChecker<CustomChecker>("test.LocIncDecChecker", "Description",
+                                       "");
+  });
+}
+
 TEST(RegisterCustomCheckers, CheckLocationIncDec) {
   EXPECT_TRUE(
-      runCheckerOnCode<LocIncDecChecker>("void f() { int *p; (*p)++; }"));
+      runCheckerOnCode<addLocIncDecChecker>("void f() { int *p; (*p)++; }"));
 }
 
-}
-}
-}
+} // namespace
+} // namespace ento
+} // namespace clang
Index: clang/unittests/StaticAnalyzer/CheckerRegistration.h
===================================================================
--- /dev/null
+++ clang/unittests/StaticAnalyzer/CheckerRegistration.h
@@ -0,0 +1,81 @@
+//===- unittests/StaticAnalyzer/RegisterCustomCheckersTest.cpp ------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
+#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
+#include "clang/Tooling/Tooling.h"
+
+namespace clang {
+namespace ento {
+
+class DiagConsumer : public PathDiagnosticConsumer {
+  llvm::raw_ostream &Output;
+
+public:
+  DiagConsumer(llvm::raw_ostream &Output) : Output(Output) {}
+  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
+                            FilesMade *filesMade) override {
+    for (const auto *PD : Diags)
+      Output << PD->getCheckerName() << ":" << PD->getShortDescription() << '\n';
+  }
+
+  StringRef getName() const override { return "Test"; }
+};
+
+using AddCheckerFn = void(AnalysisASTConsumer &AnalysisConsumer,
+                          AnalyzerOptions &AnOpts);
+
+template <AddCheckerFn Fn1, AddCheckerFn Fn2, AddCheckerFn... Fns>
+void addChecker(AnalysisASTConsumer &AnalysisConsumer,
+                AnalyzerOptions &AnOpts) {
+  Fn1(AnalysisConsumer, AnOpts);
+  addChecker<Fn2, Fns...>(AnalysisConsumer, AnOpts);
+}
+
+template <AddCheckerFn Fn1>
+void addChecker(AnalysisASTConsumer &AnalysisConsumer,
+                AnalyzerOptions &AnOpts) {
+  Fn1(AnalysisConsumer, AnOpts);
+}
+
+template <AddCheckerFn... Fns>
+class TestAction : public ASTFrontendAction {
+  llvm::raw_ostream &DiagsOutput;
+
+public:
+  TestAction(llvm::raw_ostream &DiagsOutput) : DiagsOutput(DiagsOutput) {}
+
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &Compiler,
+                                                 StringRef File) override {
+    std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer =
+        CreateAnalysisConsumer(Compiler);
+    AnalysisConsumer->AddDiagnosticConsumer(new DiagConsumer(DiagsOutput));
+    addChecker<Fns...>(*AnalysisConsumer, *Compiler.getAnalyzerOpts());
+    return std::move(AnalysisConsumer);
+  }
+};
+
+template <AddCheckerFn... Fns>
+bool runCheckerOnCode(const std::string &Code, std::string &Diags) {
+  llvm::raw_string_ostream OS(Diags);
+  return tooling::runToolOnCode(new TestAction<Fns...>(OS), Code);
+}
+
+template <AddCheckerFn... Fns>
+bool runCheckerOnCode(const std::string &Code) {
+  std::string Diags;
+  return runCheckerOnCode<Fns...>(Code, Diags);
+}
+
+} // namespace ento
+} // namespace clang
Index: clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
+++ clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
@@ -204,16 +204,14 @@
 
   using PackageInfoList = llvm::SmallVector<PackageInfo, 0>;
 
-private:
-  template <typename T> static void initializeManager(CheckerManager &mgr) {
+  template <typename T> static void addToCheckerMgr(CheckerManager &mgr) {
     mgr.registerChecker<T>();
   }
 
-  template <typename T> static bool returnTrue(const LangOptions &LO) {
+  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,
@@ -227,8 +225,8 @@
                   bool IsHidden = false) {
     // Avoid MSVC's Compiler Error C2276:
     // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
-    addChecker(&CheckerRegistry::initializeManager<T>,
-               &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri,
+    addChecker(&CheckerRegistry::addToCheckerMgr<T>,
+               &CheckerRegistry::returnTrue, FullName, Desc, DocsUri,
                IsHidden);
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to