#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "revng/Support/YAMLTraits.h" #include "revng/TupleTree/TupleTreeDiff.h" namespace pipeline { class GlobalTupleTreeDiffBase { private: char *ID; public: virtual void serialize(llvm::raw_ostream &OS) const = 0; virtual ~GlobalTupleTreeDiffBase() = default; virtual std::unique_ptr clone() const = 0; virtual bool isEmpty() const = 0; GlobalTupleTreeDiffBase(char *ID) : ID(ID) {} const char *getID() const { return ID; } }; template class GlobalTupleTreeDiffImpl : public GlobalTupleTreeDiffBase { private: TupleTreeDiff Diff; static char *getID() { static char ID; return &ID; } public: GlobalTupleTreeDiffImpl(TupleTreeDiff Diff) : GlobalTupleTreeDiffBase(getID()), Diff(std::move(Diff)) {} ~GlobalTupleTreeDiffImpl() override = default; void serialize(llvm::raw_ostream &OS) const override { ::serialize(OS, Diff); } std::unique_ptr clone() const override { auto Ptr = new GlobalTupleTreeDiffImpl(*this); return std::unique_ptr(Ptr); } bool isEmpty() const override { return Diff.Changes.size() == 0; } static bool classof(const GlobalTupleTreeDiffBase *Base) { return Base->getID() == getID(); } TupleTreeDiff &getDiff() { return Diff; } const TupleTreeDiff &getDiff() const { return Diff; } }; class GlobalTupleTreeDiff { private: std::unique_ptr Diff; public: template GlobalTupleTreeDiff(TupleTreeDiff Diff) : Diff(new GlobalTupleTreeDiffImpl(std::move(Diff))) {} GlobalTupleTreeDiff(GlobalTupleTreeDiff &&) = default; GlobalTupleTreeDiff &operator=(GlobalTupleTreeDiff &&) = default; GlobalTupleTreeDiff(const GlobalTupleTreeDiff &Other) : Diff(Other.Diff->clone()) {} GlobalTupleTreeDiff &operator=(const GlobalTupleTreeDiff &Other) { if (this == &Other) return *this; Diff = Other.Diff->clone(); return *this; } ~GlobalTupleTreeDiff() = default; void serialize(llvm::raw_ostream &OS) const { Diff->serialize(OS); } template const TupleTreeDiff *getAs() const { const auto *Casted = llvm::dyn_cast>(Diff.get()); if (not Casted) return nullptr; return &Casted->getDiff(); } template TupleTreeDiff *getAs() { const auto *Casted = llvm::dyn_cast>(Diff.get()); if (not Casted) return nullptr; return &Casted->getDiff(); } bool isEmpty() const { return Diff.get()->isEmpty(); } }; using DiffMap = llvm::StringMap; } // namespace pipeline