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.
This commit is contained in:
gingerBill
2022-11-02 00:05:51 +00:00
parent 382bd87667
commit 3b583cbac7
3 changed files with 147 additions and 0 deletions
+7
View File
@@ -499,6 +499,13 @@ i64 exact_value_to_i64(ExactValue v) {
}
return 0;
}
u64 exact_value_to_u64(ExactValue v) {
v = exact_value_to_integer(v);
if (v.kind == ExactValue_Integer) {
return big_int_to_u64(&v.value_integer);
}
return 0;
}
f64 exact_value_to_f64(ExactValue v) {
v = exact_value_to_float(v);
if (v.kind == ExactValue_Float) {
+27
View File
@@ -1736,6 +1736,13 @@ void lb_generate_code(lbGenerator *gen) {
lbProcedure *startup_runtime = lb_create_startup_runtime(default_module, startup_type_info, objc_names, global_variables);
gb_unused(startup_runtime);
if (build_context.ODIN_DEBUG) {
for_array(i, builtin_pkg->scope->elements.entries) {
Entity *e = builtin_pkg->scope->elements.entries[i].value;
add_debug_info_for_global_constant_from_entity(gen, e);
}
}
TIME_SECTION("LLVM Global Procedures and Types");
for_array(i, info->entities) {
Entity *e = info->entities[i];
@@ -1759,6 +1766,11 @@ void lb_generate_code(lbGenerator *gen) {
case Entity_TypeName:
case Entity_Procedure:
break;
case Entity_Constant:
if (build_context.ODIN_DEBUG) {
add_debug_info_for_global_constant_from_entity(gen, e);
}
break;
}
bool polymorphic_struct = false;
@@ -1820,6 +1832,21 @@ void lb_generate_code(lbGenerator *gen) {
lb_finalize_objc_names(objc_names);
if (build_context.ODIN_DEBUG) {
TIME_SECTION("LLVM Debug Info for global constant value declarations");
{
// lbModule *m = default_module;
}
// if (gen->modules.entries.count == 1) {
// } else {
// for_array(j, gen->modules.entries) {
// lbModule *m = gen->modules.entries[j].value;
// if (m->debug_builder != nullptr) {
// }
// }
// }
TIME_SECTION("LLVM Debug Info Complete Types and Finalize");
for_array(j, gen->modules.entries) {
lbModule *m = gen->modules.entries[j].value;
+113
View File
@@ -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);
}
}
}