#include #include #include static UID next_uid = 0; static std::unordered_map targets; static tree get_record_main_variant(tree t) { if (!t || TREE_CODE(t) != RECORD_TYPE) return NULL_TREE; return TYPE_MAIN_VARIANT(t); } TargetType::TargetType(tree t) : m_uid{ UID_INVALID }, m_flags{ 0 } { if (!(m_main_variant = get_record_main_variant(t))) return; m_flags |= FLAG_MAIN_VARIANT; } TargetType::~TargetType() {} bool TargetType::valid() const { return (m_flags & FLAG_MAIN_VARIANT) != 0; } bool TargetType::fields() const { return (m_flags & FLAG_FIELDS) != 0; } bool TargetType::fetch_fields() { // TODO return false; } void TargetType::add(tree t) { if (find(t) != nullptr) return; TargetType tmp { t }; if (!tmp.valid()) return; tmp.m_uid = next_uid++; targets.emplace(tmp.m_uid, tmp); } std::size_t TargetType::count() { return targets.size(); } const TargetType* TargetType::find(tree t) { tree main_variant = get_record_main_variant(t); if (!main_variant) return nullptr; for (const auto& [uid, target] : targets) { if (lang_hooks.types_compatible_p(main_variant, target.m_main_variant)) return ⌖ } return nullptr; } const TargetType* TargetType::find(UID uid) { auto it = targets.find(uid); if (it == targets.end()) return nullptr; return &it->second; }