#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; llvm::StringRef GlobalName; public: virtual ~GlobalTupleTreeDiffBase() = default; GlobalTupleTreeDiffBase(char *ID, llvm::StringRef GlobalName) : ID(ID), GlobalName(GlobalName) {} public: virtual void serialize(llvm::raw_ostream &OS) const = 0; virtual std::optional pathAsString(const TupleTreePath &) const = 0; public: virtual std::unique_ptr clone() const = 0; public: const char *getID() const { return ID; } public: virtual bool isEmpty() const = 0; llvm::StringRef getGlobalName() const { return GlobalName; } virtual llvm::SmallVector getPaths() const = 0; }; template class GlobalTupleTreeDiffImpl : public GlobalTupleTreeDiffBase { private: TupleTreeDiff Diff; static char *getID() { static char ID; return &ID; } public: GlobalTupleTreeDiffImpl(TupleTreeDiff Diff, llvm::StringRef GlobalName) : GlobalTupleTreeDiffBase(getID(), GlobalName), Diff(std::move(Diff)) {} ~GlobalTupleTreeDiffImpl() override = default; void serialize(llvm::raw_ostream &OS) const override { ::serialize(OS, Diff); } std::optional pathAsString(const TupleTreePath &Path) const override { return pathAsString(Path); } 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; } llvm::SmallVector getPaths() const override { llvm::SmallVector ToReturn; for (const Change &Entry : Diff.Changes) { ToReturn.emplace_back(&Entry.Path); } return ToReturn; } }; class GlobalTupleTreeDiff { private: std::unique_ptr Diff; public: template GlobalTupleTreeDiff(TupleTreeDiff Diff, llvm::StringRef GlobalName) : Diff(new GlobalTupleTreeDiffImpl(std::move(Diff), GlobalName)) {} 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); } std::optional pathAsString(const TupleTreePath &Path) const { return Diff->pathAsString(Path); } void dump() const debug_function { serialize(llvm::dbgs()); } 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(); } llvm::SmallVector getPaths() const { return Diff->getPaths(); } bool isEmpty() const { return Diff.get()->isEmpty(); } llvm::StringRef getGlobalName() const { return Diff->getGlobalName(); } }; using DiffMap = llvm::StringMap; } // namespace pipeline