llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-ssaf

Author: Aviral Goel (aviralg)

<details>
<summary>Changes</summary>

This change Introduces the analysis execution layer of the Scalable Static 
Analysis Framework. This layer bridges the LUSummary (entity summaries from the 
linker phase) to WPASuite (the collection of whole-program analysis results). 
It introduces the following classes:

  - `AnalysisResult` — base class for all per-analysis results.
  - `AnalysisBase` — minimal common base with a private kind tag used by the 
driver for dispatch
  - `SummaryAnalysis&lt;ResultT, EntitySummaryT&gt;` — processes per-entity 
EntitySummary objects from LUSummary.
  - `DerivedAnalysis&lt;ResultT, DepResultTs...&gt;` — consumes previously 
produced AnalysisResult objects.
  - `AnalysisRegistry` — unified `llvm::Registry` backed registry to register 
analyses.
  - `WPASuite` — Container bundling `EntityIdTable` and all `AnalysisResult` 
objects from a driver run.
  - `AnalysisDriver` — executes analyses topologically, feeding results of 
child analyses to parent analyses.

---

Patch is 65.33 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/186813.diff


17 Files Affected:

- (added) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisBase.h
 (+55) 
- (added) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisDriver.h
 (+96) 
- (added) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisName.h
 (+49) 
- (added) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisRegistry.h
 (+100) 
- (added) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisResult.h
 (+30) 
- (added) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisTraits.h
 (+33) 
- (added) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/DerivedAnalysis.h
 (+145) 
- (added) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/SummaryAnalysis.h
 (+134) 
- (added) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/WPASuite.h 
(+96) 
- (modified) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/EntityLinker/LUSummary.h
 (+1) 
- (modified) 
clang/include/clang/ScalableStaticAnalysisFramework/Core/Support/FormatProviders.h
 (+8) 
- (added) 
clang/lib/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisDriver.cpp 
(+207) 
- (added) 
clang/lib/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisName.cpp (+16) 
- (added) 
clang/lib/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisRegistry.cpp 
(+44) 
- (modified) clang/lib/ScalableStaticAnalysisFramework/Core/CMakeLists.txt (+3) 
- (added) 
clang/unittests/ScalableStaticAnalysisFramework/Analysis/AnalysisDriverTest.cpp 
(+553) 
- (modified) clang/unittests/ScalableStaticAnalysisFramework/CMakeLists.txt 
(+1) 


``````````diff
diff --git 
a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisBase.h
 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisBase.h
new file mode 100644
index 0000000000000..29c46f3c2e544
--- /dev/null
+++ 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisBase.h
@@ -0,0 +1,55 @@
+//===- AnalysisBase.h 
-----------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Minimal common base for SummaryAnalysisBase and DerivedAnalysisBase.
+// Carries the identity (analysisName()) and dependency list
+// (dependencyNames()) shared by every analysis regardless of kind.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISBASE_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISBASE_H
+
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisName.h"
+#include <vector>
+
+namespace clang::ssaf {
+
+class AnalysisDriver;
+class SummaryAnalysisBase;
+class DerivedAnalysisBase;
+
+/// Minimal common base for both analysis kinds.
+///
+/// Not subclassed directly -- use SummaryAnalysis<...> or
+/// DerivedAnalysis<...> instead.
+class AnalysisBase {
+  friend class AnalysisDriver;
+  friend class SummaryAnalysisBase;
+  friend class DerivedAnalysisBase;
+
+  enum class Kind { Summary, Derived };
+  Kind TheKind;
+
+protected:
+  explicit AnalysisBase(Kind K) : TheKind(K) {}
+
+public:
+  virtual ~AnalysisBase() = default;
+
+  /// Name of this analysis. Equal to ResultT::analysisName() in both typed
+  /// intermediates.
+  virtual AnalysisName analysisName() const = 0;
+
+  /// AnalysisNames of all AnalysisResult dependencies.
+  virtual const std::vector<AnalysisName> &dependencyNames() const = 0;
+};
+
+} // namespace clang::ssaf
+
+#endif // 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISBASE_H
diff --git 
a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisDriver.h
 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisDriver.h
