mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
inline anonymous members
This commit is contained in:
@@ -125,6 +125,7 @@ typedef struct DW_AttribList
|
|||||||
U64 count;
|
U64 count;
|
||||||
} DW_AttribList;
|
} DW_AttribList;
|
||||||
|
|
||||||
|
typedef U8 DW_TagSpare;
|
||||||
typedef struct DW_Tag
|
typedef struct DW_Tag
|
||||||
{
|
{
|
||||||
B32 has_children;
|
B32 has_children;
|
||||||
@@ -132,7 +133,7 @@ typedef struct DW_Tag
|
|||||||
DW_TagKind kind;
|
DW_TagKind kind;
|
||||||
DW_AttribList attribs;
|
DW_AttribList attribs;
|
||||||
U64 info_off;
|
U64 info_off;
|
||||||
U8 v[1];
|
DW_TagSpare v;
|
||||||
} DW_Tag;
|
} DW_Tag;
|
||||||
|
|
||||||
typedef struct DW_TagNode
|
typedef struct DW_TagNode
|
||||||
|
|||||||
@@ -1756,15 +1756,15 @@ d2r_tag_iterator_parent_tag(D2R_TagIterator *iter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
d2r_flag_converted_tag(DW_TagNode *tag_node)
|
d2r_flag_converted_type_tag(DW_TagNode *tag_node)
|
||||||
{
|
{
|
||||||
tag_node->tag.v[0] = 1;
|
tag_node->tag.v |= D2R_TagFlags_TypeConverted;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal B8
|
internal B8
|
||||||
d2r_is_tag_converted(DW_TagNode *tag_node)
|
d2r_is_type_tag_converted(DW_TagNode *tag_node)
|
||||||
{
|
{
|
||||||
return tag_node->tag.v[0];
|
return !!(tag_node->tag.v & D2R_TagFlags_TypeConverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal RDIM_Type *
|
internal RDIM_Type *
|
||||||
@@ -1825,12 +1825,12 @@ d2r_convert_types(Arena *arena,
|
|||||||
DW_Tag tag = tag_node->tag;
|
DW_Tag tag = tag_node->tag;
|
||||||
|
|
||||||
// skip converted tags
|
// skip converted tags
|
||||||
if (d2r_is_tag_converted(tag_node)) {
|
if (d2r_is_type_tag_converted(tag_node)) {
|
||||||
d2r_tag_iterator_skip_children(it);
|
d2r_tag_iterator_skip_children(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// mark the tag as converted here, because during conversion we may recurse on the same tag
|
// mark the tag as converted here, because during conversion we may recurse on the same tag
|
||||||
d2r_flag_converted_tag(tag_node);
|
d2r_flag_converted_type_tag(tag_node);
|
||||||
|
|
||||||
switch (tag.kind) {
|
switch (tag.kind) {
|
||||||
case DW_TagKind_ClassType: {
|
case DW_TagKind_ClassType: {
|
||||||
@@ -2196,20 +2196,44 @@ d2r_convert_types(Arena *arena,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RDIM_Type *parent = d2r_type_from_offset(type_table, parent_tag.info_off);
|
RDIM_Type *parent = d2r_type_from_offset(type_table, parent_tag.info_off);
|
||||||
if(parent->udt != 0)
|
RDIM_Type *type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch_addr_size, tag, DW_AttribKind_Type);
|
||||||
{
|
RDIM_UDTMember *member = rdim_udt_push_member(arena, &udts, parent->udt);
|
||||||
RDIM_Type *type = d2r_find_or_convert_type(arena, type_table, input, cu, cu_lang, arch_addr_size, tag, DW_AttribKind_Type);
|
member->kind = RDI_MemberKind_Base;
|
||||||
RDIM_UDTMember *member = rdim_udt_push_member(arena, &udts, parent->udt);
|
member->type = type;
|
||||||
member->kind = RDI_MemberKind_Base;
|
member->off = safe_cast_u32(dw_const_u32_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_DataMemberLocation));
|
||||||
member->type = type;
|
|
||||||
member->off = safe_cast_u32(dw_const_u32_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_DataMemberLocation));
|
|
||||||
}
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal B8
|
||||||
|
d2r_is_udt_tag_converted(DW_TagNode *tag_node)
|
||||||
|
{
|
||||||
|
return !!(tag_node->tag.v & D2R_TagFlags_UdtConverted);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
d2r_flag_converted_udt_tag(DW_TagNode *tag_node)
|
||||||
|
{
|
||||||
|
tag_node->tag.v |= D2R_TagFlags_UdtConverted;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
d2r_inline_anonymous_udt_member(Arena *arena, RDIM_UDT *top_udt, U64 base_off, RDIM_UDT *udt)
|
||||||
|
{
|
||||||
|
for (RDIM_UDTMember *curr = udt->first_member, *prev = 0; curr != 0; prev = curr, curr = curr->next) {
|
||||||
|
if (curr->name.size == 0) {
|
||||||
|
d2r_inline_anonymous_udt_member(arena, top_udt, base_off + curr->off, curr->type->udt);
|
||||||
|
} else {
|
||||||
|
// copy member and adjust its offset relative to inlined position in the root UDT
|
||||||
|
RDIM_UDTMember *m = rdim_udt_push_member(arena, &udts, top_udt);
|
||||||
|
*m = *curr;
|
||||||
|
m->off += base_off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
d2r_convert_udts(Arena *arena,
|
d2r_convert_udts(Arena *arena,
|
||||||
D2R_TypeTable *type_table,
|
D2R_TypeTable *type_table,
|
||||||
@@ -2220,89 +2244,82 @@ d2r_convert_udts(Arena *arena,
|
|||||||
DW_TagNode *root)
|
DW_TagNode *root)
|
||||||
{
|
{
|
||||||
Temp scratch = scratch_begin(&arena, 1);
|
Temp scratch = scratch_begin(&arena, 1);
|
||||||
|
|
||||||
for (D2R_TagIterator *it = d2r_tag_iterator_init(scratch.arena, root); it->tag_node != 0; d2r_tag_iterator_next(scratch.arena, it)) {
|
for (D2R_TagIterator *it = d2r_tag_iterator_init(scratch.arena, root); it->tag_node != 0; d2r_tag_iterator_next(scratch.arena, it)) {
|
||||||
DW_TagNode *tag_node = it->tag_node;
|
DW_TagNode *tag_node = it->tag_node;
|
||||||
DW_Tag tag = tag_node->tag;
|
DW_Tag tag = tag_node->tag;
|
||||||
switch (tag.kind) {
|
|
||||||
case DW_TagKind_ClassType: {
|
// skip converted tags
|
||||||
B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration);
|
if (d2r_is_udt_tag_converted(tag_node)) {
|
||||||
if (is_decl) {
|
d2r_tag_iterator_skip_children(it);
|
||||||
d2r_tag_iterator_skip_children(it);
|
continue;
|
||||||
} else {
|
}
|
||||||
RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off);
|
d2r_flag_converted_udt_tag(tag_node);
|
||||||
RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP);
|
|
||||||
udt->self_type = type;
|
if (tag.kind == DW_TagKind_ClassType || tag.kind == DW_TagKind_StructureType || tag.kind == DW_TagKind_UnionType) {
|
||||||
type->udt = udt;
|
B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration);
|
||||||
}
|
if (is_decl) {
|
||||||
} break;
|
d2r_tag_iterator_skip_children(it);
|
||||||
case DW_TagKind_StructureType: {
|
} else {
|
||||||
B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration);
|
RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off);
|
||||||
if (is_decl) {
|
RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP);
|
||||||
d2r_tag_iterator_skip_children(it);
|
udt->self_type = type;
|
||||||
} else {
|
type->udt = udt;
|
||||||
RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off);
|
}
|
||||||
RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP);
|
} else if (tag.kind == DW_TagKind_EnumerationType) {
|
||||||
udt->self_type = type;
|
B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration);
|
||||||
type->udt = udt;
|
if (is_decl) {
|
||||||
}
|
d2r_tag_iterator_skip_children(it);
|
||||||
} break;
|
} else {
|
||||||
case DW_TagKind_UnionType: {
|
RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off);
|
||||||
B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration);
|
RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP);
|
||||||
if (is_decl) {
|
udt->self_type = type;
|
||||||
d2r_tag_iterator_skip_children(it);
|
type->udt = udt;
|
||||||
} else {
|
}
|
||||||
RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off);
|
} else if (tag.kind == DW_TagKind_Member) {
|
||||||
RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP);
|
DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it);
|
||||||
udt->self_type = type;
|
B32 is_parent_udt = parent_tag.kind == DW_TagKind_StructureType ||
|
||||||
type->udt = udt;
|
parent_tag.kind == DW_TagKind_ClassType ||
|
||||||
}
|
parent_tag.kind == DW_TagKind_UnionType;
|
||||||
} break;
|
if (is_parent_udt) {
|
||||||
case DW_TagKind_EnumerationType: {
|
RDIM_Type *parent_type = d2r_type_from_offset(type_table, parent_tag.info_off);
|
||||||
B32 is_decl = dw_flag_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Declaration);
|
RDIM_Type *type = d2r_type_from_attrib(type_table, input, cu, tag, DW_AttribKind_Type);
|
||||||
if (is_decl) {
|
String8 name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name);
|
||||||
d2r_tag_iterator_skip_children(it);
|
U64 off = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_DataMemberLocation);
|
||||||
} else {
|
if (name.size == 0) { // inline anonymous members
|
||||||
RDIM_Type *type = d2r_type_from_offset(type_table, tag.info_off);
|
DW_Reference type_ref = dw_ref_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Type);
|
||||||
RDIM_UDT *udt = rdim_udt_chunk_list_push(arena, &udts, UDT_CHUNK_CAP);
|
RDIM_Type *member_type = d2r_type_from_offset(type_table, type_ref.info_off);
|
||||||
udt->self_type = type;
|
RDIM_UDT *member_udt = member_type->udt;
|
||||||
type->udt = udt;
|
if (member_udt == 0) {
|
||||||
}
|
DW_Language ref_cu_lang = dw_const_u64_from_tag_attrib_kind(input, type_ref.cu, type_ref.cu->tag, DW_AttribKind_Language);
|
||||||
} break;
|
DW_TagNode *ref_tag_node = dw_tag_node_from_info_off(type_ref.cu, type_ref.info_off);
|
||||||
case DW_TagKind_Member: {
|
d2r_convert_udts(arena, type_table, input, type_ref.cu, ref_cu_lang, arch_addr_size, ref_tag_node);
|
||||||
DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it);
|
Assert(member_type->udt);
|
||||||
B32 is_parent_udt = parent_tag.kind == DW_TagKind_StructureType ||
|
member_udt = member_type->udt;
|
||||||
parent_tag.kind == DW_TagKind_ClassType ||
|
|
||||||
parent_tag.kind == DW_TagKind_UnionType;
|
|
||||||
if (is_parent_udt) {
|
|
||||||
DW_Attrib *data_member_location = dw_attrib_from_tag(input, cu, tag, DW_AttribKind_DataMemberLocation);
|
|
||||||
DW_AttribClass data_member_location_class = dw_value_class_from_attrib(cu, data_member_location);
|
|
||||||
if (data_member_location_class == DW_AttribClass_LocList) {
|
|
||||||
AssertAlways(!"UDT member with multiple locations are not supported");
|
|
||||||
}
|
}
|
||||||
|
d2r_inline_anonymous_udt_member(arena, parent_type->udt, off, member_udt);
|
||||||
RDIM_Type *parent_type = d2r_type_from_offset(type_table, parent_tag.info_off);
|
|
||||||
RDIM_UDTMember *udt_member = rdim_udt_push_member(arena, &udts, parent_type->udt);
|
|
||||||
udt_member->kind = RDI_MemberKind_DataField;
|
|
||||||
udt_member->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name);
|
|
||||||
udt_member->type = d2r_type_from_attrib(type_table, input, cu, tag, DW_AttribKind_Type);
|
|
||||||
udt_member->off = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_DataMemberLocation);
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: error handling
|
RDIM_UDTMember *member = rdim_udt_push_member(arena, &udts, parent_type->udt);
|
||||||
AssertAlways(!"unexpected parent tag");
|
member->kind = RDI_MemberKind_DataField;
|
||||||
|
member->name = name;
|
||||||
|
member->type = type;
|
||||||
|
member->off = off;
|
||||||
}
|
}
|
||||||
} break;
|
} else {
|
||||||
case DW_TagKind_Enumerator: {
|
// TODO: error handling
|
||||||
DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it);
|
AssertAlways(!"unexpected parent tag");
|
||||||
if (parent_tag.kind == DW_TagKind_EnumerationType) {
|
}
|
||||||
RDIM_Type *parent_type = d2r_type_from_offset(type_table, parent_tag.info_off);
|
} else if (tag.kind == DW_TagKind_Enumerator) {
|
||||||
RDIM_UDTEnumVal *udt_member = rdim_udt_push_enum_val(arena, &udts, parent_type->udt);
|
DW_Tag parent_tag = d2r_tag_iterator_parent_tag(it);
|
||||||
udt_member->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name);
|
if (parent_tag.kind == DW_TagKind_EnumerationType) {
|
||||||
udt_member->val = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_ConstValue);
|
RDIM_Type *parent_type = d2r_type_from_offset(type_table, parent_tag.info_off);
|
||||||
} else {
|
RDIM_UDTEnumVal *udt_member = rdim_udt_push_enum_val(arena, &udts, parent_type->udt);
|
||||||
// TODO: error handling
|
udt_member->name = dw_string_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_Name);
|
||||||
AssertAlways(!"unexpected parent tag");
|
udt_member->val = dw_const_u64_from_tag_attrib_kind(input, cu, tag, DW_AttribKind_ConstValue);
|
||||||
}
|
} else {
|
||||||
} break;
|
// TODO: error handling
|
||||||
|
AssertAlways(!"unexpected parent tag");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scratch_end(scratch);
|
scratch_end(scratch);
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ typedef struct D2R_TypeTable
|
|||||||
RDIM_Type **builtin_types;
|
RDIM_Type **builtin_types;
|
||||||
} D2R_TypeTable;
|
} D2R_TypeTable;
|
||||||
|
|
||||||
|
typedef DW_TagSpare D2R_TagFlags;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
D2R_TagFlags_TypeConverted = (1 << 0),
|
||||||
|
D2R_TagFlags_UdtConverted = (1 << 1),
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct D2R_TagFrame
|
typedef struct D2R_TagFrame
|
||||||
{
|
{
|
||||||
DW_TagNode *node;
|
DW_TagNode *node;
|
||||||
|
|||||||
Reference in New Issue
Block a user