Browse Source

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.
gingerBill 2 years ago
parent
commit
3b583cbac7
3 changed files with 147 additions and 0 deletions
  1. 7 0
      src/exact_value.cpp
  2. 27 0
      src/llvm_backend.cpp
  3. 113 0
      src/llvm_backend_debug.cpp

+ 7 - 0
src/exact_value.cpp

@@ -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 - 0
src/llvm_backend.cpp

@@ -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 - 0
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);
+		}
+	}
+}