new file mode 100644
index 0000000000000..c17cd584f2434
--- /dev/null
+++ 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisDriver.h
@@ -0,0 +1,96 @@
+//===- AnalysisDriver.h 
---------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Central orchestrator for whole-program analysis. Takes ownership of an
+// LUSummary, drives all registered analyses in topological dependency order,
+// and returns a WPASuite.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISDRIVER_H
+#define 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISDRIVER_H
+
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/WPASuite.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/EntityLinker/LUSummary.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Error.h"
+#include <memory>
+#include <vector>
+
+namespace clang::ssaf {
+
+class AnalysisBase;
+class SummaryAnalysisBase;
+class DerivedAnalysisBase;
+
+/// Orchestrates whole-program analysis over an LUSummary.
+///
+/// Three run() patterns are supported:
+///   - run() &&        -- all registered analyses in topological dependency
+///                        order. Returns an error if any registered analysis
+///                        has no matching entity data in the LUSummary.
+///                        Requires an rvalue driver because this exhausts the
+///                        LUSummary.
+///   - run(names)      -- named subset plus transitive dependencies; returns
+///                        Expected and fails if any listed name has no
+///                        registered analysis or missing entity data.
+///   - run<ResultTs..> -- type-safe variant of run(names).
+class AnalysisDriver final {
+public:
+  explicit AnalysisDriver(std::unique_ptr<LUSummary> LU);
+
+  /// Runs all registered analyses in topological dependency order.
+  /// Returns an error if any registered analysis has no matching entity data
+  /// in the LUSummary.
+  ///
+  /// Requires an rvalue driver (std::move(Driver).run()) because this
+  /// exhausts all remaining LUSummary data.
+  [[nodiscard]] llvm::Expected<WPASuite> run() &&;
+
+  /// Runs only the named analyses (plus their transitive dependencies).
+  ///
+  /// Returns an error if any listed AnalysisName has no registered analysis
+  /// or if a required SummaryAnalysis has no matching entity data in the
+  /// LUSummary. The EntityIdTable is copied (not moved) so the driver remains
+  /// usable for subsequent calls.
+  [[nodiscard]] llvm::Expected<WPASuite>
+  run(llvm::ArrayRef<AnalysisName> Names);
+
+  /// Type-safe variant of run(names). Derives names from
+  /// ResultTs::analysisName().
+  template <typename... ResultTs> [[nodiscard]] llvm::Expected<WPASuite> run() 
{
+    return run({ResultTs::analysisName()...});
+  }
+
+private:
+  std::unique_ptr<LUSummary> LU;
+
+  /// Instantiates all analyses reachable from \p Roots (plus transitive
+  /// dependencies) and returns them in topological order via a single DFS.
+  /// Reports an error on unregistered names or cycles.
+  static llvm::Expected<std::vector<std::unique_ptr<AnalysisBase>>>
+  sort(llvm::ArrayRef<AnalysisName> Roots);
+
+  /// Executes a topologically-sorted analysis list and returns a WPASuite.
+  /// \p IdTable is moved into the returned WPASuite.
+  llvm::Expected<WPASuite>
+  execute(EntityIdTable IdTable,
+          std::vector<std::unique_ptr<AnalysisBase>> Sorted);
+
+  llvm::Error
+  executeSummaryAnalysis(std::unique_ptr<SummaryAnalysisBase> Summary,
+                         WPASuite &Suite);
+
+  llvm::Error
+  executeDerivedAnalysis(std::unique_ptr<DerivedAnalysisBase> Derived,
+                         WPASuite &Suite);
+};
+
+} // namespace clang::ssaf
+
+#endif // 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISDRIVER_H
diff --git 
a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisName.h
 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisName.h
new file mode 100644
index 0000000000000..73ba96ccc594e
--- /dev/null
+++ 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisName.h
@@ -0,0 +1,49 @@
+//===- AnalysisName.h 
-----------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Strong typedef identifying a whole-program analysis and its result type.
+// Distinct from SummaryName, which identifies per-entity EntitySummary types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISNAME_H
+#define LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISNAME_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+
+namespace clang::ssaf {
+
+/// Uniquely identifies a whole-program analysis and the AnalysisResult it
+/// produces. Used as the key in WPASuite and AnalysisRegistry.
+///
+/// Distinct from SummaryName, which is used by EntitySummary types for routing
+/// through the LUSummary.
+class AnalysisName {
+public:
+  explicit AnalysisName(std::string Name) : Name(std::move(Name)) {}
+
+  bool operator==(const AnalysisName &Other) const {
+    return Name == Other.Name;
+  }
+  bool operator!=(const AnalysisName &Other) const { return !(*this == Other); 
}
+  bool operator<(const AnalysisName &Other) const { return Name < Other.Name; }
+
+  /// Explicit conversion to the underlying string representation.
+  llvm::StringRef str() const { return Name; }
+
+private:
+  std::string Name;
+};
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const AnalysisName &AN);
+
+} // namespace clang::ssaf
+
+#endif // 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISNAME_H
diff --git 
a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisRegistry.h
 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisRegistry.h
