aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_debug.cpp
diff options
context:
space:
mode:
authortf2spi <misomosispi@gmail.com>2025-05-15 16:11:06 -0400
committerGitHub <noreply@github.com>2025-05-15 22:11:06 +0200
commit2f636886a565c113840d8e0b81454a24c6f7b9a0 (patch)
tree67f737dc5079385664537571dbdec23ad750fd02 /src/llvm_backend_debug.cpp
parent2d00f8d69d62344e6ff419998899348244e66ed2 (diff)
Add debug info for labels (#4385)
* Emit label debug info w/o location * Insert debug label call * Slight refactor for later fix * Improve debug labels for block statements * Improve debug info with for loops * Generate label lbBlocks w/ debug * Lightly refactor lb_add_debug_label * Revise comments, add null check assertion * Use LLVM-C API for debug labels * Prefer C DILabel API for POSIX, fallback to CPP * Use version check for LLVM-C DILabel
Diffstat (limited to 'src/llvm_backend_debug.cpp')
-rw-r--r--src/llvm_backend_debug.cpp56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp
index 53c007d8d..8339a021b 100644
--- a/src/llvm_backend_debug.cpp
+++ b/src/llvm_backend_debug.cpp
@@ -1295,3 +1295,59 @@ gb_internal void add_debug_info_for_global_constant_from_entity(lbGenerator *gen
}
}
}
+
+gb_internal void lb_add_debug_label(lbProcedure *p, Ast *label, lbBlock *target) {
+// NOTE(tf2spi): LLVM-C DILabel API used only existed for major versions 20+
+#if LLVM_VERSION_MAJOR >= 20
+ if (p == nullptr || p->debug_info == nullptr) {
+ return;
+ }
+ if (target == nullptr || label == nullptr || label->kind != Ast_Label) {
+ return;
+ }
+ Token label_token = label->Label.token;
+ if (is_blank_ident(label_token.string)) {
+ return;
+ }
+ lbModule *m = p->module;
+ if (m == nullptr) {
+ return;
+ }
+
+ AstFile *file = label->file();
+ LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file);
+ if (llvm_file == nullptr) {
+ debugf("llvm file not found for label\n");
+ return;
+ }
+ LLVMMetadataRef llvm_scope = p->debug_info;
+ if(llvm_scope == nullptr) {
+ debugf("llvm scope not found for label\n");
+ return;
+ }
+ LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, label_token.pos);
+ LLVMBasicBlockRef llvm_block = target->block;
+ if (llvm_block == nullptr || llvm_debug_loc == nullptr) {
+ return;
+ }
+ LLVMMetadataRef llvm_label = LLVMDIBuilderCreateLabel(
+ m->debug_builder,
+ llvm_scope,
+ (const char *)label_token.string.text,
+ (size_t)label_token.string.len,
+ llvm_file,
+ label_token.pos.line,
+
+ // NOTE(tf2spi): Defaults to false in LLVM API, but I'd rather not take chances
+ // Always preserve the label no matter what when debugging
+ true
+ );
+ GB_ASSERT(llvm_label != nullptr);
+ (void)LLVMDIBuilderInsertLabelAtEnd(
+ m->debug_builder,
+ llvm_label,
+ llvm_debug_loc,
+ llvm_block
+ );
+#endif
+}