================
@@ -0,0 +1,134 @@
+//===- SummaryAnalysis.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 SummaryAnalysisBase (type-erased base known to AnalysisDriver) and
+// the typed intermediate SummaryAnalysis<ResultT, EntitySummaryT> that
+// concrete analyses inherit from.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_SUMMARYANALYSIS_H
+#define 
LLVM_CLANG_SCALABLESTATICANALYSISFRAMEWORK_CORE_ANALYSIS_SUMMARYANALYSIS_H
+
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisBase.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisResult.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Analysis/AnalysisTraits.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Model/EntityId.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/Model/SummaryName.h"
+#include "clang/ScalableStaticAnalysisFramework/Core/TUSummary/EntitySummary.h"
+#include "llvm/Support/Error.h"
+#include <memory>
+
+namespace clang::ssaf {
+
+class AnalysisDriver;
+class AnalysisRegistry;
+
+/// Type-erased base for summary analyses. Known to AnalysisDriver.
+///
+/// Not subclassed directly -- use SummaryAnalysis<ResultT, EntitySummaryT>.
+/// A summary analysis processes per-entity EntitySummary objects from the
+/// LUSummary one at a time, accumulating whole-program data into an
+/// AnalysisResult.
+class SummaryAnalysisBase : public AnalysisBase {
+  friend class AnalysisDriver;
+
+protected:
+  SummaryAnalysisBase() : AnalysisBase(AnalysisBase::Kind::Summary) {}
+
+public:
+  /// SummaryName of the EntitySummary type this analysis consumes.
+  /// Used by the driver to route entities from the LUSummary.
+  virtual SummaryName summaryName() const = 0;
+
+private:
+  /// Called once before any add() calls. Default is a no-op.
+  virtual llvm::Error initialize() { return llvm::Error::success(); }
+
+  /// Called once per matching entity. The driver retains ownership of the
+  /// summary; multiple SummaryAnalysis instances may receive the same entity.
+  virtual llvm::Error add(EntityId Id, const EntitySummary &Summary) = 0;
+
+  /// Called after all entities have been processed. Default is a no-op.
+  virtual llvm::Error finalize() { return llvm::Error::success(); }
+
+  /// Transfers ownership of the built result. Called once after finalize().
+  /// The rvalue ref-qualifier enforces single use.
+  virtual std::unique_ptr<AnalysisResult> result() && = 0;
+};
+
+/// Typed intermediate that concrete summary analyses inherit from.
+///
+/// Concrete analyses must implement:
+///   llvm::Error add(EntityId Id, const EntitySummaryT &Summary) override;
+/// and may override initialize() and finalize().
+///
+/// The result being built is accessible via result() const & (read-only) and
+/// result() & (mutable) within the analysis implementation.
+template <typename ResultT, typename EntitySummaryT>
+class SummaryAnalysis : public SummaryAnalysisBase {
+  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<EntitySummary, EntitySummaryT>,
+                "EntitySummaryT must derive from EntitySummary");
+
+  friend class AnalysisRegistry;
+  using ResultType = ResultT;
+
+  std::unique_ptr<ResultT> Result;
+
+public:
+  SummaryAnalysis() : Result(std::make_unique<ResultT>()) {}
+
+  /// Used by AnalysisRegistry::Add to derive the registry entry name.
+  AnalysisName analysisName() const final { return ResultT::analysisName(); }
+
+  SummaryName summaryName() const final {
+    return EntitySummaryT::summaryName();
+  }
+
+  const std::vector<AnalysisName> &dependencyNames() const final {
+    static const std::vector<AnalysisName> Empty;
+    return Empty;
+  }
+
+  /// Called once before the first add() call. Override for initialization.
+  virtual llvm::Error initialize() override { return llvm::Error::success(); }
+
+  /// Called once per matching entity. Implement to accumulate data.
+  virtual llvm::Error add(EntityId Id, const EntitySummaryT &Summary) = 0;
+
+  /// Called after all entities have been processed. Override for
+  /// post-processing.
+  virtual llvm::Error finalize() override { return llvm::Error::success(); }
----------------
aviralg wrote:

finalize is useful here because the code in the add method will not know when 
it is called for the last time. There will likely be some processing that needs 
to run after all the entities have been added.

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