#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include "llvm/Support/YAMLTraits.h" #include "revng/ADT/UpcastablePointer.h" #include "revng/TupleTree/TupleLikeTraits.h" template void initializeOwningPointer(llvm::StringRef Kind, llvm::yaml::IO &TheIO, O &Obj) { using concrete_types = concrete_types_traits_t; if constexpr (I < std::tuple_size_v) { using type = typename std::tuple_element_t; if (llvm::StringRef(TupleLikeTraits::Name) == Kind) { Obj.reset(new type); } else { initializeOwningPointer(Kind, TheIO, Obj); } } else { TheIO.setError("No concrete type for Kind " + Kind.str()); } } template void dispatchMappingTraits(llvm::yaml::IO &TheIO, O &Obj) { using concrete_types = concrete_types_traits_t; if constexpr (I < std::tuple_size_v) { using type = typename std::tuple_element_t; if (type *Upcast = llvm::dyn_cast(Obj.get())) llvm::yaml::MappingTraits::mapping(TheIO, *Upcast); else dispatchMappingTraits(TheIO, Obj); } else { TheIO.setError("Upcastable pointer could not be upcast"); } } template struct PolymorphicMappingTraits { static void mapping(llvm::yaml::IO &TheIO, T &Obj) { // Skip empty pointers when serializing if (TheIO.outputting() && Obj.isEmpty()) return; if (!TheIO.outputting()) { std::string Kind; TheIO.mapRequired("Kind", Kind); initializeOwningPointer(Kind, TheIO, Obj); } dispatchMappingTraits(TheIO, Obj); // If kind is default-initialized, clear the pointer. if (!TheIO.outputting()) if (size_t(Obj->Kind()) == 0) Obj.reset(); } };