[clang] [NFC][analyzer] Framework for multipart checkers (PR #130985)

DonĂ¡t Nagy via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 14 06:10:52 PDT 2025


================
@@ -190,23 +203,38 @@ class CheckerManager {
   // Checker registration.
   //===--------------------------------------------------------------------===//
 
-  /// Used to register checkers.
-  /// All arguments are automatically passed through to the checker
-  /// constructor.
+  /// Construct the singleton instance of a checker, register it for the
+  /// supported callbacks and record its name with `registerCheckerPart()`.
+  /// Arguments passed to this function are forwarded to the constructor of the
+  /// checker.
+  ///
+  /// If `CHECKER` has multiple parts, then the constructor call and the
+  /// callback registration only happen within the first `registerChecker()`
+  /// call; while the subsequent calls only enable additional parts of the
+  /// existing checker object (while registering their names).
   ///
   /// \returns a pointer to the checker object.
-  template <typename CHECKER, typename... AT>
-  CHECKER *registerChecker(AT &&... Args) {
+  template <typename CHECKER, CheckerPartIdx Idx = DefaultPart, typename... AT>
+  CHECKER *registerChecker(AT &&...Args) {
+    // This assert could be removed but then need to make sure that calls that
+    // register different parts of the same checker pass the same arguments.
+    static_assert(
+        Idx == DefaultPart || !sizeof...(AT),
+        "Argument forwarding isn't supported with multi-part checkers!");
+
     CheckerTag Tag = getTag<CHECKER>();
-    std::unique_ptr<CheckerBase> &Ref = CheckerTags[Tag];
-    assert(!Ref && "Checker already registered, use getChecker!");
 
-    std::unique_ptr<CHECKER> Checker =
-        std::make_unique<CHECKER>(std::forward<AT>(Args)...);
-    Checker->Name = CurrentCheckerName;
-    CHECKER::_register(Checker.get(), *this);
-    Ref = std::move(Checker);
-    return static_cast<CHECKER *>(Ref.get());
+    std::unique_ptr<CheckerBase> &Ref = CheckerTags[Tag];
+    if (!Ref) {
+      std::unique_ptr<CHECKER> Checker =
+          std::make_unique<CHECKER>(std::forward<AT>(Args)...);
+      CHECKER::_register(Checker.get(), *this);
+      Ref = std::move(Checker);
----------------
NagyDonat wrote:

Note that `CHECKER::template _register<CHECKER>(Ref.get(), *this);` does not work either, but I don't know why.

https://github.com/llvm/llvm-project/pull/130985


More information about the cfe-commits mailing list