================ @@ -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 && ...), + "Every DepResultT must have a static analysisName() method"); + + friend class AnalysisRegistry; + using ResultType = ResultT; ---------------- steakhal wrote:
Got it! https://github.com/llvm/llvm-project/pull/186813 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