new file mode 100644
index 0000000000000..4ed5999bda477
--- /dev/null
+++ 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisRegistry.h
@@ -0,0 +1,100 @@
+//===- AnalysisRegistry.h 
-------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Unified registry for both SummaryAnalysis and DerivedAnalysis subclasses.
+//
+// To register an analysis, add a static Add<AnalysisT> in its translation
+// unit:
+//
+//   static AnalysisRegistry::Add<MyAnalysis>
+//       Registered("One-line description of MyAnalysis");
+//
+// The registry entry name is derived automatically from
+// MyAnalysis::analysisName(), so name-mismatch bugs are impossible.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISREGISTRY_H
+#define 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISREGISTRY_H
+
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisName.h"
+#include 
"clang/ScalableStaticAnalysisFramework/Core/Analysis/DerivedAnalysis.h"
+#include 
"clang/ScalableStaticAnalysisFramework/Core/Analysis/SummaryAnalysis.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Support/ErrorBuilder.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Registry.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang::ssaf {
+
+/// Unified registry for SummaryAnalysis and DerivedAnalysis implementations.
+///
+/// Internally uses a single llvm::Registry<AnalysisBase>. The correct kind
+/// is carried by the AnalysisBase::TheKind tag set in each subclass
+/// constructor.
+class AnalysisRegistry {
+  using RegistryT = llvm::Registry<AnalysisBase>;
+
+  AnalysisRegistry() = delete;
+
+public:
+  /// Registers AnalysisT with the unified registry.
+  ///
+  /// The registry entry name is derived automatically from
+  /// AnalysisT::ResultType::analysisName(), so name-mismatch bugs are
+  /// impossible.
+  ///
+  /// Add objects must be declared static at namespace scope.
+  template <typename AnalysisT> struct Add {
+    static_assert(std::is_base_of_v<SummaryAnalysisBase, AnalysisT> ||
+                      std::is_base_of_v<DerivedAnalysisBase, AnalysisT>,
+                  "AnalysisT must derive from SummaryAnalysis<...> or "
+                  "DerivedAnalysis<...>");
+
+    explicit Add(llvm::StringRef Desc)
+        : Name(AnalysisT::ResultType::analysisName().str().str()),
+          Node(Name, Desc) {
+      if (contains(Name)) {
+        ErrorBuilder::fatal("duplicate analysis registration for '{0}'", Name);
+      }
+      getAnalysisNames().push_back(AnalysisT::ResultType::analysisName());
+    }
+
+    Add(const Add &) = delete;
+    Add &operator=(const Add &) = delete;
+
+  private:
+    std::string Name;
+    RegistryT::Add<AnalysisT> Node;
+  };
+
+  /// Returns true if an analysis is registered under \p Name.
+  static bool contains(llvm::StringRef Name);
+
+  /// Returns the names of all registered analyses.
+  static const std::vector<AnalysisName> &names();
+
+  /// Instantiates the analysis registered under \p Name, or returns an error
+  /// if no such analysis is registered.
+  static llvm::Expected<std::unique_ptr<AnalysisBase>>
+  instantiate(llvm::StringRef Name);
+
+private:
+  /// Returns the global list of registered analysis names.
+  ///
+  /// Uses a function-local static to avoid static initialization order
+  /// fiasco: Add<T> objects in other translation units may push names before
+  /// a plain static data member could be constructed.
+  static std::vector<AnalysisName> &getAnalysisNames();
+};
+
+} // namespace clang::ssaf
+
+#endif // 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISREGISTRY_H
diff --git 
a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisResult.h
 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisResult.h
new file mode 100644
index 0000000000000..7ac2a9ad7db6a
--- /dev/null
+++ 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisResult.h
@@ -0,0 +1,30 @@
+//===- AnalysisResult.h 
---------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Base class for all whole-program analysis results produced by 
AnalysisDriver.
+// Concrete subclasses carry a static analysisName().
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISRESULT_H
+#define 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISRESULT_H
+
+namespace clang::ssaf {
+
+/// Base class for whole-program analysis results.
+///
+/// Concrete subclasses must provide:
+///   static AnalysisName analysisName();
+class AnalysisResult {
+public:
+  virtual ~AnalysisResult() = default;
+};
+
+} // namespace clang::ssaf
+
+#endif // 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISRESULT_H
diff --git 
a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisTraits.h
 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisTraits.h
