From 3b583cbac752435ec9385201f27438c96b6f8f7b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 2 Nov 2022 00:05:51 +0000 Subject: Add debug symbols for global constants of integers, bools, enums, runes, & pointers. Variables are namespaced with `pkg::name` or `name` if built-in or the initial package for convenience. --- src/llvm_backend_debug.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 29b0ab488..8a98b7f39 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -1080,3 +1080,116 @@ void lb_add_debug_context_variable(lbProcedure *p, lbAddr const &ctx) { lb_add_debug_local_variable(p, ptr, t_context, token); } + + +String debug_info_mangle_constant_name(Entity *e, bool *did_allocate_) { + String name = e->token.string; + if (e->pkg && e->pkg->name.len > 0) { + // NOTE(bill): C++ NONSENSE FOR DEBUG SHITE! + name = concatenate3_strings(heap_allocator(), e->pkg->name, str_lit("::"), name); + if (did_allocate_) *did_allocate_ = true; + } + return name; +} + +void add_debug_info_global_variable_expr(lbModule *m, String const &name, LLVMMetadataRef dtype, LLVMMetadataRef expr) { + LLVMMetadataRef scope = nullptr; + LLVMMetadataRef file = nullptr; + unsigned line = 0; + + LLVMMetadataRef decl = nullptr; + + LLVMDIBuilderCreateGlobalVariableExpression( + m->debug_builder, scope, + cast(char const *)name.text, cast(size_t)name.len, + "", 0, // Linkage + file, line, dtype, + false, // local to unit + expr, decl, 8/*AlignInBits*/); +} + +void add_debug_info_for_global_constant_internal_i64(lbModule *m, Entity *e, LLVMMetadataRef dtype, i64 v) { + LLVMMetadataRef expr = LLVMDIBuilderCreateConstantValueExpression(m->debug_builder, v); + + bool did_allocate = false; + String name = debug_info_mangle_constant_name(e, &did_allocate); + defer (if (did_allocate) { + gb_free(heap_allocator(), name.text); + }); + + add_debug_info_global_variable_expr(m, name, dtype, expr); + if ((e->pkg && e->pkg->kind == Package_Init) || + (e->scope && (e->scope->flags & ScopeFlag_Global))) { + add_debug_info_global_variable_expr(m, e->token.string, dtype, expr); + } +} + +void add_debug_info_for_global_constant_from_entity(lbGenerator *gen, Entity *e) { + if (e == nullptr || e->kind != Entity_Constant) { + return; + } + if (is_blank_ident(e->token)) { + return; + } + lbModule *m = &gen->default_module; + if (USE_SEPARATE_MODULES) { + m = lb_pkg_module(gen, e->pkg); + } + + if (is_type_integer(e->type)) { + ExactValue const &value = e->Constant.value; + if (value.kind == ExactValue_Integer) { + LLVMMetadataRef dtype = nullptr; + i64 v = 0; + bool is_signed = false; + if (big_int_is_neg(&value.value_integer)) { + v = exact_value_to_i64(value); + is_signed = true; + } else { + v = cast(i64)exact_value_to_u64(value); + } + if (is_type_untyped(e->type)) { + dtype = lb_debug_type(m, is_signed ? t_i64 : t_u64); + } else { + dtype = lb_debug_type(m, e->type); + } + + add_debug_info_for_global_constant_internal_i64(m, e, dtype, v); + } + } else if (is_type_rune(e->type)) { + ExactValue const &value = e->Constant.value; + if (value.kind == ExactValue_Integer) { + LLVMMetadataRef dtype = lb_debug_type(m, t_rune); + i64 v = exact_value_to_i64(value); + add_debug_info_for_global_constant_internal_i64(m, e, dtype, v); + } + } else if (is_type_boolean(e->type)) { + ExactValue const &value = e->Constant.value; + if (value.kind == ExactValue_Bool) { + LLVMMetadataRef dtype = lb_debug_type(m, default_type(e->type)); + i64 v = cast(i64)value.value_bool; + + add_debug_info_for_global_constant_internal_i64(m, e, dtype, v); + } + } else if (is_type_enum(e->type)) { + ExactValue const &value = e->Constant.value; + if (value.kind == ExactValue_Integer) { + LLVMMetadataRef dtype = lb_debug_type(m, default_type(e->type)); + i64 v = 0; + if (big_int_is_neg(&value.value_integer)) { + v = exact_value_to_i64(value); + } else { + v = cast(i64)exact_value_to_u64(value); + } + + add_debug_info_for_global_constant_internal_i64(m, e, dtype, v); + } + } else if (is_type_pointer(e->type)) { + ExactValue const &value = e->Constant.value; + if (value.kind == ExactValue_Integer) { + LLVMMetadataRef dtype = lb_debug_type(m, default_type(e->type)); + i64 v = cast(i64)exact_value_to_u64(value); + add_debug_info_for_global_constant_internal_i64(m, e, dtype, v); + } + } +} \ No newline at end of file -- cgit v1.2.3