diff options
| author | gingerBill <bill@gingerbill.org> | 2021-03-22 14:51:19 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-03-22 14:51:19 +0000 |
| commit | 8ab1b32fe1b203a0d73e603bb7d5cba4e194a49c (patch) | |
| tree | a5804cab88d7f4e0720348ea58c63b52b28b63f0 /src/llvm_backend.cpp | |
| parent | 0355908af85081a1d462a2d7cd50a6c00b7e8a52 (diff) | |
Add local debug variable support for -llvm-api
Diffstat (limited to 'src/llvm_backend.cpp')
| -rw-r--r-- | src/llvm_backend.cpp | 205 |
1 files changed, 151 insertions, 54 deletions
diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 923c71c5c..907977fae 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1490,6 +1490,56 @@ LLVMMetadataRef lb_debug_location_from_ast(lbProcedure *p, Ast *node) { return lb_debug_location_from_token_pos(p, ast_token(node).pos); } +LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) { + Type *original_type = type; + + LLVMContextRef ctx = m->ctx; + i64 size = type_size_of(type); // Check size + + GB_ASSERT(type != t_invalid); + + unsigned const word_size = cast(unsigned)build_context.word_size; + unsigned const word_bits = cast(unsigned)(8*build_context.word_size); + + GB_ASSERT(type->kind == Type_Proc); + LLVMTypeRef return_type = LLVMVoidTypeInContext(ctx); + unsigned parameter_count = 1; + for (i32 i = 0; i < type->Proc.param_count; i++) { + Entity *e = type->Proc.params->Tuple.variables[i]; + if (e->kind == Entity_Variable) { + 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); + } + + LLVMMetadataRef parent_scope = nullptr; + LLVMMetadataRef scope = nullptr; + LLVMMetadataRef file = nullptr; + + for (i32 i = 0; i < type->Proc.param_count; i++) { + Entity *e = type->Proc.params->Tuple.variables[i]; + if (e->kind != Entity_Variable) { + continue; + } + parameters[param_index] = lb_debug_type(m, e->type); + param_index += 1; + } + + LLVMDIFlags flags = LLVMDIFlagZero; + if (type->Proc.diverging) { + flags = LLVMDIFlagNoReturn; + } + + return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters, parameter_count, flags); +} + LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { Type *original_type = type; @@ -1573,7 +1623,7 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { case Basic_rawptr: { - LLVMMetadataRef void_type = LLVMDIBuilderCreateBasicType(m->debug_builder, "void", 4, 8, 0, LLVMDIFlagZero); + LLVMMetadataRef void_type = LLVMDIBuilderCreateBasicType(m->debug_builder, "void", 4, 8, LLVMDWARFTypeEncoding_Unsigned, LLVMDIFlagZero); return LLVMDIBuilderCreatePointerType(m->debug_builder, void_type, word_bits, word_bits, LLVMDWARFTypeEncoding_Address, "rawptr", 6); } case Basic_string: @@ -1759,7 +1809,7 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { case Type_Enum: { - #if 1 + #if 0 return lb_debug_type(m, base_enum_type(type)); #else LLVMMetadataRef scope = nullptr; @@ -1820,51 +1870,8 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { case Type_Proc: { - LLVMTypeRef return_type = LLVMVoidTypeInContext(ctx); - unsigned parameter_count = 1; - for (i32 i = 0; i < type->Proc.param_count; i++) { - Entity *e = type->Proc.params->Tuple.variables[i]; - if (e->kind == Entity_Variable) { - 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); - } - - LLVMMetadataRef parent_scope = nullptr; - LLVMMetadataRef scope = nullptr; - LLVMMetadataRef file = nullptr; - - for (i32 i = 0; i < type->Proc.param_count; i++) { - Entity *e = type->Proc.params->Tuple.variables[i]; - if (e->kind != Entity_Variable) { - continue; - } - #if 1 - parameters[param_index] = lb_debug_type(m, e->type); - #else - String name = e->token.string; - unsigned line = cast(unsigned)e->token.pos.line; - parameters[param_index] = LLVMDIBuilderCreateParameterVariable(m->debug_builder, scope, - cast(char const *)name.text, name.len, param_index, file, line, - lb_debug_type(m, e->type), false, LLVMDIFlagZero - ); - #endif - param_index += 1; - } - - LLVMDIFlags flags = LLVMDIFlagZero; - if (type->Proc.diverging) { - flags = LLVMDIFlagNoReturn; - } - - return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters, parameter_count, flags); + LLVMMetadataRef proc_underlying_type = lb_debug_type_internal_proc(m, type); + return LLVMDIBuilderCreatePointerType(m->debug_builder, proc_underlying_type, word_bits, word_bits, 0, nullptr, 0); } break; @@ -1935,11 +1942,31 @@ LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) { idt.type = type; switch (bt->kind) { + case Type_Enum: + { + LLVMMetadataRef scope = nullptr; + LLVMMetadataRef file = nullptr; + unsigned line = 0; + unsigned element_count = cast(unsigned)bt->Enum.fields.count; + LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count); + Type *ct = base_enum_type(type); + LLVMBool is_unsigned = is_type_unsigned(ct); + for (unsigned i = 0; i < element_count; i++) { + Entity *f = bt->Enum.fields[i]; + GB_ASSERT(f->kind == Entity_Constant); + String name = f->token.string; + i64 value = exact_value_to_i64(f->Constant.value); + elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)name.text, cast(size_t)name.len, value, is_unsigned); + } + LLVMMetadataRef class_type = lb_debug_type(m, ct); + return LLVMDIBuilderCreateEnumerationType(m->debug_builder, scope, name_text, name_len, file, line, 8*type_size_of(type), 8*cast(unsigned)type_align_of(type), elements, element_count, class_type); + } + + case Type_Basic: case Type_Pointer: case Type_Array: case Type_EnumeratedArray: - case Type_Enum: case Type_Tuple: case Type_Proc: case Type_BitSet: @@ -2063,9 +2090,14 @@ void lb_debug_complete_types(lbModule *m) { case Type_Map: break; case Type_Struct: + if (file == nullptr) { + GB_ASSERT(bt->Struct.node != nullptr); + file = lb_get_llvm_metadata(m, bt->Struct.node->file); + line_number = cast(unsigned)ast_token(bt->Struct.node).pos.line; + } + type_set_offsets(bt); - /* record_scope = lb_get_llvm_metadata(m, bt->Struct.scope); element_count = cast(unsigned)bt->Struct.fields.count; elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); @@ -2086,10 +2118,14 @@ void lb_debug_complete_types(lbModule *m) { field_flags, lb_debug_type(m, f->type) ); } - */ break; case Type_Union: - /* + if (file == nullptr) { + GB_ASSERT(bt->Union.node != nullptr); + file = lb_get_llvm_metadata(m, bt->Union.node->file); + line_number = cast(unsigned)ast_token(bt->Union.node).pos.line; + } + record_scope = lb_get_llvm_metadata(m, bt->Union.scope); element_count = cast(unsigned)bt->Union.variants.count; elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); @@ -2113,7 +2149,6 @@ void lb_debug_complete_types(lbModule *m) { field_flags, lb_debug_type(m, variant) ); } - */ break; } @@ -2434,13 +2469,15 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { if (m->debug_builder) { // Debug Information + Type *bt = base_type(p->type); + unsigned line = cast(unsigned)entity->token.pos.line; LLVMMetadataRef scope = nullptr; LLVMMetadataRef file = nullptr; LLVMMetadataRef type = nullptr; scope = p->module->debug_compile_unit; - type = lb_debug_type(m, p->type); + type = lb_debug_type_internal_proc(m, bt); if (entity->file != nullptr) { file = lb_get_llvm_metadata(m, entity->file); @@ -2460,7 +2497,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) { unsigned scope_line = line; u32 flags = LLVMDIFlagStaticMember; LLVMBool is_optimized = false; - if (base_type(p->type)->Proc.diverging) { + if (bt->Proc.diverging) { flags |= LLVMDIFlagNoReturn; } if (p->body == nullptr) { @@ -3063,6 +3100,7 @@ lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, i32 p break; default: LLVMBuildStore(p->builder, LLVMConstNull(lb_type(p->module, type)), ptr); + break; } } @@ -3072,6 +3110,52 @@ lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e, bool zero_init, i32 p if (e != nullptr) { lb_add_entity(p->module, e, val); + + if (p->debug_info) do { + lbModule *m = p->module; + String name = e->token.string; + if (name == "" || name == "_") { + break; + } + + LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p); + LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, e->file); + GB_ASSERT(llvm_scope != nullptr); + if (llvm_file == nullptr) { + llvm_file = LLVMDIScopeGetFile(llvm_scope); + } + + if (llvm_file == nullptr) { + break; + } + + if (e->type == nullptr) { + break; + } + if (e->type == t_invalid) { + break; + } + + LLVMDIFlags flags = LLVMDIFlagZero; + LLVMBool always_preserve = false; + + LLVMMetadataRef debug_type = lb_debug_type(m, type); + + LLVMMetadataRef var_info = LLVMDIBuilderCreateAutoVariable( + m->debug_builder, llvm_scope, + cast(char const *)name.text, cast(size_t)name.len, + llvm_file, e->token.pos.line, + debug_type, + always_preserve, flags, 8*alignment + ); + + LLVMValueRef storage = ptr; + LLVMValueRef instr = ptr; + LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, e->token.pos); + LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0); + LLVMDIBuilderInsertDeclareBefore(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, instr); + } while (false); + } return lb_addr(val); @@ -7555,6 +7639,12 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr, } lbValue lb_emit_runtime_call(lbProcedure *p, char const *c_name, Array<lbValue> const &args) { + // LLVMMetadataRef curr_loc = LLVMGetCurrentDebugLocation2(p->builder); + // LLVMSetCurrentDebugLocation2(p->builder, nullptr); + // defer (if (curr_loc) { + // LLVMSetCurrentDebugLocation2(p->builder, curr_loc); + // }); + String name = make_string_c(c_name); @@ -13444,6 +13534,13 @@ void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Debug Info Complete Types"); lb_debug_complete_types(m); + + TIME_SECTION("LLVM Print Module to File"); + if (LLVMPrintModuleToFile(mod, cast(char const *)filepath_ll.text, &llvm_error)) { + gb_printf_err("LLVM Error: %s\n", llvm_error); + gb_exit(1); + return; + } TIME_SECTION("LLVM Debug Info Builder Finalize"); LLVMDIBuilderFinalize(m->debug_builder); } |