#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include "llvm/ADT/ArrayRef.h" #include "revng/Pipeline/Invokable.h" #include "revng/Pipeline/Pipe.h" namespace pipeline { template class AnalysisWrapperImpl; class AnalysisWrapperBase : public InvokableWrapperBase { private: std::string BoundName; public: template using ImplType = AnalysisWrapperImpl; public: virtual ~AnalysisWrapperBase() override = default; virtual llvm::ArrayRef getAcceptedKinds(size_t ContainerIndex) const = 0; virtual bool isAvailable() const = 0; virtual std::unique_ptr clone(std::vector NewRunningContainersNames = {}) const = 0; void invalidate(const GlobalTupleTreeDiff &Diff, ContainerToTargetsMap &Map, const ContainerSet &Containers) const override { revng_abort(); } const std::string &getUserBoundName() const { return BoundName; } void setUserBoundName(std::string NewName) { BoundName = std::move(NewName); } }; template concept HasIsAvailable = requires(T V) { { T::isAvailable() } -> std::same_as; }; template class AnalysisWrapperImpl : public AnalysisWrapperBase { private: InvokableWrapperImpl Invokable; public: AnalysisWrapperImpl(Analysis ActualPipe, std::vector RunningContainersNames) : Invokable(std::move(ActualPipe), std::move(RunningContainersNames)) {} AnalysisWrapperImpl(AnalysisWrapperImpl ActualPipe, std::vector RunningContainersNames) : Invokable(std::move(ActualPipe.Invokable), std::move(RunningContainersNames)) {} ~AnalysisWrapperImpl() override = default; public: std::unique_ptr clone(std::vector NewContainersNames = {}) const override { if (NewContainersNames.empty()) return std::make_unique(*this); return std::make_unique(*this, std::move(NewContainersNames)); } llvm::ArrayRef getAcceptedKinds(size_t ContainerIndex) const override { return Invokable.getPipe().AcceptedKinds.at(ContainerIndex); } bool isAvailable() const override { if constexpr (HasIsAvailable) return Analysis::isAvailable(); else return true; } void dump(std::ostream &OS, size_t Indentation) const override { Invokable.dump(OS, Indentation); } llvm::Error run(ExecutionContext &Context, ContainerSet &Containers, const llvm::StringMap &ExtraArgs) override { return Invokable.run(Context, Containers, ExtraArgs); } void invalidate(const GlobalTupleTreeDiff &Diff, ContainerToTargetsMap &Map, const ContainerSet &Containers) const override { revng_abort(); } std::vector getOptionsNames() const override { return Invokable.getOptionsNames(); } std::vector getOptionsTypes() const override { return Invokable.getOptionsTypes(); } std::vector getRunningContainersNames() const override { return Invokable.getRunningContainersNames(); } bool isContainerArgumentConst(size_t ArgumentIndex) const override { return Invokable.isContainerArgumentConst(ArgumentIndex); } std::string getName() const override { return Invokable.getName(); } }; using AnalysisWrapper = InvokableWrapper; } // namespace pipeline