aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_debug.cpp
diff options
context:
space:
mode:
authorColin Davidson <colrdavidson@gmail.com>2024-09-24 02:32:06 -0700
committerColin Davidson <colrdavidson@gmail.com>2024-09-24 02:32:06 -0700
commitf3ab14b8ccb45d0fef8a96937635bdf0943ce7d6 (patch)
tree1309d7c797117463996a84522ef3d1c9713a286c /src/llvm_backend_debug.cpp
parent99938c7d4fb26d43a07dd4b8f4f00ab87e67e73f (diff)
parentf7d74ff3a8596efef67d151ffb758ed085e94be0 (diff)
Merge branch 'master' into macharena
Diffstat (limited to 'src/llvm_backend_debug.cpp')
-rw-r--r--src/llvm_backend_debug.cpp147
1 files changed, 101 insertions, 46 deletions
diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp
index c896f889d..5cc79dcc8 100644
--- a/src/llvm_backend_debug.cpp
+++ b/src/llvm_backend_debug.cpp
@@ -55,6 +55,16 @@ gb_internal void lb_debug_file_line(lbModule *m, Ast *node, LLVMMetadataRef *fil
}
}
+gb_internal LLVMMetadataRef lb_debug_procedure_parameters(lbModule *m, Type *type) {
+ if (is_type_proc(type)) {
+ return lb_debug_type(m, t_rawptr);
+ }
+ if (type->kind == Type_Tuple && type->Tuple.variables.count == 1) {
+ return lb_debug_procedure_parameters(m, type->Tuple.variables[0]->type);
+ }
+ return lb_debug_type(m, type);
+}
+
gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) {
i64 size = type_size_of(type); // Check size
gb_unused(size);
@@ -72,13 +82,36 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type)
parameter_count += 1;
}
}
- LLVMMetadataRef *parameters = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, parameter_count);
- unsigned param_index = 0;
- if (type->Proc.result_count == 0) {
- parameters[param_index++] = nullptr;
- } else {
- parameters[param_index++] = lb_debug_type(m, type->Proc.results);
+ auto parameters = array_make<LLVMMetadataRef>(permanent_allocator(), 0, type->Proc.param_count+type->Proc.result_count+2);
+
+ array_add(&parameters, cast(LLVMMetadataRef)nullptr);
+
+ bool return_is_tuple = false;
+ if (type->Proc.result_count != 0) {
+ Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
+ if (is_type_proc(single_ret)) {
+ single_ret = t_rawptr;
+ }
+ if (is_type_tuple(single_ret) && is_calling_convention_odin(type->Proc.calling_convention)) {
+ LLVMTypeRef actual = lb_type_internal_for_procedures_raw(m, type);
+ actual = LLVMGetReturnType(actual);
+ if (actual == nullptr) {
+ // results were passed as a single pointer
+ parameters[0] = lb_debug_procedure_parameters(m, single_ret);
+ } else {
+ LLVMTypeRef possible = lb_type(m, type->Proc.results);
+ if (possible == actual) {
+ // results were returned directly
+ parameters[0] = lb_debug_procedure_parameters(m, single_ret);
+ } else {
+ // resulsts were returned separately
+ return_is_tuple = true;
+ }
+ }
+ } else {
+ parameters[0] = lb_debug_procedure_parameters(m, single_ret);
+ }
}
LLVMMetadataRef file = nullptr;
@@ -88,8 +121,22 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type)
if (e->kind != Entity_Variable) {
continue;
}
- parameters[param_index] = lb_debug_type(m, e->type);
- param_index += 1;
+ array_add(&parameters, lb_debug_procedure_parameters(m, e->type));
+ }
+
+
+ if (return_is_tuple) {
+ Type *results = type->Proc.results;
+ GB_ASSERT(results != nullptr && results->kind == Type_Tuple);
+ isize count = results->Tuple.variables.count;
+ parameters[0] = lb_debug_procedure_parameters(m, results->Tuple.variables[count-1]->type);
+ for (isize i = 0; i < count-1; i++) {
+ array_add(&parameters, lb_debug_procedure_parameters(m, results->Tuple.variables[i]->type));
+ }
+ }
+
+ if (type->Proc.calling_convention == ProcCC_Odin) {
+ array_add(&parameters, lb_debug_type(m, t_context_ptr));
}
LLVMDIFlags flags = LLVMDIFlagZero;
@@ -97,7 +144,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type)
flags = LLVMDIFlagNoReturn;
}
- return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters, parameter_count, flags);
+ return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters.data, cast(unsigned)parameters.count, flags);
}
gb_internal LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &name, Type *type, u64 offset_in_bits) {
@@ -505,6 +552,48 @@ gb_internal LLVMMetadataRef lb_debug_bitset(lbModule *m, Type *type, String name
return final_decl;
}
+gb_internal LLVMMetadataRef lb_debug_bitfield(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
+ Type *bt = base_type(type);
+ GB_ASSERT(bt->kind == Type_BitField);
+
+ lb_debug_file_line(m, bt->BitField.node, &file, &line);
+
+ u64 size_in_bits = 8*type_size_of(bt);
+ u32 align_in_bits = 8*cast(u32)type_align_of(bt);
+
+ unsigned element_count = cast(unsigned)bt->BitField.fields.count;
+ LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
+
+ u64 offset_in_bits = 0;
+ for (unsigned i = 0; i < element_count; i++) {
+ Entity *f = bt->BitField.fields[i];
+ u8 bit_size = bt->BitField.bit_sizes[i];
+ GB_ASSERT(f->kind == Entity_Variable);
+ String name = f->token.string;
+ elements[i] = LLVMDIBuilderCreateBitFieldMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, line,
+ bit_size, offset_in_bits, 0,
+ LLVMDIFlagZero, lb_debug_type(m, f->type)
+ );
+
+ offset_in_bits += bit_size;
+ }
+
+ LLVMMetadataRef final_decl = LLVMDIBuilderCreateStructType(
+ m->debug_builder, scope,
+ cast(char const *)name.text, cast(size_t)name.len,
+ file, line,
+ size_in_bits, align_in_bits,
+ LLVMDIFlagZero,
+ nullptr,
+ elements, element_count,
+ 0,
+ nullptr,
+ "", 0
+ );
+ lb_set_llvm_metadata(m, type, final_decl);
+ return final_decl;
+}
+
gb_internal LLVMMetadataRef lb_debug_enum(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_Enum);
@@ -769,6 +858,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
case Type_Union: return lb_debug_union( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
case Type_BitSet: return lb_debug_bitset( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
case Type_Enum: return lb_debug_enum( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
+ case Type_BitField: return lb_debug_bitfield( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0);
case Type_Tuple:
if (type->Tuple.variables.count == 1) {
@@ -854,42 +944,6 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
lb_debug_type(m, type->Matrix.elem),
subscripts, gb_count_of(subscripts));
}
-
- case Type_BitField: {
- LLVMMetadataRef parent_scope = nullptr;
- LLVMMetadataRef scope = nullptr;
- LLVMMetadataRef file = nullptr;
- unsigned line = 0;
- u64 size_in_bits = 8*cast(u64)type_size_of(type);
- u32 align_in_bits = 8*cast(u32)type_align_of(type);
- LLVMDIFlags flags = LLVMDIFlagZero;
-
- unsigned element_count = cast(unsigned)type->BitField.fields.count;
- LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count);
-
- u64 offset_in_bits = 0;
- for (unsigned i = 0; i < element_count; i++) {
- Entity *f = type->BitField.fields[i];
- u8 bit_size = type->BitField.bit_sizes[i];
- GB_ASSERT(f->kind == Entity_Variable);
- String name = f->token.string;
- unsigned field_line = 0;
- LLVMDIFlags field_flags = LLVMDIFlagZero;
- elements[i] = LLVMDIBuilderCreateBitFieldMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, field_line,
- bit_size, offset_in_bits, offset_in_bits,
- field_flags, lb_debug_type(m, f->type)
- );
-
- offset_in_bits += bit_size;
- }
-
-
- return LLVMDIBuilderCreateStructType(m->debug_builder, parent_scope, "", 0, file, line,
- size_in_bits, align_in_bits, flags,
- nullptr, elements, element_count, 0, nullptr,
- "", 0
- );
- }
}
GB_PANIC("Invalid type %s", type_to_string(type));
@@ -969,12 +1023,13 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
return lb_debug_struct(m, type, bt, name, scope, file, line);
}
- case Type_Struct: return lb_debug_struct(m, type, base_type(type), name, scope, file, line);
+ case Type_Struct: return lb_debug_struct(m, type, bt, name, scope, file, line);
case Type_Slice: return lb_debug_slice(m, type, name, scope, file, line);
case Type_DynamicArray: return lb_debug_dynamic_array(m, type, name, scope, file, line);
case Type_Union: return lb_debug_union(m, type, name, scope, file, line);
case Type_BitSet: return lb_debug_bitset(m, type, name, scope, file, line);
case Type_Enum: return lb_debug_enum(m, type, name, scope, file, line);
+ case Type_BitField: return lb_debug_bitfield(m, type, name, scope, file, line);
}
}