From 747098efaf3ba466effc15b6f64c394277f4fb48 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 18 Jul 2025 23:48:32 -0400 Subject: [PATCH] Support for using on procedure struct typed arguments --- src/llvm_backend_general.cpp | 14 +++++++++++ src/llvm_backend_proc.cpp | 45 +++++++++++++++++++++++++++++++++--- src/llvm_backend_stmt.cpp | 13 ----------- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index aaa9ffd4d..6241bac3f 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -3199,3 +3199,17 @@ gb_internal void lb_set_linkage_from_entity_flags(lbModule *m, LLVMValueRef valu LLVMSetLinkage(value, LLVMLinkOnceAnyLinkage); } } + +// NOTE(Ed) - Sectr Fork: Added for namespaced names on using statements in debug +// Format: struct_name::field_name +// I tired todo struct_name.field_name it didn't work (nor using struct_name.field_name) +char* debug_lb_make_using_struct_ref_identifier(gbAllocator allocator, String struct_name, String field_name) { + isize name_len = 2 + struct_name.len + 1 + field_name.len + 1; + char* debug_name = gb_alloc_array(allocator, char, name_len); + gb_snprintf(debug_name, name_len, "%.*s::%.*s" + , LIT(struct_name) + , LIT(field_name) + ); + return debug_name; +} + diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 844154064..edb43699d 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -600,13 +600,15 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { unsigned param_index = 0; for_array(i, params->variables) { - Entity *e = params->variables[i]; + Entity *e = params->variables[i]; if (e->kind != Entity_Variable) { continue; } lbArgType *arg_type = &ft->args[param_index]; defer (param_index += 1); + + lbValue ptr = {}; if (arg_type->kind == lbArg_Ignore) { // Even though it is an ignored argument, it might still be referenced in the @@ -625,10 +627,11 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { map_set(&p->direct_parameters, e, param); - lbValue ptr = lb_address_from_load_or_generate_local(p, param); + ptr = lb_address_from_load_or_generate_local(p, param); GB_ASSERT(LLVMIsAAllocaInst(ptr.value)); lb_add_entity(p->module, e, ptr); lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->curr_block); + } } else if (arg_type->kind == lbArg_Indirect) { if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) { @@ -642,7 +645,7 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { } } - lbValue ptr = {}; + ptr = {}; ptr.value = LLVMGetParam(p->value, param_offset+param_index); ptr.type = alloc_type_pointer(e->type); @@ -656,6 +659,42 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block); } } + + if (p->debug_info && (e->flags & EntityFlag_Using)) { + // NOTE(Ed) - Sectr Fork: Added this in for debubability. + // Will add a local ptr variable referencing for every exposed field into the stack frame + + Type* struct_type = base_type(type_deref(e->type)); + if (struct_type == nullptr || struct_type->kind != Type_Struct) { + continue; + } + + String struct_name = e->token.string; + + // Get base struct pointer + //lbValue struct_ptr = lb_build_addr_ptr(p, ast_var); + + wait_signal_until_available(& struct_type->Struct.fields_wait_signal); + for_array(id, struct_type->Struct.fields) + { + Entity* field = struct_type->Struct.fields [ id ]; + if (field->kind != Entity_Variable || ! (field->flags & EntityFlag_Field)) { + continue; + } + Type* type_ptr_field_type = alloc_type_pointer(field->type); + + Token debug_token = field->token; + char* debug_name = debug_lb_make_using_struct_ref_identifier(temporary_allocator(), struct_name, field->token.string); + debug_token.string = make_string((u8*)debug_name, gb_strlen(debug_name)); + + Entity* debug_field = alloc_entity_variable(field->scope, debug_token, field->type); + Selection sel_field = lookup_field_from_index(struct_type, field->Variable.field_index); + + lbAddr field_debug_ptr = lb_add_local(p, type_ptr_field_type, debug_field, false); + lbValue field_ptr = lb_emit_deep_field_gep(p, ptr, sel_field); + lb_addr_store(p, field_debug_ptr, field_ptr); + } + } } } diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 4f070d5b3..9a0e8bdbb 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -2711,19 +2711,6 @@ gb_internal void lb_build_assign_stmt(lbProcedure *p, AstAssignStmt *as) { } } -// NOTE(Ed) - Sectr Fork: Added for namespaced names on using statements in debug -// Format: struct_name::field_name -// I tired todo struct_name.field_name it didn't work (nor using struct_name.field_name) -char* debug_lb_make_using_struct_ref_identifier(gbAllocator allocator, String struct_name, String field_name) { - isize name_len = 2 + struct_name.len + 1 + field_name.len + 1; - char* debug_name = gb_alloc_array(allocator, char, name_len); - gb_snprintf(debug_name, name_len, "%.*s::%.*s" - , LIT(struct_name) - , LIT(field_name) - ); - return debug_name; -} - gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) { Ast *prev_stmt = p->curr_stmt; defer (p->curr_stmt = prev_stmt);