From c2e90225b90521782ea9b307dfb2b18f6d5b1cfc Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 16 Jan 2024 11:12:08 -0800 Subject: [PATCH] type graph data member gathering -> follow single-inheritance base class members + sort members by offset --- src/mule/mule_main.cpp | 18 ++++++++ src/type_graph/type_graph.c | 84 +++++++++++++++++++++++++++---------- src/type_graph/type_graph.h | 1 + 3 files changed, 82 insertions(+), 21 deletions(-) diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index eed3f726..72f826ca 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -914,6 +914,18 @@ struct Template_Example3{ } }; +struct SingleInheritanceBase +{ + int x; + int y; +}; + +struct SingleInheritanceDerived : SingleInheritanceBase +{ + int z; + int w; +}; + struct Has_Members{ int a; int b; @@ -1245,6 +1257,12 @@ extended_type_coverage_eval_tests(void){ Template_Example3 temp3_vi((void *)&temp3_if, 1.f); Template_Example3> temp3_itif(123, temp_if); + SingleInheritanceDerived sid; + sid.x = 123; + sid.y = 456; + sid.z = 789; + sid.w = 999; + Pointer_To_Member pointer_to_member = { &Has_Members::a, &Has_Members::c, &Has_Members::bas, &Has_Members::x, &Has_Members::z, &Has_Members::bas_f, diff --git a/src/type_graph/type_graph.c b/src/type_graph/type_graph.c index b019a70e..59dae802 100644 --- a/src/type_graph/type_graph.c +++ b/src/type_graph/type_graph.c @@ -15,6 +15,21 @@ tg_hash_from_string(U64 seed, String8 string) return result; } +internal int +tg_qsort_compare_members_offset(TG_Member *a, TG_Member *b) +{ + int result = 0; + if(a->off < b->off) + { + result = -1; + } + else if(a->off > b->off) + { + result = +1; + } + return result; +} + //////////////////////////////// //~ rjf: RADDBG <-> TG Enum Conversions @@ -742,7 +757,7 @@ tg_type_from_graph_raddbg_key(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg // rjf: commit members type->count = members.count; - type->members = push_array_no_zero(arena, TG_Member, 1); + type->members = push_array_no_zero(arena, TG_Member, members.count); U64 idx = 0; for(TG_MemberNode *n = members.first; n != 0; n = n->next, idx += 1) { @@ -912,36 +927,63 @@ tg_members_from_graph_raddbg_key(Arena *arena, TG_Graph *graph, RADDBG_Parsed *r internal TG_MemberArray tg_data_members_from_graph_raddbg_key(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, TG_Key key) { - TG_MemberArray result = {0}; Temp scratch = scratch_begin(&arena, 1); + TG_MemberList members_list = {0}; + B32 members_need_offset_sort = 0; { - TG_Type *type = tg_type_from_graph_raddbg_key(scratch.arena, graph, rdbg, key); - if(type->members != 0) + TG_Type *root_type = tg_type_from_graph_raddbg_key(scratch.arena, graph, rdbg, key); + typedef struct Task Task; + struct Task { - U64 data_member_count = 0; - for(U64 member_idx = 0; member_idx < type->count; member_idx += 1) + Task *next; + TG_Type *type; + }; + Task start_task = {0, root_type}; + Task *first_task = &start_task; + Task *last_task = &start_task; + for(Task *task = first_task; task != 0; task = task->next) + { + TG_Type *type = task->type; + if(type->members != 0) { - if(type->members[member_idx].kind == TG_MemberKind_DataField) + for(U64 member_idx = 0; member_idx < type->count; member_idx += 1) { - data_member_count += 1; - } - } - result.count = data_member_count; - result.v = push_array_no_zero(arena, TG_Member, result.count); - U64 idx = 0; - for(U64 member_idx = 0; member_idx < type->count; member_idx += 1) - { - if(type->members[member_idx].kind == TG_MemberKind_DataField) - { - MemoryCopyStruct(&result.v[idx], &type->members[member_idx]); - result.v[idx].name = push_str8_copy(arena, result.v[idx].name); - idx += 1; + if(type->members[member_idx].kind == TG_MemberKind_DataField) + { + TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); + MemoryCopyStruct(&n->v, &type->members[member_idx]); + SLLQueuePush(members_list.first, members_list.last, n); + members_list.count += 1; + } + else if(type->members[member_idx].kind == TG_MemberKind_Base) + { + Task *t = push_array(scratch.arena, Task, 1); + t->type = tg_type_from_graph_raddbg_key(scratch.arena, graph, rdbg, type->members[member_idx].type_key); + SLLQueuePush(first_task, last_task, t); + members_need_offset_sort = 1; + } } } } } + TG_MemberArray members = {0}; + { + members.count = members_list.count; + members.v = push_array(arena, TG_Member, members.count); + U64 idx = 0; + for(TG_MemberNode *n = members_list.first; n != 0; n = n->next) + { + MemoryCopyStruct(&members.v[idx], &n->v); + members.v[idx].name = push_str8_copy(arena, members.v[idx].name); + idx += 1; + } + } + if(members_need_offset_sort) + { + qsort(members.v, members.count, sizeof(TG_Member), (int (*)(const void *, const void *))tg_qsort_compare_members_offset); + } scratch_end(scratch); - return result; + return members; } internal void diff --git a/src/type_graph/type_graph.h b/src/type_graph/type_graph.h index 9003f13e..154db97f 100644 --- a/src/type_graph/type_graph.h +++ b/src/type_graph/type_graph.h @@ -179,6 +179,7 @@ thread_static Arena *tg_build_arena = 0; //~ rjf: Basic Helpers internal U64 tg_hash_from_string(U64 seed, String8 string); +internal int tg_qsort_compare_members_offset(TG_Member *a, TG_Member *b); //////////////////////////////// //~ rjf: RADDBG <-> TG Enum Conversions