new file mode 100644
index 0000000000000..ef6a5a56d990a
--- /dev/null
+++ 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisTraits.h
@@ -0,0 +1,33 @@
+//===- AnalysisTraits.h 
---------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Type traits for AnalysisResult subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISTRAITS_H
+#define 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISTRAITS_H
+
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisName.h"
+#include <type_traits>
+
+namespace clang::ssaf {
+
+/// Type trait that checks whether \p T has a static \c analysisName() method
+/// returning \c AnalysisName. Used to enforce the convention on AnalysisResult
+/// subclasses and analysis classes at instantiation time.
+template <typename T, typename = void>
+struct HasAnalysisName : std::false_type {};
+
+template <typename T>
+struct HasAnalysisName<T, std::void_t<decltype(T::analysisName())>>
+    : std::is_same<decltype(T::analysisName()), AnalysisName> {};
+
+} // namespace clang::ssaf
+
+#endif // 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_ANALYSISTRAITS_H
diff --git 
a/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/DerivedAnalysis.h
 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/DerivedAnalysis.h
new file mode 100644
index 0000000000000..7066f3451a3d0
--- /dev/null
+++ 
b/clang/include/clang/ScalableStaticAnalysisFramework/Core/Analysis/DerivedAnalysis.h
@@ -0,0 +1,145 @@
+//===- DerivedAnalysis.h 
--------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines DerivedAnalysisBase (type-erased base known to AnalysisDriver) and
+// the typed intermediate DerivedAnalysis<ResultT, DepResultTs...> that
+// concrete analyses inherit from.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_DERIVEDANALYSIS_H
+#define 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_DERIVEDANALYSIS_H
+
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisBase.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisName.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisResult.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisTraits.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Support/ErrorBuilder.h"
+#include "llvm/Support/Error.h"
+#include <map>
+#include <memory>
+#include <vector>
+
+namespace clang::ssaf {
+
+class AnalysisDriver;
+class AnalysisRegistry;
+
+/// Type-erased base for derived analyses. Known to AnalysisDriver.
+///
+/// Not subclassed directly -- use DerivedAnalysis<ResultT, DepResultTs...>.
+/// A derived analysis consumes previously produced AnalysisResult objects
+/// and computes a new one via an initialize/step/finalize lifecycle.
+class DerivedAnalysisBase : public AnalysisBase {
+  friend class AnalysisDriver;
+
+protected:
+  DerivedAnalysisBase() : AnalysisBase(AnalysisBase::Kind::Derived) {}
+
+private:
+  /// Called once with the dependency results before the step() loop.
+  ///
+  /// \param DepResults  Immutable results of all declared dependencies, keyed
+  ///                    by AnalysisName. Guaranteed to contain every name
+  ///                    returned by dependencyNames().
+  virtual llvm::Error initialize(
+      const std::map<AnalysisName, const AnalysisResult *> &DepResults) = 0;
+
+  /// Performs one pass. Returns true if another pass is needed; false when
+  /// converged.
+  virtual llvm::Expected<bool> step() = 0;
+
+  /// Called after the step() loop converges. Default is a no-op.
+  virtual llvm::Error finalize() { return llvm::Error::success(); }
+
+  /// Transfers ownership of the computed result. Called once after finalize().
+  virtual std::unique_ptr<AnalysisResult> result() && = 0;
+};
+
+/// Typed intermediate that concrete derived analyses inherit from.
+///
+/// Concrete analyses must implement:
+///   llvm::Error initialize(const DepResultTs &...) override;
+///   llvm::Expected<bool> step() override;
+/// and may override finalize().
+///
+/// Dependencies are fixed for the lifetime of the analysis: initialize()
+/// binds them once, step() is called until it returns false, and
+/// finalize() post-processes after convergence.
+template <typename ResultT, typename... DepResultTs>
+class DerivedAnalysis : public DerivedAnalysisBase {
+  static_assert(std::is_base_of_v<AnalysisResult, ResultT>,
+                "ResultT must derive from AnalysisResult");
+  static_assert(HasAnalysisName<ResultT>::value,
+                "ResultT must have a static analysisName() method");
+  static_assert((std::is_base_of_v<AnalysisResult, DepResultTs> && ...),
+                "Every DepResultT must derive from AnalysisResult");
+  static_assert((HasAnalysisName<DepResultTs>::value && ...),
+                "...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/186813
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to