mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-22 05:34:59 -07:00
Add DebugInfoArray as separate debug info type. Minor cleanup of various debug infos.
This commit is contained in:
+173
-150
@@ -28,6 +28,7 @@ struct irModule {
|
||||
irDebugInfo * debug_compile_unit;
|
||||
|
||||
|
||||
|
||||
i32 global_string_index;
|
||||
i32 global_array_index; // For ConstantSlice
|
||||
i32 global_generated_index;
|
||||
@@ -255,7 +256,7 @@ gbAllocator ir_allocator(void) {
|
||||
IR_INSTR_KIND(StartupRuntime, i32) \
|
||||
IR_INSTR_KIND(DebugDeclare, struct { \
|
||||
irDebugInfo *scope; \
|
||||
Ast * expr; \
|
||||
Ast * expr; \
|
||||
Entity * entity; \
|
||||
bool is_addr; \
|
||||
irValue * value; \
|
||||
@@ -536,6 +537,7 @@ enum irDebugInfoKind {
|
||||
irDebugInfo_GlobalVariable,
|
||||
irDebugInfo_LocalVariable,
|
||||
|
||||
irDebugInfo_DebugInfoArray, // array of irDebugInfo *'s
|
||||
|
||||
irDebugInfo_Count,
|
||||
};
|
||||
@@ -549,6 +551,8 @@ struct irDebugInfo {
|
||||
AstFile * file;
|
||||
String producer;
|
||||
irDebugInfo *all_procs;
|
||||
irDebugInfo *enums; // DebugInfoArray
|
||||
irDebugInfo *globals; // DebugInfoArray
|
||||
} CompileUnit;
|
||||
struct {
|
||||
AstFile *file;
|
||||
@@ -562,16 +566,16 @@ struct irDebugInfo {
|
||||
Scope * scope; // Actual scope
|
||||
} Scope;
|
||||
struct {
|
||||
Entity * entity;
|
||||
String name;
|
||||
irDebugInfo * file;
|
||||
TokenPos pos;
|
||||
Array<irDebugInfo *> types; // !{return, return, param, param, param.. etc.}
|
||||
Entity * entity;
|
||||
String name;
|
||||
irDebugInfo * file;
|
||||
TokenPos pos;
|
||||
irDebugInfo * types; // !{return, return, param, param, param.. etc.}
|
||||
// TODO(lachsinc): variables / retainedNodes ?
|
||||
} Proc;
|
||||
struct {
|
||||
Array<irDebugInfo *> procs;
|
||||
} AllProcs;
|
||||
} AllProcs; // TODO(lach): Redundant w/ DebugInfoArray. Merge.
|
||||
|
||||
// NOTE(lachsinc): Many of the following fields could be removed/resolved as we print it?
|
||||
struct {
|
||||
@@ -606,7 +610,7 @@ struct irDebugInfo {
|
||||
irDebugInfo * base_type; // optional, used for enumeration_type.
|
||||
i32 size;
|
||||
i32 align;
|
||||
Array<irDebugInfo *> elements;
|
||||
irDebugInfo * elements;
|
||||
i32 array_count; // TODO(lach): We could define a new !DISubrange and place ptr to it inside above elements array instead.
|
||||
} CompositeType;
|
||||
struct {
|
||||
@@ -630,6 +634,9 @@ struct irDebugInfo {
|
||||
i32 arg; // Non-zero if proc parameter
|
||||
irDebugInfo *type;
|
||||
} LocalVariable;
|
||||
struct {
|
||||
Array<irDebugInfo *> elements;
|
||||
} DebugInfoArray;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1418,8 +1425,8 @@ irValue *ir_add_local(irProcedure *proc, Entity *e, Ast *expr, bool zero_initial
|
||||
|
||||
// TODO(lachsinc): "Arg" is not used yet but should be eventually, if applicable, set to param index
|
||||
// NOTE(lachsinc): The following call recurses through a type creating or finding the necessary debug info.
|
||||
// This approach may be quite detrimental to perf esp. debug builds!
|
||||
// This may not be the most appropriate place to place this?
|
||||
// This approach may be quite detrimental to perf?
|
||||
// This may not be the most appropriate place to place this? (for proc non-value params etc.)
|
||||
ir_add_debug_info_local(proc, di, e, 0);
|
||||
}
|
||||
|
||||
@@ -1529,6 +1536,13 @@ irValue *ir_add_param(irProcedure *proc, Entity *e, Ast *expr, Type *abi_type) {
|
||||
|
||||
irDebugInfo *ir_add_debug_info_type(irModule *module, irDebugInfo *scope, Entity *e, Type *type, irDebugInfo *file);
|
||||
|
||||
irDebugInfo *ir_add_debug_info_array(irModule *module, isize count, isize capacity) {
|
||||
irDebugInfo *di = ir_alloc_debug_info(irDebugInfo_DebugInfoArray);
|
||||
array_init(&di->DebugInfoArray.elements, ir_allocator(), count, capacity);
|
||||
map_set(&module->debug_info, hash_pointer(di), di);
|
||||
return di;
|
||||
}
|
||||
|
||||
irDebugInfo *ir_add_debug_info_file(irProcedure *proc, AstFile *file) {
|
||||
// if (!proc->module->generate_debug_info) {
|
||||
// return nullptr;
|
||||
@@ -1653,6 +1667,140 @@ irDebugInfo *ir_add_debug_info_enumerator(irModule *module, Entity *e) {
|
||||
return di;
|
||||
}
|
||||
|
||||
irDebugInfo *ir_add_debug_info_dynamic_array(irModule *module, irDebugInfo *scope, Entity *e, Type *type, irDebugInfo *file) {
|
||||
//
|
||||
// TODO(lachsinc): Hardcode McGee.
|
||||
//
|
||||
|
||||
// TODO(lachsinc): SPEED? I assume this will create a bunch of new debug infos for _every single_
|
||||
// dynamic array type. Maybe that's what we want, but with ability to refer to the _same_
|
||||
// derived types for the len/cap/allocator fields.
|
||||
|
||||
// TODO(lachsinc): HACK we should handle named's as derived types to
|
||||
// minimise duplication of work / ir output
|
||||
Type *named = nullptr;
|
||||
if (is_type_named(type)) {
|
||||
named = type;
|
||||
type = base_type(type);
|
||||
}
|
||||
GB_ASSERT(type->kind == Type_DynamicArray);
|
||||
|
||||
// if (!module->debug_dynamic_array_type) {
|
||||
irDebugInfo *di = ir_alloc_debug_info(irDebugInfo_CompositeType);
|
||||
di->CompositeType.name = named ? named->Named.name : str_lit("dynamic array");
|
||||
di->CompositeType.tag = irDebugBasicEncoding_structure_type;
|
||||
|
||||
// TODO(lachsinc): Necessary ?
|
||||
di->CompositeType.size = 8*cast(i32)(type_size_of(t_rawptr) +
|
||||
type_size_of(t_int) +
|
||||
type_size_of(t_int) +
|
||||
type_size_of(t_allocator)); // TODO(lachsinc): Allocator is correct size??
|
||||
di->CompositeType.align = 8*cast(i32)type_align_of(t_rawptr);
|
||||
di->CompositeType.elements = ir_add_debug_info_array(module, 0, 4);
|
||||
|
||||
// Data pointer type
|
||||
irDebugInfo *data_ptr_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
data_ptr_di->DerivedType.name = str_lit("ptr_type_name_todo");
|
||||
data_ptr_di->DerivedType.tag = irDebugBasicEncoding_pointer_type;
|
||||
data_ptr_di->DerivedType.size = 8*cast(i32)type_size_of(type->DynamicArray.elem);
|
||||
data_ptr_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, type->DynamicArray.elem, file);
|
||||
|
||||
// Field "data"
|
||||
irDebugInfo *data_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
data_di->DerivedType.name = str_lit("data");
|
||||
data_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
data_di->DerivedType.size = 8*cast(i32)type_size_of(t_rawptr);
|
||||
data_di->DerivedType.offset = 0;
|
||||
data_di->DerivedType.base_type = data_ptr_di;
|
||||
|
||||
// Field "len"
|
||||
irDebugInfo *len_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
len_di->DerivedType.name = str_lit("len");
|
||||
len_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
len_di->DerivedType.size = 8*cast(i32)type_size_of(t_int);
|
||||
len_di->DerivedType.offset = data_di->DerivedType.size;
|
||||
len_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_int, file);
|
||||
|
||||
// Field "cap"
|
||||
irDebugInfo *cap_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
cap_di->DerivedType.name = str_lit("cap");
|
||||
cap_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
cap_di->DerivedType.size = 8*cast(i32)type_size_of(t_int);
|
||||
cap_di->DerivedType.offset = data_di->DerivedType.size + len_di->DerivedType.size;
|
||||
cap_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_int, file);
|
||||
|
||||
// Field "allocator"
|
||||
irDebugInfo *alloc_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
alloc_di->DerivedType.name = str_lit("allocator");
|
||||
alloc_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
alloc_di->DerivedType.size = 8*cast(i32)type_size_of(t_allocator);
|
||||
alloc_di->DerivedType.offset = data_di->DerivedType.size + len_di->DerivedType.size + alloc_di->DerivedType.size;
|
||||
alloc_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_allocator, file); // TODO(lachsinc): Highly doubtful t_allocator creates correct debug info!
|
||||
|
||||
array_add(&di->CompositeType.elements->DebugInfoArray.elements, data_di);
|
||||
array_add(&di->CompositeType.elements->DebugInfoArray.elements, len_di);
|
||||
array_add(&di->CompositeType.elements->DebugInfoArray.elements, cap_di);
|
||||
array_add(&di->CompositeType.elements->DebugInfoArray.elements, alloc_di);
|
||||
|
||||
// NOTE(lach): This isn't particularly robust; we create a new one for every type. A potential workaround
|
||||
// is to store a pointer for each of these "custom" types inside irModule, creating if not exists
|
||||
// (and either adding to debug_info map, or assigning id's manually to them).
|
||||
map_set(&module->debug_info, hash_pointer(data_ptr_di), data_ptr_di);
|
||||
map_set(&module->debug_info, hash_pointer(data_di), data_di);
|
||||
map_set(&module->debug_info, hash_pointer(len_di), len_di);
|
||||
map_set(&module->debug_info, hash_pointer(cap_di), cap_di);
|
||||
map_set(&module->debug_info, hash_pointer(alloc_di), alloc_di);
|
||||
|
||||
map_set(&module->debug_info, hash_type(named ? named : type), di);
|
||||
// }
|
||||
|
||||
return di;
|
||||
}
|
||||
|
||||
irDebugInfo *ir_add_debug_info_string(irModule *module, irDebugInfo *scope, Entity *e, Type *type, irDebugInfo *file) {
|
||||
// TODO(lach): Is there a cleaner way to set up these types without hardcoding values ??
|
||||
// Also we may want to just create hardcoded "base type" for things like strings etc.
|
||||
// and just create a derived (named) type to "inherit" from. That way we can look them up directly
|
||||
// inside irModule, and avoid lots of map lookups and array creations for their elements.
|
||||
// In theory this should only occur once, as we hash the type t_string once and return it.
|
||||
|
||||
GB_ASSERT(type->kind == Type_Basic);
|
||||
GB_ASSERT(type->Basic.kind == Basic_string);
|
||||
|
||||
irDebugInfo *di = ir_alloc_debug_info(irDebugInfo_CompositeType);
|
||||
di->CompositeType.name = type->Basic.name;
|
||||
di->CompositeType.tag = irDebugBasicEncoding_structure_type;
|
||||
di->CompositeType.size = 8*cast(i32)type_size_of(t_string);
|
||||
di->CompositeType.align = 8*cast(i32)type_align_of(t_string);
|
||||
di->CompositeType.elements = ir_add_debug_info_array(module, 0, 2);
|
||||
|
||||
irDebugInfo *data_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
data_di->DerivedType.name = str_lit("data"); // TODO(lachsinc):
|
||||
data_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
data_di->DerivedType.size = 8*cast(i32)type_size_of(t_rawptr);
|
||||
data_di->DerivedType.offset = 0;
|
||||
data_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_cstring, file);
|
||||
|
||||
irDebugInfo *len_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
len_di->DerivedType.name = str_lit("len"); // TODO(lachsinc):
|
||||
len_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
len_di->DerivedType.size = 8*cast(i32)type_size_of(t_i64);
|
||||
len_di->DerivedType.offset = data_di->DerivedType.size;
|
||||
len_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_i64, file);
|
||||
|
||||
array_add(&di->CompositeType.elements->DebugInfoArray.elements, data_di);
|
||||
array_add(&di->CompositeType.elements->DebugInfoArray.elements, len_di);
|
||||
|
||||
// NOTE(lach): This isn't particularly robust, it assumes all strings will be caught
|
||||
// by the map lookup (ie this will only be created once).
|
||||
map_set(&module->debug_info, hash_pointer(data_di), data_di);
|
||||
map_set(&module->debug_info, hash_pointer(len_di), len_di);
|
||||
|
||||
map_set(&module->debug_info, hash_type(type), di);
|
||||
|
||||
return di;
|
||||
}
|
||||
|
||||
irDebugInfo *ir_add_debug_info_type(irModule *module, irDebugInfo *scope, Entity *e, Type *type, irDebugInfo *file) {
|
||||
// if (!proc->module->generate_debug_info) {
|
||||
// return nullptr;
|
||||
@@ -1695,25 +1843,25 @@ irDebugInfo *ir_add_debug_info_type(irModule *module, irDebugInfo *scope, Entity
|
||||
} else {
|
||||
di->CompositeType.name = str_lit("struct_name_todo");
|
||||
}
|
||||
array_init(&di->CompositeType.elements, ir_allocator(), 0, base->Struct.fields.capacity);
|
||||
di->CompositeType.elements = ir_add_debug_info_array(module, 0, base->Struct.fields.count);
|
||||
for_array(field_index, base->Struct.fields) {
|
||||
array_add(&di->CompositeType.elements,
|
||||
array_add(&di->CompositeType.elements->DebugInfoArray.elements,
|
||||
ir_add_debug_info_field(module, di, base->Struct.fields[field_index], cast(i32)field_index,
|
||||
base->Struct.fields[field_index]->type, file));
|
||||
}
|
||||
di->CompositeType.tag = irDebugBasicEncoding_structure_type;
|
||||
} else if (is_type_union(type)) {
|
||||
di->CompositeType.name = str_lit("union_todo");
|
||||
array_init(&di->CompositeType.elements, ir_allocator(), 0, 0);
|
||||
di->CompositeType.name = str_lit("union_name_todo");
|
||||
di->CompositeType.elements = nullptr; // ir_add_debug_info_array(module, 0, 0);
|
||||
// TODO(lachsinc): Add elements for union
|
||||
di->CompositeType.tag = irDebugBasicEncoding_union_type;
|
||||
} else if (is_type_enum(type)) {
|
||||
GB_ASSERT(type->kind == Type_Named);
|
||||
di->CompositeType.name = type->Named.name;
|
||||
di->CompositeType.base_type = ir_add_debug_info_type(module, scope, e, type->Named.base->Enum.base_type, file);
|
||||
array_init(&di->CompositeType.elements, ir_allocator(), 0, base->Enum.fields.capacity);
|
||||
di->CompositeType.elements = ir_add_debug_info_array(module, 0, base->Enum.fields.count);
|
||||
for_array(field_index, base->Enum.fields) {
|
||||
array_add(&di->CompositeType.elements,
|
||||
array_add(&di->CompositeType.elements->DebugInfoArray.elements,
|
||||
ir_add_debug_info_enumerator(module, base->Enum.fields[field_index]));
|
||||
}
|
||||
di->CompositeType.tag = irDebugBasicEncoding_enumeration_type;
|
||||
@@ -1735,7 +1883,7 @@ irDebugInfo *ir_add_debug_info_type(irModule *module, irDebugInfo *scope, Entity
|
||||
} else if (deref->kind == Type_Basic) {
|
||||
di->DerivedType.name = deref->Basic.name;
|
||||
} else {
|
||||
di->DerivedType.name = str_lit("derived_name_todo");
|
||||
di->DerivedType.name = str_lit("pointer_name_todo");
|
||||
}
|
||||
di->DerivedType.tag = irDebugBasicEncoding_pointer_type;
|
||||
di->DerivedType.scope = scope;
|
||||
@@ -1759,92 +1907,7 @@ irDebugInfo *ir_add_debug_info_type(irModule *module, irDebugInfo *scope, Entity
|
||||
// We could get fancy and use a composite type along with
|
||||
// DW_TAG_class_type / template debug stuff eventually.
|
||||
if (is_type_dynamic_array(type)) {
|
||||
//
|
||||
// TODO(lachsinc): Hardcode McGee.
|
||||
//
|
||||
|
||||
// TODO(lachsinc): SPEED? I assume this will create a bunch of new debug infos for _every single_
|
||||
// dynamic array type. Maybe that's what we want, but with ability to refer to the _same_
|
||||
// derived types for the len/cap/allocator fields.
|
||||
|
||||
// TODO(lachsinc): HACK we should handle named's as derived types to
|
||||
// minimise duplication of work / ir output
|
||||
Type *named = nullptr;
|
||||
if (is_type_named(type)) {
|
||||
named = type;
|
||||
type = base_type(type);
|
||||
}
|
||||
|
||||
GB_ASSERT(type->kind == Type_DynamicArray);
|
||||
|
||||
irDebugInfo *di = ir_alloc_debug_info(irDebugInfo_CompositeType);
|
||||
di->CompositeType.name = named ? named->Named.name : str_lit("dynamic array");
|
||||
di->CompositeType.tag = irDebugBasicEncoding_structure_type;
|
||||
// TODO(lachsinc): Necessary ?
|
||||
di->CompositeType.size = 8*cast(i32)(type_size_of(t_rawptr) +
|
||||
type_size_of(t_int) +
|
||||
type_size_of(t_int) +
|
||||
type_size_of(t_allocator)); // TODO(lachsinc): Allocator is correct size??
|
||||
di->CompositeType.align = 8*cast(i32)type_align_of(t_rawptr);
|
||||
|
||||
array_init(&di->CompositeType.elements, ir_allocator(), 0, 4);
|
||||
|
||||
// Data pointer type
|
||||
irDebugInfo *data_ptr_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
data_ptr_di->DerivedType.name = str_lit("ptr_type_name_todo");
|
||||
data_ptr_di->DerivedType.tag = irDebugBasicEncoding_pointer_type;
|
||||
data_ptr_di->DerivedType.size = 8*cast(i32)type_size_of(type->DynamicArray.elem);
|
||||
data_ptr_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, type->DynamicArray.elem, file);
|
||||
|
||||
// Field "data"
|
||||
irDebugInfo *data_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
data_di->DerivedType.name = str_lit("data");
|
||||
data_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
data_di->DerivedType.size = 8*cast(i32)type_size_of(t_rawptr);
|
||||
data_di->DerivedType.offset = 0;
|
||||
data_di->DerivedType.base_type = data_ptr_di;
|
||||
|
||||
// Field "len"
|
||||
irDebugInfo *len_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
len_di->DerivedType.name = str_lit("len");
|
||||
len_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
len_di->DerivedType.size = 8*cast(i32)type_size_of(t_int);
|
||||
len_di->DerivedType.offset = data_di->DerivedType.size;
|
||||
len_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_int, file);
|
||||
|
||||
// Field "cap"
|
||||
irDebugInfo *cap_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
cap_di->DerivedType.name = str_lit("cap");
|
||||
cap_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
cap_di->DerivedType.size = 8*cast(i32)type_size_of(t_int);
|
||||
cap_di->DerivedType.offset = data_di->DerivedType.size + len_di->DerivedType.size;
|
||||
cap_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_int, file);
|
||||
|
||||
// Field "allocator"
|
||||
irDebugInfo *alloc_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
alloc_di->DerivedType.name = str_lit("allocator");
|
||||
alloc_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
alloc_di->DerivedType.size = 8*cast(i32)type_size_of(t_allocator);
|
||||
alloc_di->DerivedType.offset = data_di->DerivedType.size + len_di->DerivedType.size + alloc_di->DerivedType.size;
|
||||
alloc_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_allocator, file); // TODO(lachsinc): Highly doubtful t_allocator creates correct debug info!
|
||||
|
||||
array_add(&di->CompositeType.elements, data_di);
|
||||
array_add(&di->CompositeType.elements, len_di);
|
||||
array_add(&di->CompositeType.elements, cap_di);
|
||||
array_add(&di->CompositeType.elements, alloc_di);
|
||||
|
||||
// NOTE(lach): This isn't particularly robust; we create a new one for every type. A potential workaround
|
||||
// is to store a pointer for each of these "custom" types inside irModule, creating if not exists
|
||||
// (and either adding to debug_info map, or assigning id's manually to them).
|
||||
map_set(&module->debug_info, hash_pointer(data_ptr_di), data_ptr_di);
|
||||
map_set(&module->debug_info, hash_pointer(data_di), data_di);
|
||||
map_set(&module->debug_info, hash_pointer(len_di), len_di);
|
||||
map_set(&module->debug_info, hash_pointer(cap_di), cap_di);
|
||||
map_set(&module->debug_info, hash_pointer(alloc_di), alloc_di);
|
||||
|
||||
map_set(&module->debug_info, hash_type(named ? named : type), di);
|
||||
|
||||
return di;
|
||||
return ir_add_debug_info_dynamic_array(module, scope, e, type, file);
|
||||
}
|
||||
|
||||
if (is_type_array(type)) {
|
||||
@@ -1878,48 +1941,7 @@ irDebugInfo *ir_add_debug_info_type(irModule *module, irDebugInfo *scope, Entity
|
||||
}
|
||||
|
||||
if (is_type_string(type)) {
|
||||
// TODO(lach): Is there a cleaner way to set up these types without hardcoding values ??
|
||||
// Also we may want to just create hardcoded "base type" for things like strings etc.
|
||||
// and just create a derived (named) type to "inherit" from. That way we can look them up directly
|
||||
// inside irModule, and avoid lots of map lookups and array creations for their elements.
|
||||
// In theory this should only occur once, as we hash the type t_string once and return it.
|
||||
|
||||
GB_ASSERT(type->kind == Type_Basic);
|
||||
GB_ASSERT(type->Basic.kind == Basic_string);
|
||||
|
||||
irDebugInfo *di = ir_alloc_debug_info(irDebugInfo_CompositeType);
|
||||
di->CompositeType.name = type->Basic.name;
|
||||
di->CompositeType.tag = irDebugBasicEncoding_structure_type;
|
||||
di->CompositeType.size = 8*cast(i32)type_size_of(t_string);
|
||||
di->CompositeType.align = 8*cast(i32)type_align_of(t_string);
|
||||
|
||||
array_init(&di->CompositeType.elements, ir_allocator(), 0, 2);
|
||||
|
||||
irDebugInfo *data_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
data_di->DerivedType.name = str_lit("data"); // TODO(lachsinc):
|
||||
data_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
data_di->DerivedType.size = 8*cast(i32)type_size_of(t_rawptr);
|
||||
data_di->DerivedType.offset = 0;
|
||||
data_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_cstring, file);
|
||||
|
||||
irDebugInfo *len_di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
len_di->DerivedType.name = str_lit("len"); // TODO(lachsinc):
|
||||
len_di->DerivedType.tag = irDebugBasicEncoding_member;
|
||||
len_di->DerivedType.size = 8*cast(i32)type_size_of(t_i64);
|
||||
len_di->DerivedType.offset = data_di->DerivedType.size;
|
||||
len_di->DerivedType.base_type = ir_add_debug_info_type(module, scope, e, t_i64, file);
|
||||
|
||||
array_add(&di->CompositeType.elements, data_di);
|
||||
array_add(&di->CompositeType.elements, len_di);
|
||||
|
||||
// NOTE(lach): This isn't particularly robust, it assumes all strings will be caught
|
||||
// by the map lookup (ie this will only be created once).
|
||||
map_set(&module->debug_info, hash_pointer(data_di), data_di);
|
||||
map_set(&module->debug_info, hash_pointer(len_di), len_di);
|
||||
|
||||
map_set(&module->debug_info, hash_type(type), di);
|
||||
|
||||
return di;
|
||||
return ir_add_debug_info_string(module, scope, e, type, file);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1968,7 +1990,8 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
|
||||
|
||||
isize result_count = proc->type->Proc.result_count;
|
||||
isize param_count = proc->type->Proc.param_count;
|
||||
array_init(&di->Proc.types, ir_allocator(), 0, gb_max(result_count, 1) + param_count); // TODO(lachsinc): ir_allocator() safe to use?
|
||||
// gb_max(result_count, 1) because llvm expects explicit "null" return type
|
||||
di->Proc.types = ir_add_debug_info_array(proc->module, 0, gb_max(result_count, 1) + param_count);
|
||||
|
||||
// Result/return types
|
||||
if (result_count >= 1) {
|
||||
@@ -1981,12 +2004,12 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
|
||||
|
||||
irDebugInfo *type_di = ir_add_debug_info_type(proc->module, di, e, e->type, file);
|
||||
GB_ASSERT_NOT_NULL(type_di);
|
||||
array_add(&di->Proc.types, type_di);
|
||||
array_add(&di->Proc.types->DebugInfoArray.elements, type_di);
|
||||
}
|
||||
} else {
|
||||
// llvm expects "!{null}" for a function without return type, use nullptr to represent it.
|
||||
// TODO(lachsinc): Is there a specific "void" type we should refer to?
|
||||
array_add(&di->Proc.types, (irDebugInfo*)nullptr);
|
||||
array_add(&di->Proc.types->DebugInfoArray.elements, (irDebugInfo*)nullptr);
|
||||
}
|
||||
|
||||
// Param types
|
||||
@@ -2000,10 +2023,10 @@ irDebugInfo *ir_add_debug_info_proc(irProcedure *proc, Entity *entity, String na
|
||||
// TODO(lach): Could technically be a local?
|
||||
irDebugInfo *type_di = ir_add_debug_info_type(proc->module, di, e, e->type, file);
|
||||
GB_ASSERT_NOT_NULL(type_di);
|
||||
array_add(&di->Proc.types, type_di);
|
||||
array_add(&di->Proc.types->DebugInfoArray.elements, type_di);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc->debug_scope = di;
|
||||
|
||||
map_set(&proc->module->debug_info, hash_entity(entity), di);
|
||||
|
||||
+22
-28
@@ -1974,30 +1974,16 @@ void print_llvm_ir(irGen *ir) {
|
||||
", flags: DIFlagPrototyped"
|
||||
", isOptimized: false"
|
||||
", unit: !%d"
|
||||
", type: !DISubroutineType(types: !{",
|
||||
", type: !DISubroutineType(types: !%d)",
|
||||
LIT(di->Proc.entity->token.string),
|
||||
LIT(di->Proc.name),
|
||||
di->Proc.file->id, // TODO(lachsinc): HACK For now lets pretend all procs scope's == file.
|
||||
di->Proc.file->id,
|
||||
di->Proc.pos.line,
|
||||
di->Proc.pos.line, // NOTE(lachsinc): Assume scopeLine always same as line.
|
||||
m->debug_compile_unit->id);
|
||||
if (di->Proc.types.count > 0) {
|
||||
for_array(type_index, di->Proc.types) {
|
||||
if (type_index > 0) {
|
||||
ir_write_byte(f, ',');
|
||||
}
|
||||
if (di->Proc.types[type_index]) {
|
||||
ir_fprintf(f, "!%d", di->Proc.types[type_index]->id);
|
||||
} else {
|
||||
ir_write_str_lit(f, "null");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ir_write_str_lit(f, "null");
|
||||
}
|
||||
ir_write_str_lit(f, "})"); // !DISubroutineTypes close
|
||||
ir_write_byte(f, ')');
|
||||
m->debug_compile_unit->id,
|
||||
di->Proc.types->id);
|
||||
ir_write_byte(f, ')'); // !DISubprogram(
|
||||
break;
|
||||
case irDebugInfo_LocalVariable: {
|
||||
ir_fprintf(f, "!DILocalVariable("
|
||||
@@ -2074,7 +2060,7 @@ void print_llvm_ir(irGen *ir) {
|
||||
di->CompositeType.size,
|
||||
di->CompositeType.align);
|
||||
ir_print_debug_encoding(f, irDebugInfo_CompositeType, di->CompositeType.tag);
|
||||
if (di->CompositeType.scope) {
|
||||
if (di->CompositeType.scope != nullptr) {
|
||||
ir_fprintf(f, ", scope: !%d"
|
||||
", file: !%d"
|
||||
", line: %td",
|
||||
@@ -2082,18 +2068,12 @@ void print_llvm_ir(irGen *ir) {
|
||||
di->CompositeType.file->id,
|
||||
di->CompositeType.pos.line);
|
||||
}
|
||||
if (di->CompositeType.base_type) {
|
||||
if (di->CompositeType.base_type != nullptr) {
|
||||
GB_ASSERT(di->CompositeType.tag == irDebugBasicEncoding_enumeration_type);
|
||||
ir_fprintf(f, ", baseType: !%d", di->CompositeType.base_type->id);
|
||||
}
|
||||
if (di->CompositeType.elements.count > 0) {
|
||||
ir_write_str_lit(f, ", elements: !{");
|
||||
for_array(element_index, di->CompositeType.elements) {
|
||||
ir_fprintf(f, "%s!%d",
|
||||
element_index > 0 ? ", " : "",
|
||||
di->CompositeType.elements[element_index]->id);
|
||||
}
|
||||
ir_write_byte(f, '}');
|
||||
if (di->CompositeType.elements != nullptr) {
|
||||
ir_fprintf(f, ", elements: !%d", di->CompositeType.elements->id);
|
||||
}
|
||||
ir_write_byte(f, ')');
|
||||
}
|
||||
@@ -2108,6 +2088,7 @@ void print_llvm_ir(irGen *ir) {
|
||||
ir_write_byte(f, ')');
|
||||
break;
|
||||
}
|
||||
// TODO(lach): Merge w/ DebugInfoArray
|
||||
case irDebugInfo_AllProcs:
|
||||
ir_fprintf(f, "!{");
|
||||
for_array(proc_index, di->AllProcs.procs) {
|
||||
@@ -2117,6 +2098,19 @@ void print_llvm_ir(irGen *ir) {
|
||||
}
|
||||
ir_write_byte(f, '}');
|
||||
break;
|
||||
case irDebugInfo_DebugInfoArray:
|
||||
ir_fprintf(f, "!{");
|
||||
for_array(element_index, di->DebugInfoArray.elements) {
|
||||
irDebugInfo *elem = di->DebugInfoArray.elements[element_index];
|
||||
if (element_index > 0) {ir_write_str_lit(f, ", ");}
|
||||
if (elem) {
|
||||
ir_fprintf(f, "!%d", elem->id);
|
||||
} else {
|
||||
ir_fprintf(f, "null"); // NOTE(lachsinc): Proc's can contain "nullptr" entries to represent void return values.
|
||||
}
|
||||
}
|
||||
ir_write_byte(f, '}');
|
||||
break;
|
||||
|
||||
default:
|
||||
GB_PANIC("Unhandled irDebugInfo kind %d", di->kind);
|
||||
|
||||
Reference in New Issue
Block a user