aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2025-05-17 11:36:30 +0100
committergingerBill <bill@gingerbill.org>2025-05-17 11:36:30 +0100
commit63304af47efae07dc540b8efb115b9ca9604f349 (patch)
tree34456114a5df109cce5d2fb3efe6f00865e999f8 /src
parentd77124feae57a919734e77e88c3801d86ee097dd (diff)
parent326454f0f00945a2a4f5d02e8d8c5bc37f472883 (diff)
Merge branch 'master' of https://github.com/odin-lang/Odin
Diffstat (limited to 'src')
-rw-r--r--src/llvm_abi.cpp2
-rw-r--r--src/llvm_backend_debug.cpp56
-rw-r--r--src/llvm_backend_stmt.cpp72
3 files changed, 124 insertions, 6 deletions
diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp
index baad3f873..af08722c3 100644
--- a/src/llvm_abi.cpp
+++ b/src/llvm_abi.cpp
@@ -1246,7 +1246,7 @@ namespace lbAbiArm64 {
cast_type = LLVMIntTypeInContext(c, cast(unsigned)(size*8));
} else {
LLVMTypeRef llvm_i64 = LLVMIntTypeInContext(c, 64);
- cast_type = LLVMArrayType2(llvm_i64, 2);
+ cast_type = llvm_array_type(llvm_i64, 2);
}
return lb_arg_type_direct(return_type, cast_type, nullptr, nullptr);
}
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
+}
diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp
index 89737a454..44a78b036 100644
--- a/src/llvm_backend_stmt.cpp
+++ b/src/llvm_backend_stmt.cpp
@@ -136,7 +136,6 @@ gb_internal lbBranchBlocks lb_lookup_branch_blocks(lbProcedure *p, Ast *ident) {
return empty;
}
-
gb_internal lbTargetList *lb_push_target_list(lbProcedure *p, Ast *label, lbBlock *break_, lbBlock *continue_, lbBlock *fallthrough_) {
lbTargetList *tl = gb_alloc_item(permanent_allocator(), lbTargetList);
tl->prev = p->target_list;
@@ -688,6 +687,18 @@ gb_internal void lb_build_range_interval(lbProcedure *p, AstBinaryExpr *node,
lbBlock *body = lb_create_block(p, "for.interval.body");
lbBlock *done = lb_create_block(p, "for.interval.done");
+ // TODO(tf2spi): This is inlined in more than several places.
+ // Putting this in a function might be preferred.
+ // LLVMSetCurrentDebugLocation2 has side effects,
+ // so I didn't want to hide that before it got reviewed.
+ if (rs->label != nullptr && p->debug_info != nullptr) {
+ lbBlock *label = lb_create_block(p, "for.interval.label");
+ lb_emit_jump(p, label);
+ lb_start_block(p, label);
+
+ LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, rs->label));
+ lb_add_debug_label(p, rs->label, label);
+ }
lb_emit_jump(p, loop);
lb_start_block(p, loop);
@@ -893,6 +904,14 @@ gb_internal void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs
lbAddr index = lb_add_local_generated(p, t_int, false);
+ if (rs->label != nullptr && p->debug_info != nullptr) {
+ lbBlock *label = lb_create_block(p, "for.soa.label");
+ lb_emit_jump(p, label);
+ lb_start_block(p, label);
+
+ LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, rs->label));
+ lb_add_debug_label(p, rs->label, label);
+ }
if (!is_reverse) {
/*
for x, i in array {
@@ -970,7 +989,6 @@ gb_internal void lb_build_range_stmt_struct_soa(lbProcedure *p, AstRangeStmt *rs
lb_store_range_stmt_val(p, val1, lb_addr_load(p, index));
}
-
lb_push_target_list(p, rs->label, done, loop, nullptr);
lb_build_stmt(p, rs->body);
@@ -1029,6 +1047,15 @@ gb_internal void lb_build_range_stmt(lbProcedure *p, AstRangeStmt *rs, Scope *sc
lbBlock *done = nullptr;
bool is_map = false;
+ if (rs->label != nullptr && p->debug_info != nullptr) {
+ lbBlock *label = lb_create_block(p, "for.range.label");
+ lb_emit_jump(p, label);
+ lb_start_block(p, label);
+
+ LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, rs->label));
+ lb_add_debug_label(p, rs->label, label);
+ }
+
if (tav.mode == Addressing_Type) {
lb_build_range_enum(p, type_deref(tav.type), val0_type, &val, &key, &loop, &done);
} else {
@@ -1530,6 +1557,14 @@ gb_internal bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, boo
gb_internal void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss, Scope *scope) {
lb_open_scope(p, scope);
+ if (ss->label != nullptr && p->debug_info != nullptr) {
+ lbBlock *label = lb_create_block(p, "switch.label");
+ lb_emit_jump(p, label);
+ lb_start_block(p, label);
+
+ LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, ss->label));
+ lb_add_debug_label(p, ss->label, label);
+ }
if (ss->init != nullptr) {
lb_build_stmt(p, ss->init);
}
@@ -1736,6 +1771,7 @@ gb_internal lbAddr lb_store_range_stmt_val(lbProcedure *p, Ast *stmt_val, lbValu
gb_internal void lb_type_case_body(lbProcedure *p, Ast *label, Ast *clause, lbBlock *body, lbBlock *done) {
ast_node(cc, CaseClause, clause);
+ // NOTE(tf2spi): Debug info for label not generated here on purpose
lb_push_target_list(p, label, done, nullptr, nullptr);
lb_build_stmt_list(p, cc->stmts);
lb_close_scope(p, lbDeferExit_Default, body, clause);
@@ -2307,6 +2343,14 @@ gb_internal void lb_build_if_stmt(lbProcedure *p, Ast *node) {
else_ = lb_create_block(p, "if.else");
}
if (is->label != nullptr) {
+ if (p->debug_info != nullptr) {
+ lbBlock *label = lb_create_block(p, "if.label");
+ lb_emit_jump(p, label);
+ lb_start_block(p, label);
+
+ LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, is->label));
+ lb_add_debug_label(p, is->label, label);
+ }
lbTargetList *tl = lb_push_target_list(p, is->label, done, nullptr, nullptr);
tl->is_block = true;
}
@@ -2399,12 +2443,19 @@ gb_internal void lb_build_for_stmt(lbProcedure *p, Ast *node) {
lb_push_target_list(p, fs->label, done, post, nullptr);
+ if (fs->label != nullptr && p->debug_info != nullptr) {
+ lbBlock *label = lb_create_block(p, "for.label");
+ lb_emit_jump(p, label);
+ lb_start_block(p, label);
+
+ LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, fs->label));
+ lb_add_debug_label(p, fs->label, label);
+ }
if (fs->init != nullptr) {
- #if 1
lbBlock *init = lb_create_block(p, "for.init");
lb_emit_jump(p, init);
lb_start_block(p, init);
- #endif
+
lb_build_stmt(p, fs->init);
}
@@ -2420,7 +2471,6 @@ gb_internal void lb_build_for_stmt(lbProcedure *p, Ast *node) {
lb_start_block(p, body);
}
-
lb_build_stmt(p, fs->body);
lb_pop_target_list(p);
@@ -2694,9 +2744,21 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) {
case_ast_node(bs, BlockStmt, node);
+ lbBlock *body = nullptr;
lbBlock *done = nullptr;
if (bs->label != nullptr) {
+ if (p->debug_info != nullptr) {
+ lbBlock *label = lb_create_block(p, "block.label");
+ lb_emit_jump(p, label);
+ lb_start_block(p, label);
+
+ LLVMSetCurrentDebugLocation2(p->builder, lb_debug_location_from_ast(p, bs->label));
+ lb_add_debug_label(p, bs->label, label);
+ }
+ body = lb_create_block(p, "block.body");
done = lb_create_block(p, "block.done");
+ lb_emit_jump(p, body);
+ lb_start_block(p, body);
lbTargetList *tl = lb_push_target_list(p, bs->label, done, nullptr, nullptr);
tl->is_block = true;
}