#include "CodegenInput.hpp" #include #include #include #include struct SomeDecl { std::variant v; }; class CodegenInput::Private { public: // We want address stability for everything robin_hood::unordered_node_map decls; robin_hood::unordered_node_map namespaces; }; CodegenInput::CodegenInput() : m{ new Private() } // { } CodegenInput::~CodegenInput() { delete m; } #define STORE_DECL_OF_TYPE(DeclType, fullname, decl) \ auto [iter, success] = m->decls.try_emplace(std::move(fullname), SomeDecl{ .v = std::move(decl) }); \ auto& key = iter->first; \ auto& val = iter->second; \ auto& declRef = std::get(val.v); \ declRef.fullname = key; \ return &declRef DeclEnum* CodegenInput::AddEnum(std::string fullname, DeclEnum decl) { #if CODEGEN_DEBUG_PRINT printf("Committed enum '%s'\n", decl.name.c_str()); for (auto& elm : decl.elements) { printf(" - element %s = %" PRId64 "\n", elm.name.c_str(), elm.value); } #endif STORE_DECL_OF_TYPE(DeclEnum, fullname, decl); } DeclStruct* CodegenInput::AddStruct(std::string fullname, DeclStruct decl) { #if CODEGEN_DEBUG_PRINT printf("Committed struct '%s'\n", decl.name.c_str()); printf(" Base classes:\n"); for (auto& base : decl.baseClasses) { printf(" - %.*s\n", PRINTF_STRING_VIEW(base->name)); } #endif STORE_DECL_OF_TYPE(DeclStruct, fullname, decl); } #define FIND_DECL_OF_TYPE(DeclType) \ auto iter = m->decls.find(name); \ if (iter != m->decls.end()) { \ auto& some = iter->second.v; \ if (auto decl = std::get_if(&some)) { \ return decl; \ } \ } \ return nullptr const DeclEnum* CodegenInput::FindEnum(std::string_view name) const { FIND_DECL_OF_TYPE(DeclEnum); } const DeclStruct* CodegenInput::FindStruct(std::string_view name) const { FIND_DECL_OF_TYPE(DeclStruct); } DeclNamespace* CodegenInput::AddNamespace(DeclNamespace ns) { auto path = Utils::MakeFullName(""sv, &ns); auto [iter, success] = m->namespaces.try_emplace(std::move(path), std::move(ns)); auto& nsRef = iter->second; if (success) { nsRef.fullname = iter->first; } return &nsRef; } const DeclNamespace* CodegenInput::FindNamespace(std::string_view fullname) const { auto iter = m->namespaces.find(fullname); if (iter != m->namespaces.end()) { return &iter->second; } else { return nullptr; } } DeclNamespace* CodegenInput::FindNamespace(std::string_view name) { return const_cast(const_cast(this)->FindNamespace(name)); }