From a30678cee330425acd37f29a43007d05dcb62d0b Mon Sep 17 00:00:00 2001 From: Ben Lubar Date: Sat, 29 Feb 2020 13:11:23 -0600 Subject: [PATCH] subclass struct_identity for unions --- library/DataDefs.cpp | 7 +++++++ library/LuaTypes.cpp | 2 +- library/LuaWrapper.cpp | 2 ++ library/include/DataDefs.h | 21 ++++++++++++++++++--- library/xml | 2 +- plugins/devel/check-structures-sanity.cpp | 6 ++++-- 6 files changed, 33 insertions(+), 7 deletions(-) diff --git a/library/DataDefs.cpp b/library/DataDefs.cpp index 5952e3da1..92bd19fd4 100644 --- a/library/DataDefs.cpp +++ b/library/DataDefs.cpp @@ -224,6 +224,13 @@ std::string df::buffer_container_identity::getFullName(type_identity *item) (size > 0 ? stl_sprintf("[%d]", size) : std::string("[]")); } +union_identity::union_identity(size_t size, TAllocateFn alloc, + compound_identity *scope_parent, const char *dfhack_name, + struct_identity *parent, const struct_field_info *fields) + : struct_identity(size, alloc, scope_parent, dfhack_name, parent, fields) +{ +} + virtual_identity::virtual_identity(size_t size, TAllocateFn alloc, const char *dfhack_name, const char *original_name, virtual_identity *parent, const struct_field_info *fields, diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index f744f3eba..3144ff7a6 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -1179,7 +1179,7 @@ static void IndexFields(lua_State *state, int base, struct_identity *pstruct, bo case struct_field_info::POINTER: // Skip class-typed pointers within unions and other bad pointers - if ((fields[i].count & 2) != 0 && fields[i].type) + if ((pstruct->type() == IDTYPE_UNION || (fields[i].count & 2) != 0) && fields[i].type) add_to_enum = false; break; diff --git a/library/LuaWrapper.cpp b/library/LuaWrapper.cpp index ef41d8076..3b8471d27 100644 --- a/library/LuaWrapper.cpp +++ b/library/LuaWrapper.cpp @@ -296,6 +296,7 @@ bool LuaWrapper::is_type_compatible(lua_State *state, type_identity *type1, int } case IDTYPE_STRUCT: + case IDTYPE_UNION: case IDTYPE_CLASS: { auto b1 = (struct_identity*)type1; @@ -1618,6 +1619,7 @@ static void RenderType(lua_State *state, compound_identity *node) switch (node->type()) { case IDTYPE_STRUCT: + case IDTYPE_UNION: // TODO: change this to union-type? what relies on this? lua_pushstring(state, "struct-type"); lua_setfield(state, ftable, "_kind"); IndexStatics(state, ix_meta, ftable, (struct_identity*)node); diff --git a/library/include/DataDefs.h b/library/include/DataDefs.h index 5adfb5353..faabcddcc 100644 --- a/library/include/DataDefs.h +++ b/library/include/DataDefs.h @@ -64,7 +64,13 @@ namespace DFHack IDTYPE_CLASS, IDTYPE_BUFFER, IDTYPE_STL_PTR_VECTOR, - IDTYPE_OPAQUE + IDTYPE_OPAQUE, + IDTYPE_UNION + }; + + enum pointer_identity_flags { + PTRFLAG_IS_ARRAY = 1, + PTRFLAG_HAS_BAD_POINTERS = 2, }; typedef void *(*TAllocateFn)(void*,const void*); @@ -279,8 +285,8 @@ namespace DFHack public: struct_identity(size_t size, TAllocateFn alloc, - compound_identity *scope_parent, const char *dfhack_name, - struct_identity *parent, const struct_field_info *fields); + compound_identity *scope_parent, const char *dfhack_name, + struct_identity *parent, const struct_field_info *fields); virtual identity_type type() { return IDTYPE_STRUCT; } @@ -305,6 +311,15 @@ namespace DFHack virtual void build_metatable(lua_State *state); }; + class DFHACK_EXPORT global_identity : public union_identity { + public: + union_identity(size_t size, TAllocateFn alloc, + compound_identity *scope_parent, const char *dfhack_name, + struct_identity *parent, const struct_field_info *fields); + + virtual identity_type type() { return IDTYPE_UNION; } + }; + #ifdef _MSC_VER typedef void *virtual_ptr; #else diff --git a/library/xml b/library/xml index 3486919f0..17b1c45ff 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 3486919f01b86d558558ecd36c815d0a527459c2 +Subproject commit 17b1c45fff78d0c49aa8b4dc4824dc36ae7eae08 diff --git a/plugins/devel/check-structures-sanity.cpp b/plugins/devel/check-structures-sanity.cpp index 07dea4ddd..2baddd170 100644 --- a/plugins/devel/check-structures-sanity.cpp +++ b/plugins/devel/check-structures-sanity.cpp @@ -448,6 +448,7 @@ void Checker::queue_field(ToCheck && item, const struct_field_info *field) // TODO: check static strings? break; case struct_field_info::POINTER: + // TODO: flags inside field->count item.temp_identity = std::unique_ptr(new df::pointer_identity(field->type)); item.identity = item.temp_identity.get(); queue.push_back(std::move(item)); @@ -554,12 +555,12 @@ bool Checker::maybe_queue_tagged_union(const ToCheck & item, const struct_field_ auto tag_identity = static_cast(tag_field->type); - if (!field->type || field->type->type() != IDTYPE_STRUCT) + if (!field->type || field->type->type() != IDTYPE_UNION) { return false; } - auto union_identity = static_cast(field->type); + auto union_identity = static_cast(field->type); if (!union_identity->getFields() || union_identity->getFields()->mode != struct_field_info::POINTER) { @@ -699,6 +700,7 @@ void Checker::check_dispatch(const ToCheck & item) check_enum(item); break; case IDTYPE_STRUCT: + case IDTYPE_UNION: check_struct(item); break; case IDTYPE_CLASS: