#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "revng/Pipeline/PathComponent.h" #include "revng/Pipeline/Rank.h" #include "revng/Pipeline/RegisterKind.h" #include "revng/Support/Assert.h" namespace pipeline { class Target; class Context; class TargetsList; class ContainerBase; class InvalidationEventBase; /// A Kind is used to accumunate objects that logically belongs to the same /// cathegory. /// /// As an example, the Kind of Isolated Functions, the Kind of translated /// binaries. /// /// A kind refers to a rank which is used by Targets, furthermore a Kind /// can optionally have a Parent Kind. Again this is used mostly by targets. /// /// If you wish to declare a kind to be used in a llvm container, declare a /// LLVMKind instead. class Kind : public DynamicHierarchy { private: RegisterKind Register; const Rank *TheRank; public: Kind(llvm::StringRef Name, const Rank *TheRank) : DynamicHierarchy(Name), Register(*this), TheRank(TheRank) { revng_assert(TheRank != nullptr); } Kind(llvm::StringRef Name, Kind &Parent, const Rank *TheRank) : DynamicHierarchy(Name, Parent), Register(*this), TheRank(TheRank) { revng_assert(TheRank != nullptr); } /// Kinds may provide a override for this method. Thye must return success if /// ToVerify (which always has this kind as a kind), well formed inside /// Container (which always contains ToVerify). virtual llvm::Error verify(const ContainerBase &Container, const Target &ToVerify) const; public: size_t depth() const { return TheRank->depth(); } const Rank &rank() const { return *TheRank; } public: virtual ~Kind() = default; /// A Kind can have a expand target method, which will be used to expand all /// targets that rapresents a collection of objects rather than a scalar one. /// /// As an example, the espansion of Input equal to /Root/* of isolated /// functions kind will create a target equivalent to /Root/FX for each FX /// container in the revng model. virtual void expandTarget(const Context &Ctx, const Target &Input, TargetsList &Output) const; virtual void getInvalidations(pipeline::TargetsList &ToRemove, const InvalidationEventBase &Event) const {} public: template static Kind &deadKind() { static Kind DeadKind("Dead", R); return DeadKind; } }; } // namespace pipeline