From 528908a06e9663a5e6595fc5ff80e017c663dc76 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 6 Nov 2019 22:49:24 +0100 Subject: Fix ptrCast of array references to fn Closes #3607 --- src/codegen.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 154c21893a..7d3ae656fb 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7050,16 +7050,12 @@ check: switch (const_val->special) { case ZigTypeIdEnum: return bigint_to_llvm_const(get_llvm_type(g, type_entry), &const_val->data.x_enum_tag); case ZigTypeIdFn: - if (const_val->data.x_ptr.special == ConstPtrSpecialFunction) { - assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst); - return fn_llvm_value(g, const_val->data.x_ptr.data.fn.fn_entry); - } else if (const_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { - LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; - uint64_t addr = const_val->data.x_ptr.data.hard_coded_addr.addr; - return LLVMConstIntToPtr(LLVMConstInt(usize_type_ref, addr, false), get_llvm_type(g, type_entry)); - } else { + if (const_val->data.x_ptr.special == ConstPtrSpecialFunction && + const_val->data.x_ptr.mut != ConstPtrMutComptimeConst) { zig_unreachable(); } + // Treat it the same as we do for pointers + return gen_const_val_ptr(g, const_val, name); case ZigTypeIdPointer: return gen_const_val_ptr(g, const_val, name); case ZigTypeIdErrorUnion: -- cgit v1.2.3 From 2e52fafac50b545b5ef7dce42d0827e8077a8698 Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Wed, 6 Nov 2019 20:00:39 -0800 Subject: correctly use llvm undef in release modes --- src/codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 7d3ae656fb..89c41b61cc 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5128,7 +5128,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns bool val_is_undef = value_is_all_undef(g, &instruction->byte->value); LLVMValueRef fill_char; - if (val_is_undef) { + if (val_is_undef && ir_want_runtime_safety_scope(g, instruction->base.scope)) { fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false); } else { fill_char = ir_llvm_value(g, instruction->byte); -- cgit v1.2.3 From 2a6fbbd8fba30b8d24aa966606372f595c102d55 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 6 Nov 2019 23:21:31 -0500 Subject: introduce `@as` builtin for type coercion This commit also hooks up type coercion (previously called implicit casting) into the result location mechanism, and additionally hooks up variable declarations, maintaining the property that: var a: T = b; is semantically equivalent to: var a = @as(T, b); See #1757 --- src/all_types.hpp | 25 ++++--- src/codegen.cpp | 1 + src/ir.cpp | 190 ++++++++++++++++++++++++++++++++++++++++-------------- src/ir_print.cpp | 23 ++++--- 4 files changed, 175 insertions(+), 64 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index 42f14539f3..8ba2bfc503 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -48,6 +48,7 @@ struct ResultLoc; struct ResultLocPeer; struct ResultLocPeerParent; struct ResultLocBitCast; +struct ResultLocCast; struct ResultLocReturn; enum PtrLen { @@ -1691,6 +1692,7 @@ enum BuiltinFnId { BuiltinFnIdFrameType, BuiltinFnIdFrameHandle, BuiltinFnIdFrameSize, + BuiltinFnIdAs, }; struct BuiltinFnEntry { @@ -3458,6 +3460,13 @@ struct IrInstructionPtrCastGen { bool safety_check_on; }; +struct IrInstructionImplicitCast { + IrInstruction base; + + IrInstruction *operand; + ResultLocCast *result_loc_cast; +}; + struct IrInstructionBitCastSrc { IrInstruction base; @@ -3823,14 +3832,6 @@ struct IrInstructionEndExpr { ResultLoc *result_loc; }; -struct IrInstructionImplicitCast { - IrInstruction base; - - IrInstruction *dest_type; - IrInstruction *target; - ResultLoc *result_loc; -}; - // This one is for writing through the result pointer. struct IrInstructionResolveResult { IrInstruction base; @@ -3928,6 +3929,7 @@ enum ResultLocId { ResultLocIdPeerParent, ResultLocIdInstruction, ResultLocIdBitCast, + ResultLocIdCast, }; // Additions to this struct may need to be handled in @@ -3995,6 +3997,13 @@ struct ResultLocBitCast { ResultLoc *parent; }; +// The source_instruction is the destination type +struct ResultLocCast { + ResultLoc base; + + ResultLoc *parent; +}; + static const size_t slice_ptr_index = 0; static const size_t slice_len_index = 1; diff --git a/src/codegen.cpp b/src/codegen.cpp index 89c41b61cc..4861def16c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8070,6 +8070,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdFrameType, "Frame", 1); create_builtin_fn(g, BuiltinFnIdFrameAddress, "frameAddress", 0); create_builtin_fn(g, BuiltinFnIdFrameSize, "frameSize", 1); + create_builtin_fn(g, BuiltinFnIdAs, "as", 2); } static const char *bool_to_str(bool b) { diff --git a/src/ir.cpp b/src/ir.cpp index dae759ed84..ae5987d030 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -200,6 +200,8 @@ static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNo static void ir_reset_result(ResultLoc *result_loc); static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, Scope *scope, AstNode *source_node, Buf *out_bare_name); +static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type, + ResultLoc *parent_result_loc); static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { assert(get_src_ptr_type(const_val->type) != nullptr); @@ -2766,6 +2768,18 @@ static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *sourc return &instruction->base; } +static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *operand, ResultLocCast *result_loc_cast) +{ + IrInstructionImplicitCast *instruction = ir_build_instruction(irb, scope, source_node); + instruction->operand = operand; + instruction->result_loc_cast = result_loc_cast; + + ir_ref_instruction(operand, irb->current_basic_block); + + return &instruction->base; +} + static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast) { @@ -3063,20 +3077,6 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } -static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc) -{ - IrInstructionImplicitCast *instruction = ir_build_instruction(irb, scope, source_node); - instruction->dest_type = dest_type; - instruction->target = target; - instruction->result_loc = result_loc; - - ir_ref_instruction(dest_type, irb->current_basic_block); - ir_ref_instruction(target, irb->current_basic_block); - - return &instruction->base; -} - static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node, ResultLoc *result_loc, IrInstruction *ty) { @@ -5374,6 +5374,24 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); } + case BuiltinFnIdAs: + { + AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); + IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope); + if (dest_type == irb->codegen->invalid_instruction) + return dest_type; + + ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc); + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, + &result_loc_cast->base); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + IrInstruction *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast); + return ir_lval_wrap(irb, scope, result, lval, result_loc); + } case BuiltinFnIdIntToPtr: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); @@ -6214,6 +6232,20 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo return result_loc_var; } +static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type, + ResultLoc *parent_result_loc) +{ + ResultLocCast *result_loc_cast = allocate(1); + result_loc_cast->base.id = ResultLocIdCast; + result_loc_cast->base.source_instruction = dest_type; + ir_ref_instruction(dest_type, irb->current_basic_block); + result_loc_cast->parent = parent_result_loc; + + ir_build_reset_result(irb, dest_type->scope, dest_type->source_node, &result_loc_cast->base); + + return result_loc_cast; +} + static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, IrInstruction *init, const char *name_hint, IrInstruction *is_comptime) { @@ -6282,7 +6314,15 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod // Create a result location for the initialization expression. ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); - ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr; + ResultLoc *init_result_loc; + ResultLocCast *result_loc_cast; + if (type_instruction != nullptr) { + result_loc_cast = ir_build_cast_result_loc(irb, type_instruction, &result_loc_var->base); + init_result_loc = &result_loc_cast->base; + } else { + result_loc_cast = nullptr; + init_result_loc = &result_loc_var->base; + } Scope *init_scope = is_comptime_scalar ? create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; @@ -6298,9 +6338,8 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod if (init_value == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; - if (type_instruction != nullptr) { - IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value, - &result_loc_var->base); + if (result_loc_cast != nullptr) { + IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, init_value, result_loc_cast); ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); } @@ -15435,6 +15474,7 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspe case ResultLocIdNone: case ResultLocIdVar: case ResultLocIdBitCast: + case ResultLocIdCast: return nullptr; case ResultLocIdInstruction: return result_loc->source_instruction->child->value.type; @@ -15489,6 +15529,7 @@ static bool ir_result_has_type(ResultLoc *result_loc) { case ResultLocIdReturn: case ResultLocIdInstruction: case ResultLocIdBitCast: + case ResultLocIdCast: return true; case ResultLocIdVar: return reinterpret_cast(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; @@ -15668,6 +15709,61 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe result_loc->resolved_loc = parent_result_loc; return result_loc->resolved_loc; } + case ResultLocIdCast: { + ResultLocCast *result_cast = reinterpret_cast(result_loc); + ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); + if (type_is_invalid(dest_type)) + return ira->codegen->invalid_instruction; + + ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type, + result_cast->base.source_instruction->source_node, false); + if (const_cast_result.id == ConstCastResultIdInvalid) + return ira->codegen->invalid_instruction; + if (const_cast_result.id != ConstCastResultIdOk) { + // We will not be able to provide a result location for this value. Allow the + // code to create a new result location and then type coerce to the old one. + return nullptr; + } + + // In this case we can pointer cast the result location. + IrInstruction *casted_value; + if (value != nullptr) { + casted_value = ir_implicit_cast(ira, value, dest_type); + } else { + casted_value = nullptr; + } + + if (casted_value == nullptr || type_is_invalid(casted_value->value.type)) { + return casted_value; + } + + IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, + dest_type, casted_value, force_runtime, non_null_comptime, true); + if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) || + parent_result_loc->value.type->id == ZigTypeIdUnreachable) + { + return parent_result_loc; + } + ZigType *parent_ptr_type = parent_result_loc->value.type; + assert(parent_ptr_type->id == ZigTypeIdPointer); + if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, + ResolveStatusAlignmentKnown))) + { + return ira->codegen->invalid_instruction; + } + uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); + if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { + return ira->codegen->invalid_instruction; + } + ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, + parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, + parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); + + result_loc->written = true; + result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, + ptr_type, result_cast->base.source_instruction, false); + return result_loc->resolved_loc; + } case ResultLocIdBitCast: { ResultLocBitCast *result_bit_cast = reinterpret_cast(result_loc); ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); @@ -15790,18 +15886,6 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s return result_loc; } -static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) { - ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); - if (type_is_invalid(dest_type)) - return ira->codegen->invalid_instruction; - - IrInstruction *target = instruction->target->child; - if (type_is_invalid(target->value.type)) - return ira->codegen->invalid_instruction; - - return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc); -} - static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) { ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); if (type_is_invalid(implicit_elem_type)) @@ -15864,6 +15948,7 @@ static void ir_reset_result(ResultLoc *result_loc) { case ResultLocIdNone: case ResultLocIdInstruction: case ResultLocIdBitCast: + case ResultLocIdCast: break; } } @@ -16903,25 +16988,14 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC if (is_comptime || instr_is_comptime(fn_ref)) { if (fn_ref->value.type->id == ZigTypeIdMetaType) { - ZigType *dest_type = ir_resolve_type(ira, fn_ref); - if (type_is_invalid(dest_type)) + ZigType *ty = ir_resolve_type(ira, fn_ref); + if (ty == nullptr) return ira->codegen->invalid_instruction; - - size_t actual_param_count = call_instruction->arg_count; - - if (actual_param_count != 1) { - ir_add_error_node(ira, call_instruction->base.source_node, - buf_sprintf("cast expression expects exactly one parameter")); - return ira->codegen->invalid_instruction; - } - - IrInstruction *arg = call_instruction->args[0]->child; - - IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg, - call_instruction->result_loc); - if (type_is_invalid(cast_instruction->value.type)) - return ira->codegen->invalid_instruction; - return ir_finish_anal(ira, cast_instruction); + ErrorMsg *msg = ir_add_error_node(ira, fn_ref->source_node, + buf_sprintf("type '%s' not a function", buf_ptr(&ty->name))); + add_error_note(ira->codegen, msg, call_instruction->base.source_node, + buf_sprintf("use @as builtin for type coercion")); + return ira->codegen->invalid_instruction; } else if (fn_ref->value.type->id == ZigTypeIdFn) { ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value.type; @@ -25958,6 +26032,26 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct return ir_const_void(ira, &instruction->base); } +static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) { + IrInstruction *operand = instruction->operand->child; + if (type_is_invalid(operand->value.type)) + return operand; + + IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, + &instruction->result_loc_cast->base, operand->value.type, operand, false, false, true); + if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc))) + return result_loc; + + if (instruction->result_loc_cast->parent->gen_instruction != nullptr) { + return instruction->result_loc_cast->parent->gen_instruction; + } + + ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); + if (type_is_invalid(dest_type)) + return ira->codegen->invalid_instruction; + return ir_implicit_cast(ira, operand, dest_type); +} + static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) { IrInstruction *operand = instruction->operand->child; if (type_is_invalid(operand->value.type)) diff --git a/src/ir_print.cpp b/src/ir_print.cpp index aa53b11e03..85b58faefc 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -601,6 +601,12 @@ static void ir_print_result_loc_bit_cast(IrPrint *irp, ResultLocBitCast *result_ fprintf(irp->f, ")"); } +static void ir_print_result_loc_cast(IrPrint *irp, ResultLocCast *result_loc_cast) { + fprintf(irp->f, "cast(ty="); + ir_print_other_instruction(irp, result_loc_cast->base.source_instruction); + fprintf(irp->f, ")"); +} + static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) { switch (result_loc->id) { case ResultLocIdInvalid: @@ -619,6 +625,8 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) { return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc); case ResultLocIdBitCast: return ir_print_result_loc_bit_cast(irp, (ResultLocBitCast *)result_loc); + case ResultLocIdCast: + return ir_print_result_loc_cast(irp, (ResultLocCast *)result_loc); case ResultLocIdPeerParent: fprintf(irp->f, "peer_parent"); return; @@ -1484,6 +1492,13 @@ static void ir_print_ptr_cast_gen(IrPrint *irp, IrInstructionPtrCastGen *instruc fprintf(irp->f, ")"); } +static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *instruction) { + fprintf(irp->f, "@implicitCast("); + ir_print_other_instruction(irp, instruction->operand); + fprintf(irp->f, ")result="); + ir_print_result_loc(irp, &instruction->result_loc_cast->base); +} + static void ir_print_bit_cast_src(IrPrint *irp, IrInstructionBitCastSrc *instruction) { fprintf(irp->f, "@bitCast("); ir_print_other_instruction(irp, instruction->operand); @@ -1739,14 +1754,6 @@ static void ir_print_align_cast(IrPrint *irp, IrInstructionAlignCast *instructio fprintf(irp->f, ")"); } -static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *instruction) { - fprintf(irp->f, "@implicitCast("); - ir_print_other_instruction(irp, instruction->dest_type); - fprintf(irp->f, ","); - ir_print_other_instruction(irp, instruction->target); - fprintf(irp->f, ")"); -} - static void ir_print_resolve_result(IrPrint *irp, IrInstructionResolveResult *instruction) { fprintf(irp->f, "ResolveResult("); ir_print_result_loc(irp, instruction->result_loc); -- cgit v1.2.3 From bf8870a60bb35062b2b25867a0f9a95f6f5397ce Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 11 Nov 2019 22:09:53 -0500 Subject: fix unresolved type making it to codegen found this trying to build oxid --- src/codegen.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 4861def16c..a2fc0c0687 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1699,6 +1699,10 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) { } static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { + Error err; + if ((err = type_resolve(g, instruction->value.type, ResolveStatusZeroBitsKnown))) { + codegen_report_errors_and_exit(g); + } if (!type_has_bits(instruction->value.type)) return nullptr; if (!instruction->llvm_value) { -- cgit v1.2.3 From 110ef2e52825656fc048cba020f0fc36a1e58d13 Mon Sep 17 00:00:00 2001 From: Vexu <15308111+Vexu@users.noreply.github.com> Date: Wed, 13 Nov 2019 00:25:44 +0200 Subject: add @atomicStore builtin --- doc/langref.html.in | 25 ++++++++-- src/all_types.hpp | 12 +++++ src/codegen.cpp | 14 ++++++ src/ir.cpp | 103 +++++++++++++++++++++++++++++++++++++++ src/ir_print.cpp | 26 ++++++++++ test/stage1/behavior/atomics.zig | 8 +++ 6 files changed, 185 insertions(+), 3 deletions(-) (limited to 'src/codegen.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index b0003a714b..f5fbb4e3a3 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -6612,14 +6612,14 @@ async fn func(y: *i32) void { This builtin function atomically dereferences a pointer and returns the value.

- {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}, - or an integer whose bit count meets these requirements: + {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#} + an integer whose bit count meets these requirements:

  • At least 8
  • At most the same as usize
  • Power of 2
  • -
+ or an enum with a valid integer tag type.

TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe we can remove this restriction @@ -6660,6 +6660,25 @@ async fn func(y: *i32) void {

  • {#syntax#}.Min{#endsyntax#} - stores the operand if it is smaller. Supports integers and floats.
  • {#header_close#} + {#header_open|@atomicStore#} +
    {#syntax#}@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: builtin.AtomicOrder) void{#endsyntax#}
    +

    + This builtin function atomically stores a value. +

    +

    + {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#} + an integer whose bit count meets these requirements: +

    +
      +
    • At least 8
    • +
    • At most the same as usize
    • +
    • Power of 2
    • +
    or an enum with a valid integer tag type. +

    + TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe + we can remove this restriction +

    + {#header_close#} {#header_open|@bitCast#}
    {#syntax#}@bitCast(comptime DestType: type, value: var) DestType{#endsyntax#}

    diff --git a/src/all_types.hpp b/src/all_types.hpp index e38e857209..1acd855b96 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1700,6 +1700,7 @@ enum BuiltinFnId { BuiltinFnIdErrorReturnTrace, BuiltinFnIdAtomicRmw, BuiltinFnIdAtomicLoad, + BuiltinFnIdAtomicStore, BuiltinFnIdHasDecl, BuiltinFnIdUnionInit, BuiltinFnIdFrameAddress, @@ -2569,6 +2570,7 @@ enum IrInstructionId { IrInstructionIdErrorUnion, IrInstructionIdAtomicRmw, IrInstructionIdAtomicLoad, + IrInstructionIdAtomicStore, IrInstructionIdSaveErrRetAddr, IrInstructionIdAddImplicitReturnType, IrInstructionIdErrSetCast, @@ -3713,6 +3715,16 @@ struct IrInstructionAtomicLoad { AtomicOrder resolved_ordering; }; +struct IrInstructionAtomicStore { + IrInstruction base; + + IrInstruction *operand_type; + IrInstruction *ptr; + IrInstruction *value; + IrInstruction *ordering; + AtomicOrder resolved_ordering; +}; + struct IrInstructionSaveErrRetAddr { IrInstruction base; }; diff --git a/src/codegen.cpp b/src/codegen.cpp index a2fc0c0687..3ed269e621 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5650,6 +5650,17 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutable *executable, return load_inst; } +static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutable *executable, + IrInstructionAtomicStore *instruction) +{ + LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering); + LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); + LLVMValueRef value = ir_llvm_value(g, instruction->value); + LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value.type); + LLVMSetOrdering(store_inst, ordering); + return nullptr; +} + static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutable *executable, IrInstructionFloatOp *instruction) { LLVMValueRef op = ir_llvm_value(g, instruction->op1); assert(instruction->base.value.type->id == ZigTypeIdFloat); @@ -6253,6 +6264,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, return ir_render_atomic_rmw(g, executable, (IrInstructionAtomicRmw *)instruction); case IrInstructionIdAtomicLoad: return ir_render_atomic_load(g, executable, (IrInstructionAtomicLoad *)instruction); + case IrInstructionIdAtomicStore: + return ir_render_atomic_store(g, executable, (IrInstructionAtomicStore *)instruction); case IrInstructionIdSaveErrRetAddr: return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction); case IrInstructionIdFloatOp: @@ -8064,6 +8077,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0); create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5); create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3); + create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4); create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2); create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); diff --git a/src/ir.cpp b/src/ir.cpp index 4727c32d5d..f5f1ea3e80 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1009,6 +1009,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) { return IrInstructionIdAtomicLoad; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicStore *) { + return IrInstructionIdAtomicStore; +} + static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) { return IrInstructionIdSaveErrRetAddr; } @@ -3186,6 +3190,25 @@ static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode return &instruction->base; } +static IrInstruction *ir_build_atomic_store(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *value, + IrInstruction *ordering, AtomicOrder resolved_ordering) +{ + IrInstructionAtomicStore *instruction = ir_build_instruction(irb, scope, source_node); + instruction->operand_type = operand_type; + instruction->ptr = ptr; + instruction->value = value; + instruction->ordering = ordering; + instruction->resolved_ordering = resolved_ordering; + + if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); + ir_ref_instruction(ptr, irb->current_basic_block); + ir_ref_instruction(value, irb->current_basic_block); + if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); + + return &instruction->base; +} + static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) { IrInstructionSaveErrRetAddr *instruction = ir_build_instruction(irb, scope, source_node); return &instruction->base; @@ -5730,6 +5753,33 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo AtomicOrderMonotonic); return ir_lval_wrap(irb, scope, inst, lval, result_loc); } + case BuiltinFnIdAtomicStore: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + AstNode *arg2_node = node->data.fn_call_expr.params.at(2); + IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_instruction) + return arg2_value; + + AstNode *arg3_node = node->data.fn_call_expr.params.at(3); + IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); + if (arg3_value == irb->codegen->invalid_instruction) + return arg3_value; + + IrInstruction *inst = ir_build_atomic_store(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, + // this value does not mean anything since we passed non-null values for other arg + AtomicOrderMonotonic); + return ir_lval_wrap(irb, scope, inst, lval, result_loc); + } case BuiltinFnIdIntToEnum: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); @@ -25748,6 +25798,56 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr return result; } +static IrInstruction *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstructionAtomicStore *instruction) { + ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); + if (type_is_invalid(operand_type)) + return ira->codegen->invalid_instruction; + + IrInstruction *ptr_inst = instruction->ptr->child; + if (type_is_invalid(ptr_inst->value.type)) + return ira->codegen->invalid_instruction; + + ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); + IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); + if (type_is_invalid(casted_ptr->value.type)) + return ira->codegen->invalid_instruction; + + IrInstruction *value = instruction->value->child; + if (type_is_invalid(value->value.type)) + return ira->codegen->invalid_instruction; + + IrInstruction *casted_value = ir_implicit_cast(ira, value, operand_type); + if (type_is_invalid(casted_value->value.type)) + return ira->codegen->invalid_instruction; + + + AtomicOrder ordering; + if (instruction->ordering == nullptr) { + ordering = instruction->resolved_ordering; + } else { + if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) + return ira->codegen->invalid_instruction; + } + + if (ordering == AtomicOrderAcquire || ordering == AtomicOrderAcqRel) { + ir_assert(instruction->ordering != nullptr, &instruction->base); + ir_add_error(ira, instruction->ordering, + buf_sprintf("@atomicStore atomic ordering must not be Acquire or AcqRel")); + return ira->codegen->invalid_instruction; + } + + if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) { + IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr, nullptr); + ir_assert(result->value.type != nullptr, &instruction->base); + return result; + } + + IrInstruction *result = ir_build_atomic_store(&ira->new_irb, instruction->base.scope, + instruction->base.source_node, nullptr, casted_ptr, casted_value, nullptr, ordering); + result->value.type = ira->codegen->builtin_types.entry_void; + return result; +} + static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) { IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope, instruction->base.source_node); @@ -26782,6 +26882,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction); case IrInstructionIdAtomicLoad: return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction); + case IrInstructionIdAtomicStore: + return ir_analyze_instruction_atomic_store(ira, (IrInstructionAtomicStore *)instruction); case IrInstructionIdSaveErrRetAddr: return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction); case IrInstructionIdAddImplicitReturnType: @@ -26962,6 +27064,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdSaveErrRetAddr: case IrInstructionIdAddImplicitReturnType: case IrInstructionIdAtomicRmw: + case IrInstructionIdAtomicStore: case IrInstructionIdCmpxchgGen: case IrInstructionIdCmpxchgSrc: case IrInstructionIdAssertZero: diff --git a/src/ir_print.cpp b/src/ir_print.cpp index da7ae38e5f..03224d8037 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -324,6 +324,8 @@ const char* ir_instruction_type_str(IrInstructionId id) { return "AtomicRmw"; case IrInstructionIdAtomicLoad: return "AtomicLoad"; + case IrInstructionIdAtomicStore: + return "AtomicStore"; case IrInstructionIdSaveErrRetAddr: return "SaveErrRetAddr"; case IrInstructionIdAddImplicitReturnType: @@ -1871,6 +1873,27 @@ static void ir_print_atomic_load(IrPrint *irp, IrInstructionAtomicLoad *instruct fprintf(irp->f, ")"); } +static void ir_print_atomic_store(IrPrint *irp, IrInstructionAtomicStore *instruction) { + fprintf(irp->f, "@atomicStore("); + if (instruction->operand_type != nullptr) { + ir_print_other_instruction(irp, instruction->operand_type); + } else { + fprintf(irp->f, "[TODO print]"); + } + fprintf(irp->f, ","); + ir_print_other_instruction(irp, instruction->ptr); + fprintf(irp->f, ","); + ir_print_other_instruction(irp, instruction->value); + fprintf(irp->f, ","); + if (instruction->ordering != nullptr) { + ir_print_other_instruction(irp, instruction->ordering); + } else { + fprintf(irp->f, "[TODO print]"); + } + fprintf(irp->f, ")"); +} + + static void ir_print_save_err_ret_addr(IrPrint *irp, IrInstructionSaveErrRetAddr *instruction) { fprintf(irp->f, "@saveErrRetAddr()"); } @@ -2431,6 +2454,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool case IrInstructionIdAtomicLoad: ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction); break; + case IrInstructionIdAtomicStore: + ir_print_atomic_store(irp, (IrInstructionAtomicStore *)instruction); + break; case IrInstructionIdEnumToInt: ir_print_enum_to_int(irp, (IrInstructionEnumToInt *)instruction); break; diff --git a/test/stage1/behavior/atomics.zig b/test/stage1/behavior/atomics.zig index c6344b17ca..9e41863fd1 100644 --- a/test/stage1/behavior/atomics.zig +++ b/test/stage1/behavior/atomics.zig @@ -123,3 +123,11 @@ test "atomic load and rmw with enum" { expect(@atomicLoad(Value, &x, .SeqCst) != .a); expect(@atomicLoad(Value, &x, .SeqCst) != .b); } + +test "atomic store" { + var x: u32 = 0; + @atomicStore(u32, &x, 1, .SeqCst); + expect(@atomicLoad(u32, &x, .SeqCst) == 1); + @atomicStore(u32, &x, 12345678, .SeqCst); + expect(@atomicLoad(u32, &x, .SeqCst) == 12345678); +} \ No newline at end of file -- cgit v1.2.3 From 37318bf15138d0a7b158b32ca43cbcdcf5382942 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 12 Nov 2019 17:59:24 -0500 Subject: fn parameters participate in result location semantics See #3665 --- doc/langref.html.in | 2 +- lib/std/event/loop.zig | 23 ------- src/all_types.hpp | 1 + src/codegen.cpp | 5 ++ src/ir.cpp | 155 ++++++++++++++++++++++++++++++++++++-------- test/compile_errors.zig | 8 +-- test/stage1/behavior/fn.zig | 16 +++++ 7 files changed, 154 insertions(+), 56 deletions(-) (limited to 'src/codegen.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index b0003a714b..bca12c62d7 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -5404,7 +5404,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {

    For example, if we were to introduce another function to the above snippet:

    - {#code_begin|test_err|cannot store runtime value in type 'type'#} + {#code_begin|test_err|values of type 'type' must be comptime known#} fn max(comptime T: type, a: T, b: T) T { return if (a > b) a else b; } diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig index 543863c71e..588cd3c8b5 100644 --- a/lib/std/event/loop.zig +++ b/lib/std/event/loop.zig @@ -645,12 +645,6 @@ pub const Loop = struct { } } - /// This is equivalent to function call, except it calls `startCpuBoundOperation` first. - pub fn call(comptime func: var, args: ...) @typeOf(func).ReturnType { - startCpuBoundOperation(); - return func(args); - } - /// Yielding lets the event loop run, starting any unstarted async operations. /// Note that async operations automatically start when a function yields for any other reason, /// for example, when async I/O is performed. This function is intended to be used only when @@ -942,23 +936,6 @@ test "std.event.Loop - basic" { loop.run(); } -test "std.event.Loop - call" { - // https://github.com/ziglang/zig/issues/1908 - if (builtin.single_threaded) return error.SkipZigTest; - - var loop: Loop = undefined; - try loop.initMultiThreaded(); - defer loop.deinit(); - - var did_it = false; - var handle = async Loop.call(testEventLoop); - var handle2 = async Loop.call(testEventLoop2, &handle, &did_it); - - loop.run(); - - testing.expect(did_it); -} - async fn testEventLoop() i32 { return 1234; } diff --git a/src/all_types.hpp b/src/all_types.hpp index e38e857209..1464dfba59 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -3665,6 +3665,7 @@ struct IrInstructionArgType { IrInstruction *fn_type; IrInstruction *arg_index; + bool allow_var; }; struct IrInstructionExport { diff --git a/src/codegen.cpp b/src/codegen.cpp index a2fc0c0687..558a7011f0 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7820,6 +7820,11 @@ static void define_builtin_types(CodeGen *g) { buf_init_from_str(&entry->name, "(null)"); g->builtin_types.entry_null = entry; } + { + ZigType *entry = new_type_table_entry(ZigTypeIdOpaque); + buf_init_from_str(&entry->name, "(var)"); + g->builtin_types.entry_var = entry; + } { ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple); buf_init_from_str(&entry->name, "(args)"); diff --git a/src/ir.cpp b/src/ir.cpp index 4727c32d5d..3b7ef42f04 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -206,6 +206,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing); static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); +static ResultLoc *no_result_loc(void); static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { assert(get_src_ptr_type(const_val->type) != nullptr); @@ -3115,11 +3116,12 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast } static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *fn_type, IrInstruction *arg_index) + IrInstruction *fn_type, IrInstruction *arg_index, bool allow_var) { IrInstructionArgType *instruction = ir_build_instruction(irb, scope, source_node); instruction->fn_type = fn_type; instruction->arg_index = arg_index; + instruction->allow_var = allow_var; ir_ref_instruction(fn_type, irb->current_basic_block); ir_ref_instruction(arg_index, irb->current_basic_block); @@ -5647,7 +5649,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo if (arg1_value == irb->codegen->invalid_instruction) return arg1_value; - IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); + IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false); return ir_lval_wrap(irb, scope, arg_type, lval, result_loc); } case BuiltinFnIdExport: @@ -5842,13 +5844,22 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node if (fn_ref == irb->codegen->invalid_instruction) return fn_ref; + IrInstruction *fn_type = ir_build_typeof(irb, scope, node, fn_ref); + size_t arg_count = node->data.fn_call_expr.params.length; IrInstruction **args = allocate(arg_count); for (size_t i = 0; i < arg_count; i += 1) { AstNode *arg_node = node->data.fn_call_expr.params.at(i); - args[i] = ir_gen_node(irb, arg_node, scope); - if (args[i] == irb->codegen->invalid_instruction) - return args[i]; + + IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i); + IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true); + ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result_loc()); + + IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); + if (arg == irb->codegen->invalid_instruction) + return arg; + + args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); } IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false, @@ -12504,6 +12515,27 @@ static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *sou return result; } +static IrInstruction *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *value, ZigType *wanted_type) +{ + ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array")); + return ira->codegen->invalid_instruction; +} + +static IrInstruction *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *value, ZigType *wanted_type) +{ + ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct")); + return ira->codegen->invalid_instruction; +} + +static IrInstruction *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *value, ZigType *wanted_type) +{ + ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union")); + return ira->codegen->invalid_instruction; +} + static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc) { @@ -12515,6 +12547,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ira->codegen->invalid_instruction; } + // This means the wanted type is anything. + if (wanted_type == ira->codegen->builtin_types.entry_var) { + return value; + } + // perfect match or non-const to const ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, source_node, false); @@ -13071,6 +13108,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); } + // cast from inferred struct type to array, union, or struct + if (actual_type->id == ZigTypeIdStruct && actual_type->data.structure.is_inferred) { + AstNode *decl_node = actual_type->data.structure.decl_node; + ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr); + ContainerInitKind init_kind = decl_node->data.container_init_expr.kind; + uint32_t field_count = actual_type->data.structure.src_field_count; + if (wanted_type->id == ZigTypeIdArray && (init_kind == ContainerInitKindArray || field_count == 0) && + wanted_type->data.array.len == field_count) + { + return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type); + } else if (wanted_type->id == ZigTypeIdStruct && + (init_kind == ContainerInitKindStruct || field_count == 0)) + { + return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type); + } else if (wanted_type->id == ZigTypeIdUnion && init_kind == ContainerInitKindStruct && field_count == 1) { + return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type); + } + } + // cast from undefined to anything if (actual_type->id == ZigTypeIdUndefined) { return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); @@ -15537,21 +15593,31 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) { ptr->value.data.x_ptr.data.ref.pointee = undef_child; } -static bool ir_result_has_type(ResultLoc *result_loc) { +static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) { switch (result_loc->id) { case ResultLocIdInvalid: case ResultLocIdPeerParent: zig_unreachable(); case ResultLocIdNone: case ResultLocIdPeer: - return false; + *out = false; + return ErrorNone; case ResultLocIdReturn: case ResultLocIdInstruction: case ResultLocIdBitCast: - case ResultLocIdCast: - return true; + *out = true; + return ErrorNone; + case ResultLocIdCast: { + ResultLocCast *result_cast = reinterpret_cast(result_loc); + ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); + if (type_is_invalid(dest_type)) + return ErrorSemanticAnalyzeFail; + *out = (dest_type != ira->codegen->builtin_types.entry_var); + return ErrorNone; + } case ResultLocIdVar: - return reinterpret_cast(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; + *out = reinterpret_cast(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; + return ErrorNone; } zig_unreachable(); } @@ -15698,7 +15764,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe } return nullptr; } - if (ir_result_has_type(peer_parent->parent)) { + bool peer_parent_has_type; + if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) + return ira->codegen->invalid_instruction; + if (peer_parent_has_type) { if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) { reinterpret_cast(peer_parent->parent)->implicit_return_type_done = true; ira->src_implicit_return_type_list.append(value); @@ -15741,6 +15810,11 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe if (type_is_invalid(dest_type)) return ira->codegen->invalid_instruction; + if (dest_type == ira->codegen->builtin_types.entry_var) { + return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type, + force_runtime, non_null_comptime); + } + ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type, result_cast->base.source_instruction->source_node, false); if (const_cast_result.id == ConstCastResultIdInvalid) @@ -15948,6 +16022,9 @@ static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, if (type_is_invalid(implicit_elem_type)) return ira->codegen->invalid_instruction; } else { + implicit_elem_type = ira->codegen->builtin_types.entry_var; + } + if (implicit_elem_type == ira->codegen->builtin_types.entry_var) { Buf *bare_name = buf_alloc(); Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), instruction->base.scope, instruction->base.source_node, bare_name); @@ -17532,6 +17609,8 @@ static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira, } static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { + Error err; + if (ira->const_predecessor_bb) { for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; @@ -17663,24 +17742,32 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh } ZigType *resolved_type; - if (peer_parent != nullptr && ir_result_has_type(peer_parent->parent)) { - if (peer_parent->parent->id == ResultLocIdReturn) { - resolved_type = ira->explicit_return_type; - } else if (peer_parent->parent->id == ResultLocIdCast) { - resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); - if (type_is_invalid(resolved_type)) - return ira->codegen->invalid_instruction; - } else { - ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type; - ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); - resolved_type = resolved_loc_ptr_type->data.pointer.child_type; + if (peer_parent != nullptr) { + bool peer_parent_has_type; + if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) + return ira->codegen->invalid_instruction; + if (peer_parent_has_type) { + if (peer_parent->parent->id == ResultLocIdReturn) { + resolved_type = ira->explicit_return_type; + } else if (peer_parent->parent->id == ResultLocIdCast) { + resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); + if (type_is_invalid(resolved_type)) + return ira->codegen->invalid_instruction; + } else { + ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type; + ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base); + resolved_type = resolved_loc_ptr_type->data.pointer.child_type; + } + goto skip_resolve_peer_types; } - } else { + } + { resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, new_incoming_values.items, new_incoming_values.length); if (type_is_invalid(resolved_type)) return ira->codegen->invalid_instruction; } +skip_resolve_peer_types: switch (type_has_one_possible_value(ira->codegen, resolved_type)) { case OnePossibleValueInvalid: @@ -18379,7 +18466,7 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n inferred_struct_field->inferred_struct_type = container_type; inferred_struct_field->field_name = field_name; - ZigType *elem_type = ira->codegen->builtin_types.entry_c_void; + ZigType *elem_type = ira->codegen->builtin_types.entry_var; ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field); @@ -25547,6 +25634,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) return ira->codegen->invalid_instruction; + if (fn_type->id == ZigTypeIdBoundFn) { + fn_type = fn_type->data.bound_fn.fn_type; + arg_index += 1; + } if (fn_type->id != ZigTypeIdFn) { ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); return ira->codegen->invalid_instruction; @@ -25554,6 +25645,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; if (arg_index >= fn_type_id->param_count) { + if (instruction->allow_var) { + // TODO remove this with var args + return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); + } ir_add_error(ira, arg_index_inst, buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); @@ -25565,10 +25660,14 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct // Args are only unresolved if our function is generic. ir_assert(fn_type->data.fn.is_generic, &instruction->base); - ir_add_error(ira, arg_index_inst, - buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", - arg_index, buf_ptr(&fn_type->name))); - return ira->codegen->invalid_instruction; + if (instruction->allow_var) { + return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var); + } else { + ir_add_error(ira, arg_index_inst, + buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", + arg_index, buf_ptr(&fn_type->name))); + return ira->codegen->invalid_instruction; + } } return ir_const_type(ira, &instruction->base, result_type); } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 1adf3c3f8e..47333b7db4 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2113,8 +2113,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ \\fn bar(x: *b.Foo) void {} , - "tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'", - "tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'", + "tmp.zig:6:9: error: expected type '*b.Foo', found '*a.Foo'", + "tmp.zig:6:9: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'", "a.zig:1:17: note: a.Foo declared here", "b.zig:1:17: note: b.Foo declared here", ); @@ -4978,7 +4978,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ \\export fn entry() usize { return @sizeOf(@typeOf(foo)); } , - "tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'", + "tmp.zig:8:16: error: expected type '*const u3', found '*align(:3:1) const u3'", ); cases.add( @@ -5675,7 +5675,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ x.* += 1; \\} , - "tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'", + "tmp.zig:8:9: error: expected type '*u32', found '*align(1) u32'", ); cases.add( diff --git a/test/stage1/behavior/fn.zig b/test/stage1/behavior/fn.zig index 1fc586f39f..99d145f1b1 100644 --- a/test/stage1/behavior/fn.zig +++ b/test/stage1/behavior/fn.zig @@ -247,3 +247,19 @@ test "discard the result of a function that returns a struct" { S.entry(); comptime S.entry(); } + +test "function call with anon list literal" { + const S = struct { + fn doTheTest() void { + consumeVec(.{9, 8, 7}); + } + + fn consumeVec(vec: [3]f32) void { + expect(vec[0] == 9); + expect(vec[1] == 8); + expect(vec[2] == 7); + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} -- cgit v1.2.3 From 32b37e695aa0581b863a395e0a28b7b4aa76c07d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 12 Nov 2019 21:34:06 -0500 Subject: fix anonymous struct literal assigned to variable closes #3667 --- src/analyze.cpp | 23 ++++++++++++++++++++++- src/analyze.hpp | 2 ++ src/codegen.cpp | 7 ++++++- src/ir.cpp | 17 +++++++++-------- test/stage1/behavior/struct.zig | 11 ++++++++++- 5 files changed, 49 insertions(+), 11 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/analyze.cpp b/src/analyze.cpp index 4c63c566e9..1232cebe8b 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -5432,7 +5432,7 @@ bool fn_eval_eql(Scope *a, Scope *b) { return false; } -// Whether the type has bits at runtime. +// Deprecated. Use type_has_bits2. bool type_has_bits(ZigType *type_entry) { assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); @@ -5440,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) { return type_entry->abi_size != 0; } +// Whether the type has bits at runtime. +Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result) { + Error err; + + if (type_is_invalid(type_entry)) + return ErrorSemanticAnalyzeFail; + + if (type_entry->id == ZigTypeIdStruct && + type_entry->data.structure.resolve_status == ResolveStatusBeingInferred) + { + *result = true; + return ErrorNone; + } + + if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown))) + return err; + + *result = type_entry->abi_size != 0; + return ErrorNone; +} + // Whether you can infer the value based solely on the type. OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { assert(type_entry != nullptr); diff --git a/src/analyze.hpp b/src/analyze.hpp index 06c8847eda..884f525717 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type); bool handle_is_ptr(ZigType *type_entry); bool type_has_bits(ZigType *type_entry); +Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result); + Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result); bool ptr_allows_addr_zero(ZigType *ptr_type); bool type_is_nonnull_ptr(ZigType *type); diff --git a/src/codegen.cpp b/src/codegen.cpp index 558a7011f0..387c6120c2 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3622,9 +3622,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_ } static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) { + Error err; + ZigType *ptr_type = instruction->ptr->value.type; assert(ptr_type->id == ZigTypeIdPointer); - if (!type_has_bits(ptr_type)) + bool ptr_type_has_bits; + if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits))) + codegen_report_errors_and_exit(g); + if (!ptr_type_has_bits) return nullptr; if (instruction->ptr->ref_count == 0) { // In this case, this StorePtr instruction should be elided. Something happened like this: diff --git a/src/ir.cpp b/src/ir.cpp index 3b7ef42f04..676f69dea7 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15513,15 +15513,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; result->base.value.data.x_ptr.data.ref.pointee = pointee; - if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown))) + bool var_type_has_bits; + if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits))) return ira->codegen->invalid_instruction; if (align != 0) { if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown))) return ira->codegen->invalid_instruction; - if (!type_has_bits(var_type)) { - ir_add_error(ira, source_inst, - buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned", - name_hint, buf_ptr(&var_type->name))); + if (!var_type_has_bits) { + ir_add_error(ira, source_inst, + buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned", + name_hint, buf_ptr(&var_type->name))); return ira->codegen->invalid_instruction; } } @@ -22138,15 +22139,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct } for (size_t i = 0; i < errors_len; i += 1) { Stage2ErrorMsg *clang_err = &errors_ptr[i]; - // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null - if (clang_err->source && clang_err->filename_ptr) { + // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null + if (clang_err->source && clang_err->filename_ptr) { ErrorMsg *err_msg = err_msg_create_with_offset( clang_err->filename_ptr ? buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), clang_err->line, clang_err->column, clang_err->offset, clang_err->source, buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); err_msg_add_note(parent_err_msg, err_msg); - } + } } return ira->codegen->invalid_instruction; diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig index a42c261e3b..722f44d352 100644 --- a/test/stage1/behavior/struct.zig +++ b/test/stage1/behavior/struct.zig @@ -755,7 +755,7 @@ test "fully anonymous struct" { test "fully anonymous list literal" { const S = struct { fn doTheTest() void { - dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"}); + dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" }); } fn dump(args: var) void { expect(args.@"0" == 1234); @@ -768,3 +768,12 @@ test "fully anonymous list literal" { S.doTheTest(); comptime S.doTheTest(); } + +test "anonymous struct literal assigned to variable" { + var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) }; + expect(vec.@"0" == 22); + expect(vec.@"1" == 55); + expect(vec.@"2" == 99); + vec.@"1" += 1; + expect(vec.@"1" == 56); +} -- cgit v1.2.3 From f2f698a888afdc8709142912f8394376d28e16ea Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 13 Nov 2019 20:26:09 -0500 Subject: rework comptime struct value layout, removing 1/2 hacks in the implementation of anonymous struct literals --- src/all_types.hpp | 2 +- src/analyze.cpp | 41 +++-- src/analyze.hpp | 2 + src/codegen.cpp | 16 +- src/ir.cpp | 482 +++++++++++++++++++++++++++--------------------------- 5 files changed, 277 insertions(+), 266 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index 25815ef64a..e246016006 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -152,7 +152,7 @@ struct ConstParent { }; struct ConstStructValue { - ConstExprValue *fields; + ConstExprValue **fields; }; struct ConstUnionValue { diff --git a/src/analyze.cpp b/src/analyze.cpp index 1232cebe8b..ee95e5d246 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1461,8 +1461,8 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf ** if (type_is_invalid(result_val->type)) return false; - ConstExprValue *ptr_field = &result_val->data.x_struct.fields[slice_ptr_index]; - ConstExprValue *len_field = &result_val->data.x_struct.fields[slice_len_index]; + ConstExprValue *ptr_field = result_val->data.x_struct.fields[slice_ptr_index]; + ConstExprValue *len_field = result_val->data.x_struct.fields[slice_len_index]; assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; @@ -5283,7 +5283,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) { zig_unreachable(); case ZigTypeIdStruct: for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) { - if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i])) + if (can_mutate_comptime_var_state(value->data.x_struct.fields[i])) return true; } return false; @@ -5798,11 +5798,11 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr const_val->special = ConstValSpecialStatic; const_val->type = get_slice_type(g, ptr_type); - const_val->data.x_struct.fields = create_const_vals(2); + const_val->data.x_struct.fields = alloc_const_vals_ptrs(2); - init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const, + init_const_ptr_array(g, const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const, PtrLenUnknown); - init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len); + init_const_usize(g, const_val->data.x_struct.fields[slice_len_index], len); } ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) { @@ -5886,6 +5886,23 @@ ConstExprValue *create_const_vals(size_t count) { return vals; } +ConstExprValue **alloc_const_vals_ptrs(size_t count) { + return realloc_const_vals_ptrs(nullptr, 0, count); +} + +ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count) { + assert(new_count >= old_count); + + size_t new_item_count = new_count - old_count; + ConstExprValue **result = reallocate(ptr, old_count, new_count, "ConstExprValue*"); + ConstExprValue *vals = create_const_vals(new_item_count); + for (size_t i = old_count; i < new_count; i += 1) { + result[i] = &vals[i - old_count]; + } + return result; +} + + static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) { if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) return orig_fn_type; @@ -6567,8 +6584,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) { } case ZigTypeIdStruct: for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) { - ConstExprValue *field_a = &a->data.x_struct.fields[i]; - ConstExprValue *field_b = &b->data.x_struct.fields[i]; + ConstExprValue *field_a = a->data.x_struct.fields[i]; + ConstExprValue *field_b = b->data.x_struct.fields[i]; if (!const_values_equal(g, field_a, field_b)) return false; } @@ -6876,10 +6893,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { case ZigTypeIdStruct: { if (is_slice(type_entry)) { - ConstExprValue *len_val = &const_val->data.x_struct.fields[slice_len_index]; + ConstExprValue *len_val = const_val->data.x_struct.fields[slice_len_index]; size_t len = bigint_as_usize(&len_val->data.x_bigint); - ConstExprValue *ptr_val = &const_val->data.x_struct.fields[slice_ptr_index]; + ConstExprValue *ptr_val = const_val->data.x_struct.fields[slice_ptr_index]; if (ptr_val->special == ConstValSpecialUndef) { assert(len == 0); buf_appendf(buf, "((%s)(undefined))[0..0]", buf_ptr(&type_entry->name)); @@ -7156,9 +7173,9 @@ static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { const_val->special = ConstValSpecialStatic; size_t field_count = wanted_type->data.structure.src_field_count; - const_val->data.x_struct.fields = create_const_vals(field_count); + const_val->data.x_struct.fields = alloc_const_vals_ptrs(field_count); for (size_t i = 0; i < field_count; i += 1) { - ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; + ConstExprValue *field_val = const_val->data.x_struct.fields[i]; field_val->type = resolve_struct_field_type(g, &wanted_type->data.structure.fields[i]); assert(field_val->type); init_const_undefined(g, field_val); diff --git a/src/analyze.hpp b/src/analyze.hpp index 884f525717..0cca75891a 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -177,6 +177,8 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end); ConstExprValue *create_const_vals(size_t count); +ConstExprValue **alloc_const_vals_ptrs(size_t count); +ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count); ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); void expand_undef_array(CodeGen *g, ConstExprValue *const_val); diff --git a/src/codegen.cpp b/src/codegen.cpp index a0666a3522..ed9b69e529 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3508,7 +3508,7 @@ static bool value_is_all_undef(CodeGen *g, ConstExprValue *const_val) { case ConstValSpecialStatic: if (const_val->type->id == ZigTypeIdStruct) { for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) { - if (!value_is_all_undef(g, &const_val->data.x_struct.fields[i])) + if (!value_is_all_undef(g, const_val->data.x_struct.fields[i])) return false; } return true; @@ -6572,7 +6572,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con if (field->gen_index == SIZE_MAX) { continue; } - LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, &const_val->data.x_struct.fields[i]); + LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, const_val->data.x_struct.fields[i]); uint32_t packed_bits_size = type_size_bits(g, field->type_entry); if (is_big_endian) { LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, packed_bits_size, false); @@ -6840,7 +6840,7 @@ check: switch (const_val->special) { } if (src_field_index + 1 == src_field_index_end) { - ConstExprValue *field_val = &const_val->data.x_struct.fields[src_field_index]; + ConstExprValue *field_val = const_val->data.x_struct.fields[src_field_index]; LLVMValueRef val = gen_const_val(g, field_val, ""); fields[type_struct_field->gen_index] = val; make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val); @@ -6858,7 +6858,7 @@ check: switch (const_val->special) { continue; } LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, - &const_val->data.x_struct.fields[i]); + const_val->data.x_struct.fields[i]); uint32_t packed_bits_size = type_size_bits(g, it_field->type_entry); if (is_big_endian) { LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, @@ -6897,7 +6897,7 @@ check: switch (const_val->special) { if (type_struct_field->gen_index == SIZE_MAX) { continue; } - ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; + ConstExprValue *field_val = const_val->data.x_struct.fields[i]; assert(field_val->type != nullptr); if ((err = ensure_const_val_repr(nullptr, g, nullptr, field_val, type_struct_field->type_entry))) @@ -9074,13 +9074,13 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { this_val->parent.id = ConstParentIdArray; this_val->parent.data.p_array.array_val = test_fn_array; this_val->parent.data.p_array.elem_index = i; - this_val->data.x_struct.fields = create_const_vals(2); + this_val->data.x_struct.fields = alloc_const_vals_ptrs(2); - ConstExprValue *name_field = &this_val->data.x_struct.fields[0]; + ConstExprValue *name_field = this_val->data.x_struct.fields[0]; ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name); init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true); - ConstExprValue *fn_field = &this_val->data.x_struct.fields[1]; + ConstExprValue *fn_field = this_val->data.x_struct.fields[1]; fn_field->type = fn_type; fn_field->special = ConstValSpecialStatic; fn_field->data.x_ptr.special = ConstPtrSpecialFunction; diff --git a/src/ir.cpp b/src/ir.cpp index e5afc882d4..d52daacc42 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -240,7 +240,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c case ConstPtrSpecialBaseStruct: { ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; expand_undef_struct(g, struct_val); - result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; + result = struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; break; } case ConstPtrSpecialBaseErrorUnionCode: @@ -10784,9 +10784,9 @@ static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_ if (src->special != ConstValSpecialStatic) return; if (dest->type->id == ZigTypeIdStruct) { - dest->data.x_struct.fields = create_const_vals(dest->type->data.structure.src_field_count); + dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count); for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) { - copy_const_val(&dest->data.x_struct.fields[i], &src->data.x_struct.fields[i], false); + copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i], false); } } } @@ -10982,8 +10982,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc IrInstruction *result = ir_const(ira, source_instr, wanted_type); init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const); - result->value.data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = - value->value.data.x_ptr.mut; + result->value.data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = value->value.data.x_ptr.mut; result->value.type = wanted_type; return result; } @@ -13491,8 +13490,8 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { if (!const_val) return nullptr; - ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index]; - ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index]; + ConstExprValue *ptr_field = const_val->data.x_struct.fields[slice_ptr_index]; + ConstExprValue *len_field = const_val->data.x_struct.fields[slice_len_index]; assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; @@ -14820,11 +14819,11 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i } else if (is_slice(op1_type)) { ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry; child_type = ptr_type->data.pointer.child_type; - ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index]; + ConstExprValue *ptr_val = op1_val->data.x_struct.fields[slice_ptr_index]; assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; - ConstExprValue *len_val = &op1_val->data.x_struct.fields[slice_len_index]; + ConstExprValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); } else { ir_add_error(ira, op1, @@ -14853,11 +14852,11 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i } else if (is_slice(op2_type)) { ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry; op2_type_valid = ptr_type->data.pointer.child_type == child_type; - ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index]; + ConstExprValue *ptr_val = op2_val->data.x_struct.fields[slice_ptr_index]; assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; - ConstExprValue *len_val = &op2_val->data.x_struct.fields[slice_len_index]; + ConstExprValue *len_val = op2_val->data.x_struct.fields[slice_len_index]; op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint); } else { ir_add_error(ira, op2, @@ -14889,17 +14888,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i out_array_val->special = ConstValSpecialStatic; out_array_val->type = get_array_type(ira->codegen, child_type, new_len); - out_val->data.x_struct.fields = create_const_vals(2); + out_val->data.x_struct.fields = alloc_const_vals_ptrs(2); - out_val->data.x_struct.fields[slice_ptr_index].type = ptr_type; - out_val->data.x_struct.fields[slice_ptr_index].special = ConstValSpecialStatic; - out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.special = ConstPtrSpecialBaseArray; - out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.array_val = out_array_val; - out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.elem_index = 0; + out_val->data.x_struct.fields[slice_ptr_index]->type = ptr_type; + out_val->data.x_struct.fields[slice_ptr_index]->special = ConstValSpecialStatic; + out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.special = ConstPtrSpecialBaseArray; + out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.array_val = out_array_val; + out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.elem_index = 0; - out_val->data.x_struct.fields[slice_len_index].type = ira->codegen->builtin_types.entry_usize; - out_val->data.x_struct.fields[slice_len_index].special = ConstValSpecialStatic; - bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index].data.x_bigint, new_len); + out_val->data.x_struct.fields[slice_len_index]->type = ira->codegen->builtin_types.entry_usize; + out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; + bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); } else { new_len += 1; // null byte @@ -16496,17 +16495,10 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); struct_val->special = ConstValSpecialStatic; - if (new_field_count > 16) { - // This thing with 16 is a hack to allow this functionality to work without - // modifying the ConstExprValue layout of structs. That reworking needs to be - // done, but this hack lets us do it separately, in the future. - zig_panic("TODO need to rework the layout of ConstExprValue for structs. This realloc would have caused invalid pointer references"); - } - if (struct_val->data.x_struct.fields == nullptr) { - struct_val->data.x_struct.fields = create_const_vals(16); - } + struct_val->data.x_struct.fields = realloc_const_vals_ptrs(struct_val->data.x_struct.fields, + old_field_count, new_field_count); - ConstExprValue *field_val = &struct_val->data.x_struct.fields[old_field_count]; + ConstExprValue *field_val = struct_val->data.x_struct.fields[old_field_count]; field_val->special = ConstValSpecialUndef; field_val->type = field->type_entry; field_val->parent.id = ConstParentIdStruct; @@ -18156,7 +18148,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, false); - array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer; + array_ptr_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutInfer; } else { ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, buf_sprintf("expected array type or [_], found '%s'", @@ -18228,7 +18220,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct } return result; } else if (is_slice(array_type)) { - ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; + ConstExprValue *ptr_field = array_ptr_val->data.x_struct.fields[slice_ptr_index]; ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base); if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, @@ -18237,7 +18229,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct result->value.type = return_type; return result; } - ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; + ConstExprValue *len_field = array_ptr_val->data.x_struct.fields[slice_len_index]; IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); ConstExprValue *out_val = &result->value; uint64_t slice_len = bigint_as_u64(&len_field->data.x_bigint); @@ -18466,10 +18458,10 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction if (type_is_invalid(struct_val->type)) return ira->codegen->invalid_instruction; if (initializing && struct_val->special == ConstValSpecialUndef) { - struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count); + struct_val->data.x_struct.fields = alloc_const_vals_ptrs(struct_type->data.structure.src_field_count); struct_val->special = ConstValSpecialStatic; for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { - ConstExprValue *field_val = &struct_val->data.x_struct.fields[i]; + ConstExprValue *field_val = struct_val->data.x_struct.fields[i]; field_val->special = ConstValSpecialUndef; field_val->type = resolve_struct_field_type(ira->codegen, &struct_type->data.structure.fields[i]); @@ -21005,17 +20997,17 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr declaration_val->special = ConstValSpecialStatic; declaration_val->type = type_info_declaration_type; - ConstExprValue *inner_fields = create_const_vals(3); + ConstExprValue **inner_fields = alloc_const_vals_ptrs(3); ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); - init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true); - inner_fields[1].special = ConstValSpecialStatic; - inner_fields[1].type = ira->codegen->builtin_types.entry_bool; - inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub; - inner_fields[2].special = ConstValSpecialStatic; - inner_fields[2].type = type_info_declaration_data_type; - inner_fields[2].parent.id = ConstParentIdStruct; - inner_fields[2].parent.data.p_struct.struct_val = declaration_val; - inner_fields[2].parent.data.p_struct.field_index = 1; + init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true); + inner_fields[1]->special = ConstValSpecialStatic; + inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; + inner_fields[1]->data.x_bool = curr_entry->value->visib_mod == VisibModPub; + inner_fields[2]->special = ConstValSpecialStatic; + inner_fields[2]->type = type_info_declaration_data_type; + inner_fields[2]->parent.id = ConstParentIdStruct; + inner_fields[2]->parent.data.p_struct.struct_val = declaration_val; + inner_fields[2]->parent.data.p_struct.field_index = 1; switch (curr_entry->value->id) { case TldIdVar: @@ -21027,19 +21019,19 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr if (var->const_value->type->id == ZigTypeIdMetaType) { // We have a variable of type 'type', so it's actually a type declaration. // 0: Data.Type: type - bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); - inner_fields[2].data.x_union.payload = var->const_value; + bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); + inner_fields[2]->data.x_union.payload = var->const_value; } else { // We have a variable of another type, so we store the type of the variable. // 1: Data.Var: type - bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1); + bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 1); ConstExprValue *payload = create_const_vals(1); payload->special = ConstValSpecialStatic; payload->type = ira->codegen->builtin_types.entry_type; payload->data.x_type = var->const_value->type; - inner_fields[2].data.x_union.payload = payload; + inner_fields[2]->data.x_union.payload = payload; } break; @@ -21047,7 +21039,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr case TldIdFn: { // 2: Data.Fn: Data.FnDecl - bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); + bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 2); ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; assert(!fn_entry->is_test); @@ -21063,63 +21055,63 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr fn_decl_val->special = ConstValSpecialStatic; fn_decl_val->type = type_info_fn_decl_type; fn_decl_val->parent.id = ConstParentIdUnion; - fn_decl_val->parent.data.p_union.union_val = &inner_fields[2]; + fn_decl_val->parent.data.p_union.union_val = inner_fields[2]; - ConstExprValue *fn_decl_fields = create_const_vals(9); + ConstExprValue **fn_decl_fields = alloc_const_vals_ptrs(9); fn_decl_val->data.x_struct.fields = fn_decl_fields; // fn_type: type ensure_field_index(fn_decl_val->type, "fn_type", 0); - fn_decl_fields[0].special = ConstValSpecialStatic; - fn_decl_fields[0].type = ira->codegen->builtin_types.entry_type; - fn_decl_fields[0].data.x_type = fn_entry->type_entry; + fn_decl_fields[0]->special = ConstValSpecialStatic; + fn_decl_fields[0]->type = ira->codegen->builtin_types.entry_type; + fn_decl_fields[0]->data.x_type = fn_entry->type_entry; // inline_type: Data.FnDecl.Inline ensure_field_index(fn_decl_val->type, "inline_type", 1); - fn_decl_fields[1].special = ConstValSpecialStatic; - fn_decl_fields[1].type = type_info_fn_decl_inline_type; - bigint_init_unsigned(&fn_decl_fields[1].data.x_enum_tag, fn_entry->fn_inline); + fn_decl_fields[1]->special = ConstValSpecialStatic; + fn_decl_fields[1]->type = type_info_fn_decl_inline_type; + bigint_init_unsigned(&fn_decl_fields[1]->data.x_enum_tag, fn_entry->fn_inline); // calling_convention: TypeInfo.CallingConvention ensure_field_index(fn_decl_val->type, "calling_convention", 2); - fn_decl_fields[2].special = ConstValSpecialStatic; - fn_decl_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); - bigint_init_unsigned(&fn_decl_fields[2].data.x_enum_tag, fn_node->cc); + fn_decl_fields[2]->special = ConstValSpecialStatic; + fn_decl_fields[2]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr); + bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_node->cc); // is_var_args: bool ensure_field_index(fn_decl_val->type, "is_var_args", 3); bool is_varargs = fn_node->is_var_args; - fn_decl_fields[3].special = ConstValSpecialStatic; - fn_decl_fields[3].type = ira->codegen->builtin_types.entry_bool; - fn_decl_fields[3].data.x_bool = is_varargs; + fn_decl_fields[3]->special = ConstValSpecialStatic; + fn_decl_fields[3]->type = ira->codegen->builtin_types.entry_bool; + fn_decl_fields[3]->data.x_bool = is_varargs; // is_extern: bool ensure_field_index(fn_decl_val->type, "is_extern", 4); - fn_decl_fields[4].special = ConstValSpecialStatic; - fn_decl_fields[4].type = ira->codegen->builtin_types.entry_bool; - fn_decl_fields[4].data.x_bool = fn_node->is_extern; + fn_decl_fields[4]->special = ConstValSpecialStatic; + fn_decl_fields[4]->type = ira->codegen->builtin_types.entry_bool; + fn_decl_fields[4]->data.x_bool = fn_node->is_extern; // is_export: bool ensure_field_index(fn_decl_val->type, "is_export", 5); - fn_decl_fields[5].special = ConstValSpecialStatic; - fn_decl_fields[5].type = ira->codegen->builtin_types.entry_bool; - fn_decl_fields[5].data.x_bool = fn_node->is_export; + fn_decl_fields[5]->special = ConstValSpecialStatic; + fn_decl_fields[5]->type = ira->codegen->builtin_types.entry_bool; + fn_decl_fields[5]->data.x_bool = fn_node->is_export; // lib_name: ?[]const u8 ensure_field_index(fn_decl_val->type, "lib_name", 6); - fn_decl_fields[6].special = ConstValSpecialStatic; + fn_decl_fields[6]->special = ConstValSpecialStatic; ZigType *u8_ptr = get_pointer_to_type_extra( ira->codegen, ira->codegen->builtin_types.entry_u8, true, false, PtrLenUnknown, 0, 0, 0, false); - fn_decl_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); + fn_decl_fields[6]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) { - fn_decl_fields[6].data.x_optional = create_const_vals(1); + fn_decl_fields[6]->data.x_optional = create_const_vals(1); ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); - init_const_slice(ira->codegen, fn_decl_fields[6].data.x_optional, lib_name, 0, + init_const_slice(ira->codegen, fn_decl_fields[6]->data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true); } else { - fn_decl_fields[6].data.x_optional = nullptr; + fn_decl_fields[6]->data.x_optional = nullptr; } // return_type: type ensure_field_index(fn_decl_val->type, "return_type", 7); - fn_decl_fields[7].special = ConstValSpecialStatic; - fn_decl_fields[7].type = ira->codegen->builtin_types.entry_type; - fn_decl_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; + fn_decl_fields[7]->special = ConstValSpecialStatic; + fn_decl_fields[7]->type = ira->codegen->builtin_types.entry_type; + fn_decl_fields[7]->data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; // arg_names: [][] const u8 ensure_field_index(fn_decl_val->type, "arg_names", 8); size_t fn_arg_count = fn_entry->variable_list.length; @@ -21130,7 +21122,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); - init_const_slice(ira->codegen, &fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false); + init_const_slice(ira->codegen, fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false); for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); @@ -21143,7 +21135,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index; } - inner_fields[2].data.x_union.payload = fn_decl_val; + inner_fields[2]->data.x_union.payload = fn_decl_val; break; } case TldIdContainer: @@ -21153,14 +21145,14 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr return ErrorSemanticAnalyzeFail; // This is a type. - bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); + bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); ConstExprValue *payload = create_const_vals(1); payload->special = ConstValSpecialStatic; payload->type = ira->codegen->builtin_types.entry_type; payload->data.x_type = type_entry; - inner_fields[2].data.x_union.payload = payload; + inner_fields[2]->data.x_union.payload = payload; break; } @@ -21169,7 +21161,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr } declaration_val->data.x_struct.fields = inner_fields; - declaration_index++; + declaration_index += 1; } assert(declaration_index == declaration_count); @@ -21225,42 +21217,42 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty result->special = ConstValSpecialStatic; result->type = type_info_pointer_type; - ConstExprValue *fields = create_const_vals(6); + ConstExprValue **fields = alloc_const_vals_ptrs(6); result->data.x_struct.fields = fields; // size: Size ensure_field_index(result->type, "size", 0); ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown)); - fields[0].special = ConstValSpecialStatic; - fields[0].type = type_info_pointer_size_type; - bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index); + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = type_info_pointer_size_type; + bigint_init_unsigned(&fields[0]->data.x_enum_tag, size_enum_index); // is_const: bool ensure_field_index(result->type, "is_const", 1); - fields[1].special = ConstValSpecialStatic; - fields[1].type = ira->codegen->builtin_types.entry_bool; - fields[1].data.x_bool = attrs_type->data.pointer.is_const; + fields[1]->special = ConstValSpecialStatic; + fields[1]->type = ira->codegen->builtin_types.entry_bool; + fields[1]->data.x_bool = attrs_type->data.pointer.is_const; // is_volatile: bool ensure_field_index(result->type, "is_volatile", 2); - fields[2].special = ConstValSpecialStatic; - fields[2].type = ira->codegen->builtin_types.entry_bool; - fields[2].data.x_bool = attrs_type->data.pointer.is_volatile; + fields[2]->special = ConstValSpecialStatic; + fields[2]->type = ira->codegen->builtin_types.entry_bool; + fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile; // alignment: u32 ensure_field_index(result->type, "alignment", 3); - fields[3].special = ConstValSpecialStatic; - fields[3].type = ira->codegen->builtin_types.entry_num_lit_int; - bigint_init_unsigned(&fields[3].data.x_bigint, get_ptr_align(ira->codegen, attrs_type)); + fields[3]->special = ConstValSpecialStatic; + fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int; + bigint_init_unsigned(&fields[3]->data.x_bigint, get_ptr_align(ira->codegen, attrs_type)); // child: type ensure_field_index(result->type, "child", 4); - fields[4].special = ConstValSpecialStatic; - fields[4].type = ira->codegen->builtin_types.entry_type; - fields[4].data.x_type = attrs_type->data.pointer.child_type; + fields[4]->special = ConstValSpecialStatic; + fields[4]->type = ira->codegen->builtin_types.entry_type; + fields[4]->data.x_type = attrs_type->data.pointer.child_type; // is_allowzero: bool ensure_field_index(result->type, "is_allowzero", 5); - fields[5].special = ConstValSpecialStatic; - fields[5].type = ira->codegen->builtin_types.entry_bool; - fields[5].data.x_bool = attrs_type->data.pointer.allow_zero; + fields[5]->special = ConstValSpecialStatic; + fields[5]->type = ira->codegen->builtin_types.entry_bool; + fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero; return result; }; @@ -21271,14 +21263,14 @@ static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val, enum_field_val->special = ConstValSpecialStatic; enum_field_val->type = type_info_enum_field_type; - ConstExprValue *inner_fields = create_const_vals(2); - inner_fields[1].special = ConstValSpecialStatic; - inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int; + ConstExprValue **inner_fields = alloc_const_vals_ptrs(2); + inner_fields[1]->special = ConstValSpecialStatic; + inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); - init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true); + init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(enum_field->name), true); - bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value); + bigint_init_bigint(&inner_fields[1]->data.x_bigint, &enum_field->value); enum_field_val->data.x_struct.fields = inner_fields; } @@ -21322,19 +21314,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Int", nullptr); - ConstExprValue *fields = create_const_vals(2); + ConstExprValue **fields = alloc_const_vals_ptrs(2); result->data.x_struct.fields = fields; // is_signed: bool ensure_field_index(result->type, "is_signed", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ira->codegen->builtin_types.entry_bool; - fields[0].data.x_bool = type_entry->data.integral.is_signed; + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ira->codegen->builtin_types.entry_bool; + fields[0]->data.x_bool = type_entry->data.integral.is_signed; // bits: u8 ensure_field_index(result->type, "bits", 1); - fields[1].special = ConstValSpecialStatic; - fields[1].type = ira->codegen->builtin_types.entry_num_lit_int; - bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); + fields[1]->special = ConstValSpecialStatic; + fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; + bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.integral.bit_count); break; } @@ -21344,14 +21336,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Float", nullptr); - ConstExprValue *fields = create_const_vals(1); + ConstExprValue **fields = alloc_const_vals_ptrs(1); result->data.x_struct.fields = fields; // bits: u8 ensure_field_index(result->type, "bits", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ira->codegen->builtin_types.entry_num_lit_int; - bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; + bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.floating.bit_count); break; } @@ -21368,19 +21360,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Array", nullptr); - ConstExprValue *fields = create_const_vals(2); + ConstExprValue **fields = alloc_const_vals_ptrs(2); result->data.x_struct.fields = fields; // len: usize ensure_field_index(result->type, "len", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ira->codegen->builtin_types.entry_num_lit_int; - bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; + bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.array.len); // child: type ensure_field_index(result->type, "child", 1); - fields[1].special = ConstValSpecialStatic; - fields[1].type = ira->codegen->builtin_types.entry_type; - fields[1].data.x_type = type_entry->data.array.child_type; + fields[1]->special = ConstValSpecialStatic; + fields[1]->type = ira->codegen->builtin_types.entry_type; + fields[1]->data.x_type = type_entry->data.array.child_type; break; } @@ -21389,19 +21381,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Vector", nullptr); - ConstExprValue *fields = create_const_vals(2); + ConstExprValue **fields = alloc_const_vals_ptrs(2); result->data.x_struct.fields = fields; // len: usize ensure_field_index(result->type, "len", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ira->codegen->builtin_types.entry_num_lit_int; - bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.vector.len); + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; + bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.vector.len); // child: type ensure_field_index(result->type, "child", 1); - fields[1].special = ConstValSpecialStatic; - fields[1].type = ira->codegen->builtin_types.entry_type; - fields[1].data.x_type = type_entry->data.vector.elem_type; + fields[1]->special = ConstValSpecialStatic; + fields[1]->type = ira->codegen->builtin_types.entry_type; + fields[1]->data.x_type = type_entry->data.vector.elem_type; break; } @@ -21411,14 +21403,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Optional", nullptr); - ConstExprValue *fields = create_const_vals(1); + ConstExprValue **fields = alloc_const_vals_ptrs(1); result->data.x_struct.fields = fields; // child: type ensure_field_index(result->type, "child", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ira->codegen->builtin_types.entry_type; - fields[0].data.x_type = type_entry->data.maybe.child_type; + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ira->codegen->builtin_types.entry_type; + fields[0]->data.x_type = type_entry->data.maybe.child_type; break; } @@ -21427,14 +21419,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr); - ConstExprValue *fields = create_const_vals(1); + ConstExprValue **fields = alloc_const_vals_ptrs(1); result->data.x_struct.fields = fields; // child: ?type ensure_field_index(result->type, "child", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); - fields[0].data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr : + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + fields[0]->data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr : create_const_type(ira->codegen, type_entry->data.any_frame.result_type); break; } @@ -21444,19 +21436,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Enum", nullptr); - ConstExprValue *fields = create_const_vals(4); + ConstExprValue **fields = alloc_const_vals_ptrs(4); result->data.x_struct.fields = fields; // layout: ContainerLayout ensure_field_index(result->type, "layout", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); - bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout); + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); + bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.enumeration.layout); // tag_type: type ensure_field_index(result->type, "tag_type", 1); - fields[1].special = ConstValSpecialStatic; - fields[1].type = ira->codegen->builtin_types.entry_type; - fields[1].data.x_type = type_entry->data.enumeration.tag_int_type; + fields[1]->special = ConstValSpecialStatic; + fields[1]->type = ira->codegen->builtin_types.entry_type; + fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type; // fields: []TypeInfo.EnumField ensure_field_index(result->type, "fields", 2); @@ -21472,7 +21464,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr enum_field_array->data.x_array.special = ConstArraySpecialNone; enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count); - init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false); + init_const_slice(ira->codegen, fields[2], enum_field_array, 0, enum_field_count, false); for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) { @@ -21485,7 +21477,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr } // decls: []TypeInfo.Declaration ensure_field_index(result->type, "decls", 3); - if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3], + if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], type_entry->data.enumeration.decls_scope))) { return err; @@ -21528,17 +21520,17 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr error_val->special = ConstValSpecialStatic; error_val->type = type_info_error_type; - ConstExprValue *inner_fields = create_const_vals(2); - inner_fields[1].special = ConstValSpecialStatic; - inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int; + ConstExprValue **inner_fields = alloc_const_vals_ptrs(2); + inner_fields[1]->special = ConstValSpecialStatic; + inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; ConstExprValue *name = nullptr; if (error->cached_error_name_val != nullptr) name = error->cached_error_name_val; if (name == nullptr) name = create_const_str_lit(ira->codegen, &error->name); - init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(&error->name), true); - bigint_init_unsigned(&inner_fields[1].data.x_bigint, error->value); + init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true); + bigint_init_unsigned(&inner_fields[1]->data.x_bigint, error->value); error_val->data.x_struct.fields = inner_fields; error_val->parent.id = ConstParentIdArray; @@ -21554,20 +21546,20 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); - ConstExprValue *fields = create_const_vals(2); + ConstExprValue **fields = alloc_const_vals_ptrs(2); result->data.x_struct.fields = fields; // error_set: type ensure_field_index(result->type, "error_set", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ira->codegen->builtin_types.entry_type; - fields[0].data.x_type = type_entry->data.error_union.err_set_type; + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ira->codegen->builtin_types.entry_type; + fields[0]->data.x_type = type_entry->data.error_union.err_set_type; // payload: type ensure_field_index(result->type, "payload", 1); - fields[1].special = ConstValSpecialStatic; - fields[1].type = ira->codegen->builtin_types.entry_type; - fields[1].data.x_type = type_entry->data.error_union.payload_type; + fields[1]->special = ConstValSpecialStatic; + fields[1]->type = ira->codegen->builtin_types.entry_type; + fields[1]->data.x_type = type_entry->data.error_union.payload_type; break; } @@ -21577,18 +21569,18 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Union", nullptr); - ConstExprValue *fields = create_const_vals(4); + ConstExprValue **fields = alloc_const_vals_ptrs(4); result->data.x_struct.fields = fields; // layout: ContainerLayout ensure_field_index(result->type, "layout", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); - bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout); + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); + bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.unionation.layout); // tag_type: ?type ensure_field_index(result->type, "tag_type", 1); - fields[1].special = ConstValSpecialStatic; - fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + fields[1]->special = ConstValSpecialStatic; + fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); AstNode *union_decl_node = type_entry->data.unionation.decl_node; if (union_decl_node->data.container_decl.auto_enum || @@ -21598,9 +21590,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr tag_type->special = ConstValSpecialStatic; tag_type->type = ira->codegen->builtin_types.entry_type; tag_type->data.x_type = type_entry->data.unionation.tag_type; - fields[1].data.x_optional = tag_type; + fields[1]->data.x_optional = tag_type; } else { - fields[1].data.x_optional = nullptr; + fields[1]->data.x_optional = nullptr; } // fields: []TypeInfo.UnionField ensure_field_index(result->type, "fields", 2); @@ -21616,7 +21608,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr union_field_array->data.x_array.special = ConstArraySpecialNone; union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count); - init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); + init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false); ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); @@ -21627,23 +21619,23 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr union_field_val->special = ConstValSpecialStatic; union_field_val->type = type_info_union_field_type; - ConstExprValue *inner_fields = create_const_vals(3); - inner_fields[1].special = ConstValSpecialStatic; - inner_fields[1].type = get_optional_type(ira->codegen, type_info_enum_field_type); + ConstExprValue **inner_fields = alloc_const_vals_ptrs(3); + inner_fields[1]->special = ConstValSpecialStatic; + inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type); - if (fields[1].data.x_optional == nullptr) { - inner_fields[1].data.x_optional = nullptr; + if (fields[1]->data.x_optional == nullptr) { + inner_fields[1]->data.x_optional = nullptr; } else { - inner_fields[1].data.x_optional = create_const_vals(1); - make_enum_field_val(ira, inner_fields[1].data.x_optional, union_field->enum_field, type_info_enum_field_type); + inner_fields[1]->data.x_optional = create_const_vals(1); + make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type); } - inner_fields[2].special = ConstValSpecialStatic; - inner_fields[2].type = ira->codegen->builtin_types.entry_type; - inner_fields[2].data.x_type = union_field->type_entry; + inner_fields[2]->special = ConstValSpecialStatic; + inner_fields[2]->type = ira->codegen->builtin_types.entry_type; + inner_fields[2]->data.x_type = union_field->type_entry; ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name); - init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true); + init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true); union_field_val->data.x_struct.fields = inner_fields; union_field_val->parent.id = ConstParentIdArray; @@ -21652,7 +21644,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr } // decls: []TypeInfo.Declaration ensure_field_index(result->type, "decls", 3); - if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3], + if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], type_entry->data.unionation.decls_scope))) { return err; @@ -21673,14 +21665,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Struct", nullptr); - ConstExprValue *fields = create_const_vals(3); + ConstExprValue **fields = alloc_const_vals_ptrs(3); result->data.x_struct.fields = fields; // layout: ContainerLayout ensure_field_index(result->type, "layout", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); - bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.structure.layout); + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); + bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.structure.layout); // fields: []TypeInfo.StructField ensure_field_index(result->type, "fields", 1); @@ -21696,7 +21688,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr struct_field_array->data.x_array.special = ConstArraySpecialNone; struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count); - init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false); + init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false); for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index]; @@ -21705,9 +21697,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr struct_field_val->special = ConstValSpecialStatic; struct_field_val->type = type_info_struct_field_type; - ConstExprValue *inner_fields = create_const_vals(3); - inner_fields[1].special = ConstValSpecialStatic; - inner_fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int); + ConstExprValue **inner_fields = alloc_const_vals_ptrs(3); + inner_fields[1]->special = ConstValSpecialStatic; + inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int); ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field); if (field_type == nullptr) @@ -21715,21 +21707,21 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) return err; if (!type_has_bits(struct_field->type_entry)) { - inner_fields[1].data.x_optional = nullptr; + inner_fields[1]->data.x_optional = nullptr; } else { size_t byte_offset = struct_field->offset; - inner_fields[1].data.x_optional = create_const_vals(1); - inner_fields[1].data.x_optional->special = ConstValSpecialStatic; - inner_fields[1].data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int; - bigint_init_unsigned(&inner_fields[1].data.x_optional->data.x_bigint, byte_offset); + inner_fields[1]->data.x_optional = create_const_vals(1); + inner_fields[1]->data.x_optional->special = ConstValSpecialStatic; + inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int; + bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset); } - inner_fields[2].special = ConstValSpecialStatic; - inner_fields[2].type = ira->codegen->builtin_types.entry_type; - inner_fields[2].data.x_type = struct_field->type_entry; + inner_fields[2]->special = ConstValSpecialStatic; + inner_fields[2]->type = ira->codegen->builtin_types.entry_type; + inner_fields[2]->data.x_type = struct_field->type_entry; ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name); - init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(struct_field->name), true); + init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true); struct_field_val->data.x_struct.fields = inner_fields; struct_field_val->parent.id = ConstParentIdArray; @@ -21738,7 +21730,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr } // decls: []TypeInfo.Declaration ensure_field_index(result->type, "decls", 2); - if ((err = ir_make_type_info_decls(ira, source_instr, &fields[2], + if ((err = ir_make_type_info_decls(ira, source_instr, fields[2], type_entry->data.structure.decls_scope))) { return err; @@ -21752,38 +21744,38 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Fn", nullptr); - ConstExprValue *fields = create_const_vals(5); + ConstExprValue **fields = alloc_const_vals_ptrs(5); result->data.x_struct.fields = fields; // calling_convention: TypeInfo.CallingConvention ensure_field_index(result->type, "calling_convention", 0); - fields[0].special = ConstValSpecialStatic; - fields[0].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); - bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); + fields[0]->special = ConstValSpecialStatic; + fields[0]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr); + bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); // is_generic: bool ensure_field_index(result->type, "is_generic", 1); bool is_generic = type_entry->data.fn.is_generic; - fields[1].special = ConstValSpecialStatic; - fields[1].type = ira->codegen->builtin_types.entry_bool; - fields[1].data.x_bool = is_generic; + fields[1]->special = ConstValSpecialStatic; + fields[1]->type = ira->codegen->builtin_types.entry_bool; + fields[1]->data.x_bool = is_generic; // is_varargs: bool ensure_field_index(result->type, "is_var_args", 2); bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; - fields[2].special = ConstValSpecialStatic; - fields[2].type = ira->codegen->builtin_types.entry_bool; - fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; + fields[2]->special = ConstValSpecialStatic; + fields[2]->type = ira->codegen->builtin_types.entry_bool; + fields[2]->data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; // return_type: ?type ensure_field_index(result->type, "return_type", 3); - fields[3].special = ConstValSpecialStatic; - fields[3].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + fields[3]->special = ConstValSpecialStatic; + fields[3]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); if (type_entry->data.fn.fn_type_id.return_type == nullptr) - fields[3].data.x_optional = nullptr; + fields[3]->data.x_optional = nullptr; else { ConstExprValue *return_type = create_const_vals(1); return_type->special = ConstValSpecialStatic; return_type->type = ira->codegen->builtin_types.entry_type; return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; - fields[3].data.x_optional = return_type; + fields[3]->data.x_optional = return_type; } // args: []TypeInfo.FnArg ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); @@ -21799,7 +21791,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr fn_arg_array->data.x_array.special = ConstArraySpecialNone; fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); - init_const_slice(ira->codegen, &fields[4], fn_arg_array, 0, fn_arg_count, false); + init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false); for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; @@ -21811,24 +21803,24 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr bool arg_is_generic = fn_param_info->type == nullptr; if (arg_is_generic) assert(is_generic); - ConstExprValue *inner_fields = create_const_vals(3); - inner_fields[0].special = ConstValSpecialStatic; - inner_fields[0].type = ira->codegen->builtin_types.entry_bool; - inner_fields[0].data.x_bool = arg_is_generic; - inner_fields[1].special = ConstValSpecialStatic; - inner_fields[1].type = ira->codegen->builtin_types.entry_bool; - inner_fields[1].data.x_bool = fn_param_info->is_noalias; - inner_fields[2].special = ConstValSpecialStatic; - inner_fields[2].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + ConstExprValue **inner_fields = alloc_const_vals_ptrs(3); + inner_fields[0]->special = ConstValSpecialStatic; + inner_fields[0]->type = ira->codegen->builtin_types.entry_bool; + inner_fields[0]->data.x_bool = arg_is_generic; + inner_fields[1]->special = ConstValSpecialStatic; + inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; + inner_fields[1]->data.x_bool = fn_param_info->is_noalias; + inner_fields[2]->special = ConstValSpecialStatic; + inner_fields[2]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); if (arg_is_generic) - inner_fields[2].data.x_optional = nullptr; + inner_fields[2]->data.x_optional = nullptr; else { ConstExprValue *arg_type = create_const_vals(1); arg_type->special = ConstValSpecialStatic; arg_type->type = ira->codegen->builtin_types.entry_type; arg_type->data.x_type = fn_param_info->type; - inner_fields[2].data.x_optional = arg_type; + inner_fields[2]->data.x_optional = arg_type; } fn_arg_val->data.x_struct.fields = inner_fields; @@ -21889,8 +21881,8 @@ static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira, static ConstExprValue *get_const_field(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index) { ensure_field_index(struct_value->type, name, field_index); - assert(struct_value->data.x_struct.fields[field_index].special == ConstValSpecialStatic); - return &struct_value->data.x_struct.fields[field_index]; + assert(struct_value->data.x_struct.fields[field_index]->special == ConstValSpecialStatic); + return struct_value->data.x_struct.fields[field_index]; } static bool get_const_field_bool(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index) @@ -22698,7 +22690,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru if (!val) return ira->codegen->invalid_instruction; - ConstExprValue *len_val = &val->data.x_struct.fields[slice_len_index]; + ConstExprValue *len_val = val->data.x_struct.fields[slice_len_index]; if (value_is_comptime(len_val)) { known_len = bigint_as_u64(&len_val->data.x_bigint); have_known_len = true; @@ -22765,17 +22757,17 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct return ira->codegen->invalid_instruction; IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type); - result->value.data.x_struct.fields = create_const_vals(2); + result->value.data.x_struct.fields = alloc_const_vals_ptrs(2); - ConstExprValue *ptr_val = &result->value.data.x_struct.fields[slice_ptr_index]; - ConstExprValue *target_ptr_val = &target_val->data.x_struct.fields[slice_ptr_index]; + ConstExprValue *ptr_val = result->value.data.x_struct.fields[slice_ptr_index]; + ConstExprValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index]; copy_const_val(ptr_val, target_ptr_val, false); ptr_val->type = dest_ptr_type; - ConstExprValue *len_val = &result->value.data.x_struct.fields[slice_len_index]; + ConstExprValue *len_val = result->value.data.x_struct.fields[slice_len_index]; len_val->special = ConstValSpecialStatic; len_val->type = ira->codegen->builtin_types.entry_usize; - ConstExprValue *target_len_val = &target_val->data.x_struct.fields[slice_len_index]; + ConstExprValue *target_len_val = target_val->data.x_struct.fields[slice_len_index]; ZigType *elem_type = src_ptr_type->data.pointer.child_type; BigInt elem_size_bigint; bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type)); @@ -23664,13 +23656,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction return ira->codegen->invalid_instruction; } - parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; + parent_ptr = slice_ptr->data.x_struct.fields[slice_ptr_index]; if (parent_ptr->special == ConstValSpecialUndef) { ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); return ira->codegen->invalid_instruction; } - ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index]; + ConstExprValue *len_val = slice_ptr->data.x_struct.fields[slice_len_index]; switch (parent_ptr->data.x_ptr.special) { case ConstPtrSpecialInvalid: @@ -23742,9 +23734,9 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction IrInstruction *result = ir_const(ira, &instruction->base, return_type); ConstExprValue *out_val = &result->value; - out_val->data.x_struct.fields = create_const_vals(2); + out_val->data.x_struct.fields = alloc_const_vals_ptrs(2); - ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; + ConstExprValue *ptr_val = out_val->data.x_struct.fields[slice_ptr_index]; if (array_val) { size_t index = abs_offset + start_scalar; @@ -23791,7 +23783,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction zig_panic("TODO"); } - ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; + ConstExprValue *len_val = out_val->data.x_struct.fields[slice_len_index]; init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); return result; @@ -25141,7 +25133,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue TypeStructField *struct_field = &val->type->data.structure.fields[field_i]; if (struct_field->gen_index == SIZE_MAX) continue; - ConstExprValue *field_val = &val->data.x_struct.fields[field_i]; + ConstExprValue *field_val = val->data.x_struct.fields[field_i]; size_t offset = struct_field->offset; buf_write_value_bytes(codegen, buf + offset, field_val); } @@ -25172,7 +25164,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue if (field->gen_index != gen_i) break; uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); - buf_write_value_bytes(codegen, child_buf, &val->data.x_struct.fields[src_i]); + buf_write_value_bytes(codegen, child_buf, val->data.x_struct.fields[src_i]); BigInt child_val; bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian, false); @@ -25310,9 +25302,9 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou } case ContainerLayoutExtern: { size_t src_field_count = val->type->data.structure.src_field_count; - val->data.x_struct.fields = create_const_vals(src_field_count); + val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count); for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { - ConstExprValue *field_val = &val->data.x_struct.fields[field_i]; + ConstExprValue *field_val = val->data.x_struct.fields[field_i]; field_val->special = ConstValSpecialStatic; TypeStructField *struct_field = &val->type->data.structure.fields[field_i]; field_val->type = struct_field->type_entry; @@ -25327,7 +25319,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou } case ContainerLayoutPacked: { size_t src_field_count = val->type->data.structure.src_field_count; - val->data.x_struct.fields = create_const_vals(src_field_count); + val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count); size_t gen_field_count = val->type->data.structure.gen_field_count; size_t gen_i = 0; size_t src_i = 0; @@ -25349,7 +25341,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou src_assert(field->gen_index != SIZE_MAX, source_node); if (field->gen_index != gen_i) break; - ConstExprValue *field_val = &val->data.x_struct.fields[src_i]; + ConstExprValue *field_val = val->data.x_struct.fields[src_i]; field_val->special = ConstValSpecialStatic; field_val->type = field->type_entry; uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); -- cgit v1.2.3 From d89f39d71949c85b26f2ccd4071c9445aa8b6d7c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 13 Nov 2019 20:43:32 -0500 Subject: rework layout of struct type fields This removes the remaining hack in the implementation of anonymous struct literals, and they can now therefore now have greater than 16 fields/elements. --- src/all_types.hpp | 2 +- src/analyze.cpp | 95 +++++++++++++++++++++++++++++---------------------- src/analyze.hpp | 3 ++ src/codegen.cpp | 88 +++++++++++++++++++++++------------------------ src/dump_analysis.cpp | 6 ++-- src/ir.cpp | 84 +++++++++++++++++++++------------------------ 6 files changed, 144 insertions(+), 134 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index e246016006..a1e9d76be7 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1279,7 +1279,7 @@ struct RootStruct { struct ZigTypeStruct { AstNode *decl_node; - TypeStructField *fields; + TypeStructField **fields; ScopeDecls *decls_scope; HashMap fields_by_name; RootStruct *root_struct; diff --git a/src/analyze.cpp b/src/analyze.cpp index ee95e5d246..0a8b32dca7 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -803,19 +803,19 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) { entry->data.structure.is_slice = true; entry->data.structure.src_field_count = element_count; entry->data.structure.gen_field_count = element_count; - entry->data.structure.fields = allocate(element_count); + entry->data.structure.fields = alloc_type_struct_fields(element_count); entry->data.structure.fields_by_name.init(element_count); - entry->data.structure.fields[slice_ptr_index].name = ptr_field_name; - entry->data.structure.fields[slice_ptr_index].type_entry = ptr_type; - entry->data.structure.fields[slice_ptr_index].src_index = slice_ptr_index; - entry->data.structure.fields[slice_ptr_index].gen_index = 0; - entry->data.structure.fields[slice_len_index].name = len_field_name; - entry->data.structure.fields[slice_len_index].type_entry = g->builtin_types.entry_usize; - entry->data.structure.fields[slice_len_index].src_index = slice_len_index; - entry->data.structure.fields[slice_len_index].gen_index = 1; - - entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]); - entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]); + entry->data.structure.fields[slice_ptr_index]->name = ptr_field_name; + entry->data.structure.fields[slice_ptr_index]->type_entry = ptr_type; + entry->data.structure.fields[slice_ptr_index]->src_index = slice_ptr_index; + entry->data.structure.fields[slice_ptr_index]->gen_index = 0; + entry->data.structure.fields[slice_len_index]->name = len_field_name; + entry->data.structure.fields[slice_len_index]->type_entry = g->builtin_types.entry_usize; + entry->data.structure.fields[slice_len_index]->src_index = slice_len_index; + entry->data.structure.fields[slice_len_index]->gen_index = 1; + + entry->data.structure.fields_by_name.put(ptr_field_name, entry->data.structure.fields[slice_ptr_index]); + entry->data.structure.fields_by_name.put(len_field_name, entry->data.structure.fields[slice_len_index]); switch (type_requires_comptime(g, ptr_type)) { case ReqCompTimeInvalid: @@ -828,8 +828,8 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) { if (!type_has_bits(ptr_type)) { entry->data.structure.gen_field_count = 1; - entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX; - entry->data.structure.fields[slice_len_index].gen_index = 0; + entry->data.structure.fields[slice_ptr_index]->gen_index = SIZE_MAX; + entry->data.structure.fields[slice_len_index]->gen_index = 0; } ZigType *child_type = ptr_type->data.pointer.child_type; @@ -1984,12 +1984,12 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel struct_type->data.structure.src_field_count = field_count; struct_type->data.structure.gen_field_count = 0; struct_type->data.structure.resolve_status = ResolveStatusSizeKnown; - struct_type->data.structure.fields = allocate(field_count); + struct_type->data.structure.fields = alloc_type_struct_fields(field_count); struct_type->data.structure.fields_by_name.init(field_count); size_t abi_align = min_abi_align; for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; + TypeStructField *field = struct_type->data.structure.fields[i]; field->name = buf_create_from_str(fields[i].name); field->type_entry = fields[i].ty; field->src_index = i; @@ -2009,7 +2009,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel size_t next_offset = 0; for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; + TypeStructField *field = struct_type->data.structure.fields[i]; if (!type_has_bits(field->type_entry)) continue; @@ -2018,7 +2018,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel // find the next non-zero-byte field for offset calculations size_t next_src_field_index = i + 1; for (; next_src_field_index < field_count; next_src_field_index += 1) { - if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry)) + if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry)) break; } size_t next_abi_align; @@ -2026,7 +2026,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel next_abi_align = abi_align; } else { next_abi_align = max(fields[next_src_field_index].align, - struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align); + struct_type->data.structure.fields[next_src_field_index]->type_entry->abi_align); } next_offset = next_field_offset(next_offset, abi_align, field->type_entry->abi_size, next_abi_align); } @@ -2109,7 +2109,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { // Calculate offsets for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; + TypeStructField *field = struct_type->data.structure.fields[i]; if (field->gen_index == SIZE_MAX) continue; @@ -2178,12 +2178,12 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { gen_field_index += 1; size_t next_src_field_index = i + 1; for (; next_src_field_index < field_count; next_src_field_index += 1) { - if (struct_type->data.structure.fields[next_src_field_index].gen_index != SIZE_MAX) { + if (struct_type->data.structure.fields[next_src_field_index]->gen_index != SIZE_MAX) { break; } } size_t next_align = (next_src_field_index == field_count) ? - abi_align : struct_type->data.structure.fields[next_src_field_index].align; + abi_align : struct_type->data.structure.fields[next_src_field_index]->align; next_offset = next_field_offset(next_offset, abi_align, field_abi_size, next_align); size_in_bits = next_offset * 8; } @@ -2206,7 +2206,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) { // Resolve types for fields for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; + TypeStructField *field = struct_type->data.structure.fields[i]; ZigType *field_type = resolve_struct_field_type(g, field); if (field_type == nullptr) { struct_type->data.structure.resolve_status = ResolveStatusInvalid; @@ -2697,7 +2697,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { struct_type->data.structure.src_field_count = (uint32_t)field_count; src_assert(struct_type->data.structure.fields == nullptr, decl_node); - struct_type->data.structure.fields = allocate(field_count); + struct_type->data.structure.fields = alloc_type_struct_fields(field_count); } else if (decl_node->type == NodeTypeContainerInitExpr) { src_assert(struct_type->data.structure.is_inferred, decl_node); src_assert(struct_type->data.structure.fields != nullptr, decl_node); @@ -2711,7 +2711,7 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) { size_t gen_field_index = 0; for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; + TypeStructField *type_struct_field = struct_type->data.structure.fields[i]; AstNode *field_node; if (decl_node->type == NodeTypeContainerDecl) { @@ -2843,7 +2843,7 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) { bool packed = struct_type->data.structure.layout == ContainerLayoutPacked; for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; + TypeStructField *field = struct_type->data.structure.fields[i]; if (field->gen_index == SIZE_MAX) continue; @@ -5506,7 +5506,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) { return type_has_one_possible_value(g, type_entry->data.array.child_type); case ZigTypeIdStruct: for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { - TypeStructField *field = &type_entry->data.structure.fields[i]; + TypeStructField *field = type_entry->data.structure.fields[i]; OnePossibleValue opv = (field->type_entry != nullptr) ? type_has_one_possible_value(g, field->type_entry) : type_val_resolve_has_one_possible_value(g, field->type_val); @@ -5902,6 +5902,21 @@ ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, return result; } +TypeStructField **alloc_type_struct_fields(size_t count) { + return realloc_type_struct_fields(nullptr, 0, count); +} + +TypeStructField **realloc_type_struct_fields(TypeStructField **ptr, size_t old_count, size_t new_count) { + assert(new_count >= old_count); + + size_t new_item_count = new_count - old_count; + TypeStructField **result = reallocate(ptr, old_count, new_count, "TypeStructField*"); + TypeStructField *vals = allocate(new_item_count, "TypeStructField"); + for (size_t i = old_count; i < new_count; i += 1) { + result[i] = &vals[i - old_count]; + } + return result; +} static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) { if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) @@ -7176,7 +7191,7 @@ static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { const_val->data.x_struct.fields = alloc_const_vals_ptrs(field_count); for (size_t i = 0; i < field_count; i += 1) { ConstExprValue *field_val = const_val->data.x_struct.fields[i]; - field_val->type = resolve_struct_field_type(g, &wanted_type->data.structure.fields[i]); + field_val->type = resolve_struct_field_type(g, wanted_type->data.structure.fields[i]); assert(field_val->type); init_const_undefined(g, field_val); field_val->parent.id = ConstParentIdStruct; @@ -7608,7 +7623,7 @@ static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size } X64CABIClass working_class = X64CABIClass_Unknown; for (uint32_t i = 0; i < ty->data.structure.src_field_count; i += 1) { - X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.structure.fields->type_entry); + X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.structure.fields[0]->type_entry); if (field_class == X64CABIClass_Unknown) return X64CABIClass_Unknown; if (i == 0 || field_class == X64CABIClass_MEMORY || working_class == X64CABIClass_SSE) { @@ -7740,7 +7755,7 @@ Buf *type_h_name(ZigType *t) { static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) { if (type->data.structure.resolve_status >= wanted_resolve_status) return; - ZigType *ptr_type = type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *ptr_type = type->data.structure.fields[slice_ptr_index]->type_entry; ZigType *child_type = ptr_type->data.pointer.child_type; ZigType *usize_type = g->builtin_types.entry_usize; @@ -7762,7 +7777,7 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa // If the child type is []const T then we need to make sure the type ref // and debug info is the same as if the child type were []T. if (is_slice(child_type)) { - ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index]->type_entry; assert(child_ptr_type->id == ZigTypeIdPointer); if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile || child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero) @@ -7939,7 +7954,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS // trigger all the recursive get_llvm_type calls for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; + TypeStructField *field = struct_type->data.structure.fields[i]; ZigType *field_type = field->type_entry; if (!type_has_bits(field_type)) continue; @@ -7953,7 +7968,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS // inserting padding bytes where LLVM would do it automatically. size_t llvm_struct_abi_align = 0; for (size_t i = 0; i < field_count; i += 1) { - ZigType *field_type = struct_type->data.structure.fields[i].type_entry; + ZigType *field_type = struct_type->data.structure.fields[i]->type_entry; if (!type_has_bits(field_type)) continue; LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type); @@ -7962,7 +7977,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS } for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; + TypeStructField *field = struct_type->data.structure.fields[i]; ZigType *field_type = field->type_entry; if (!type_has_bits(field_type)) { @@ -8012,23 +8027,23 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS // find the next non-zero-byte field for offset calculations size_t next_src_field_index = i + 1; for (; next_src_field_index < field_count; next_src_field_index += 1) { - if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry)) + if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry)) break; } size_t next_abi_align; if (next_src_field_index == field_count) { next_abi_align = struct_type->abi_align; } else { - if (struct_type->data.structure.fields[next_src_field_index].align == 0) { - next_abi_align = struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align; + if (struct_type->data.structure.fields[next_src_field_index]->align == 0) { + next_abi_align = struct_type->data.structure.fields[next_src_field_index]->type_entry->abi_align; } else { - next_abi_align = struct_type->data.structure.fields[next_src_field_index].align; + next_abi_align = struct_type->data.structure.fields[next_src_field_index]->align; } } size_t llvm_next_abi_align = (next_src_field_index == field_count) ? llvm_struct_abi_align : LLVMABIAlignmentOfType(g->target_data_ref, - get_llvm_type(g, struct_type->data.structure.fields[next_src_field_index].type_entry)); + get_llvm_type(g, struct_type->data.structure.fields[next_src_field_index]->type_entry)); size_t next_offset = next_field_offset(field->offset, struct_type->abi_align, field_type->abi_size, next_abi_align); @@ -8067,7 +8082,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS ZigLLVMDIType **di_element_types = allocate(debug_field_count); size_t debug_field_index = 0; for (size_t i = 0; i < field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; + TypeStructField *field = struct_type->data.structure.fields[i]; size_t gen_field_index = field->gen_index; if (gen_field_index == SIZE_MAX) { continue; diff --git a/src/analyze.hpp b/src/analyze.hpp index 0cca75891a..ddfb31c286 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -180,6 +180,9 @@ ConstExprValue *create_const_vals(size_t count); ConstExprValue **alloc_const_vals_ptrs(size_t count); ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count); +TypeStructField **alloc_type_struct_fields(size_t count); +TypeStructField **realloc_type_struct_fields(TypeStructField **ptr, size_t old_count, size_t new_count); + ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); void expand_undef_array(CodeGen *g, ConstExprValue *const_val); void expand_undef_struct(CodeGen *g, ConstExprValue *const_val); diff --git a/src/codegen.cpp b/src/codegen.cpp index ed9b69e529..a97f5cbd55 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1108,15 +1108,15 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0); LLVMValueRef address_value = LLVMGetParam(fn_val, 1); - size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index; + size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index; LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)index_field_index, ""); - size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; + size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index; LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, ""); - ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; - size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; + ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry; + size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); - size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index; + size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, ""); @@ -2176,16 +2176,16 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { LLVMBuildCondBr(g->builder, null_bit, return_block, non_null_block); LLVMPositionBuilderAtEnd(g->builder, non_null_block); - size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index; - size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; + size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index; + size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index; LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr, (unsigned)src_index_field_index, ""); LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr, (unsigned)src_addresses_field_index, ""); - ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; - size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; + ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry; + size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, ""); - size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index; + size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, ""); LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, ""); LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, ""); @@ -3010,21 +3010,21 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable, assert(actual_type->id == ZigTypeIdStruct); assert(actual_type->data.structure.is_slice); - ZigType *actual_pointer_type = actual_type->data.structure.fields[0].type_entry; + ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry; ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type; - ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry; + ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0]->type_entry; ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type; - size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index].gen_index; - size_t actual_len_index = actual_type->data.structure.fields[slice_len_index].gen_index; - size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index].gen_index; - size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index].gen_index; + size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index]->gen_index; + size_t actual_len_index = actual_type->data.structure.fields[slice_len_index]->gen_index; + size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index]->gen_index; + size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index]->gen_index; LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, ""); LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, ""); LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, - get_llvm_type(g, wanted_type->data.structure.fields[0].type_entry), ""); + get_llvm_type(g, wanted_type->data.structure.fields[0]->type_entry), ""); LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc, (unsigned)wanted_ptr_index, ""); gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false); @@ -3140,9 +3140,9 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *ex { ZigType *actual_type = instruction->operand->value.type; ZigType *slice_type = instruction->base.value.type; - ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry; - size_t ptr_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; - size_t len_index = slice_type->data.structure.fields[slice_len_index].gen_index; + ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; + size_t ptr_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; + size_t len_index = slice_type->data.structure.fields[slice_len_index]->gen_index; LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); @@ -3766,14 +3766,14 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); if (safety_check_on) { - size_t len_index = array_type->data.structure.fields[slice_len_index].gen_index; + size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index; assert(len_index != SIZE_MAX); LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, ""); LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, ""); add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, len); } - size_t ptr_index = array_type->data.structure.fields[slice_ptr_index].gen_index; + size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index; assert(ptr_index != SIZE_MAX); LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, ""); LLVMValueRef ptr = gen_load_untyped(g, ptr_ptr, 0, false, ""); @@ -3865,7 +3865,7 @@ static void render_async_spills(CodeGen *g) { if (instruction->field_index == SIZE_MAX) continue; - size_t gen_index = frame_type->data.structure.fields[instruction->field_index].gen_index; + size_t gen_index = frame_type->data.structure.fields[instruction->field_index]->gen_index; instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index, instruction->name_hint); } @@ -4992,10 +4992,10 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment; ptr_val = target_val; } else if (target_type->id == ZigTypeIdStruct && target_type->data.structure.is_slice) { - ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; align_bytes = get_ptr_align(g, slice_ptr_type); - size_t ptr_index = target_type->data.structure.fields[slice_ptr_index].gen_index; + size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index; LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP(g->builder, target_val, (unsigned)ptr_index, ""); ptr_val = gen_load_untyped(g, ptr_val_ptr, 0, false, ""); } else { @@ -5240,13 +5240,13 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst } if (type_has_bits(array_type)) { - size_t gen_ptr_index = instruction->base.value.type->data.structure.fields[slice_ptr_index].gen_index; + size_t gen_ptr_index = instruction->base.value.type->data.structure.fields[slice_ptr_index]->gen_index; LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, ""); LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, ""); gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); } - size_t gen_len_index = instruction->base.value.type->data.structure.fields[slice_len_index].gen_index; + size_t gen_len_index = instruction->base.value.type->data.structure.fields[slice_len_index]->gen_index; LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_len_index, ""); LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, ""); gen_store_untyped(g, len_value, len_field_ptr, 0, false); @@ -5258,9 +5258,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind); - size_t ptr_index = array_type->data.structure.fields[slice_ptr_index].gen_index; + size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index; assert(ptr_index != SIZE_MAX); - size_t len_index = array_type->data.structure.fields[slice_len_index].gen_index; + size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index; assert(len_index != SIZE_MAX); LLVMValueRef prev_end = nullptr; @@ -6568,7 +6568,7 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false); size_t used_bits = 0; for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { - TypeStructField *field = &type_entry->data.structure.fields[i]; + TypeStructField *field = type_entry->data.structure.fields[i]; if (field->gen_index == SIZE_MAX) { continue; } @@ -6647,7 +6647,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con return const_val->global_refs->llvm_value; } size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index; - size_t gen_field_index = struct_const_val->type->data.structure.fields[src_field_index].gen_index; + size_t gen_field_index = struct_const_val->type->data.structure.fields[src_field_index]->gen_index; LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val, gen_field_index); LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); @@ -6826,7 +6826,7 @@ check: switch (const_val->special) { if (type_entry->data.structure.layout == ContainerLayoutPacked) { size_t src_field_index = 0; while (src_field_index < src_field_count) { - TypeStructField *type_struct_field = &type_entry->data.structure.fields[src_field_index]; + TypeStructField *type_struct_field = type_entry->data.structure.fields[src_field_index]; if (type_struct_field->gen_index == SIZE_MAX) { src_field_index += 1; continue; @@ -6834,7 +6834,7 @@ check: switch (const_val->special) { size_t src_field_index_end = src_field_index + 1; for (; src_field_index_end < src_field_count; src_field_index_end += 1) { - TypeStructField *it_field = &type_entry->data.structure.fields[src_field_index_end]; + TypeStructField *it_field = type_entry->data.structure.fields[src_field_index_end]; if (it_field->gen_index != type_struct_field->gen_index) break; } @@ -6853,7 +6853,7 @@ check: switch (const_val->special) { LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false); size_t used_bits = 0; for (size_t i = src_field_index; i < src_field_index_end; i += 1) { - TypeStructField *it_field = &type_entry->data.structure.fields[i]; + TypeStructField *it_field = type_entry->data.structure.fields[i]; if (it_field->gen_index == SIZE_MAX) { continue; } @@ -6893,7 +6893,7 @@ check: switch (const_val->special) { } } else { for (uint32_t i = 0; i < src_field_count; i += 1) { - TypeStructField *type_struct_field = &type_entry->data.structure.fields[i]; + TypeStructField *type_struct_field = type_entry->data.structure.fields[i]; if (type_struct_field->gen_index == SIZE_MAX) { continue; } @@ -6910,10 +6910,10 @@ check: switch (const_val->special) { make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val); size_t end_pad_gen_index = (i + 1 < src_field_count) ? - type_entry->data.structure.fields[i + 1].gen_index : + type_entry->data.structure.fields[i + 1]->gen_index : type_entry->data.structure.gen_field_count; size_t next_offset = (i + 1 < src_field_count) ? - type_entry->data.structure.fields[i + 1].offset : type_entry->abi_size; + type_entry->data.structure.fields[i + 1]->offset : type_entry->abi_size; if (end_pad_gen_index != SIZE_MAX) { for (size_t gen_i = type_struct_field->gen_index + 1; gen_i < end_pad_gen_index; gen_i += 1) @@ -7576,15 +7576,15 @@ static void do_code_gen(CodeGen *g) { // finishing error return trace setup. we have to do this after all the allocas. if (have_err_ret_trace_stack) { ZigType *usize = g->builtin_types.entry_usize; - size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index; + size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index; LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, ""); gen_store_untyped(g, LLVMConstNull(usize->llvm_type), index_field_ptr, 0, false); - size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index; + size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index; LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, ""); - ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry; - size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index; + ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry; + size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); LLVMValueRef zero = LLVMConstNull(usize->llvm_type); LLVMValueRef indices[] = {zero, zero}; @@ -7593,7 +7593,7 @@ static void do_code_gen(CodeGen *g) { ZigType *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false); gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type); - size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index; + size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); gen_store(g, LLVMConstInt(usize->llvm_type, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false)); } @@ -9508,7 +9508,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e return; case ZigTypeIdStruct: for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { - TypeStructField *field = &type_entry->data.structure.fields[i]; + TypeStructField *field = type_entry->data.structure.fields[i]; prepend_c_type_to_decl_list(g, gen_h, field->type_entry); } gen_h->types_to_declare.append(type_entry); @@ -9874,7 +9874,7 @@ static void gen_h_file(CodeGen *g) { if (type_entry->data.structure.layout == ContainerLayoutExtern) { fprintf(out_h, "struct %s {\n", buf_ptr(type_h_name(type_entry))); for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) { - TypeStructField *struct_field = &type_entry->data.structure.fields[field_i]; + TypeStructField *struct_field = type_entry->data.structure.fields[field_i]; Buf *type_name_buf = buf_alloc(); get_c_type(g, gen_h, struct_field->type_entry, type_name_buf); diff --git a/src/dump_analysis.cpp b/src/dump_analysis.cpp index 9703d3e57d..b5fd38e266 100644 --- a/src/dump_analysis.cpp +++ b/src/dump_analysis.cpp @@ -268,7 +268,7 @@ static void tree_print_struct(FILE *f, ZigType *struct_type, size_t indent) { ZigList children = {}; uint64_t sum_from_fields = 0; for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { - TypeStructField *field = &struct_type->data.structure.fields[i]; + TypeStructField *field = struct_type->data.structure.fields[i]; children.append(field->type_entry); sum_from_fields += field->type_entry->abi_size; } @@ -747,7 +747,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { if (ty->data.structure.is_slice) { jw_object_field(jw, "len"); jw_int(jw, 2); - anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index].type_entry); + anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index]->type_entry); break; } @@ -803,7 +803,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { for(size_t i = 0; i < ty->data.structure.src_field_count; i += 1) { jw_array_elem(jw); - anal_dump_type_ref(ctx, ty->data.structure.fields[i].type_entry); + anal_dump_type_ref(ctx, ty->data.structure.fields[i]->type_entry); } jw_end_array(jw); } diff --git a/src/ir.cpp b/src/ir.cpp index d52daacc42..99af2e7861 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -277,7 +277,7 @@ static bool is_slice(ZigType *type) { static bool slice_is_const(ZigType *type) { assert(is_slice(type)); - return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; + return type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; } // This function returns true when you can change the type of a ConstExprValue and the @@ -9858,8 +9858,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted // slice const if (is_slice(wanted_type) && is_slice(actual_type)) { - ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry; - ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index]->type_entry; + ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry; if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { result.id = ConstCastResultIdInvalid; return result; @@ -10623,7 +10623,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT ZigType *array_type = cur_type->data.pointer.child_type; ZigType *slice_type = (prev_type->id == ZigTypeIdErrorUnion) ? prev_type->data.error_union.payload_type : prev_type; - ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0) && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, @@ -10644,7 +10644,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT ZigType *array_type = prev_type->data.pointer.child_type; ZigType *slice_type = (cur_type->id == ZigTypeIdErrorUnion) ? cur_type->data.error_union.payload_type : cur_type; - ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0) && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, @@ -10658,10 +10658,10 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT // [N]T to []T if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) && - (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || + (prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const || cur_type->data.array.len == 0) && types_match_const_cast_only(ira, - prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, + prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type, cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) { convert_to_const_slice = false; @@ -10670,10 +10670,10 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT // [N]T to []T if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) && - (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || + (cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const || prev_type->data.array.len == 0) && types_match_const_cast_only(ira, - cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, + cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type, prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) { prev_inst = cur_inst; @@ -10978,7 +10978,7 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc assert(value->value.type->id == ZigTypeIdPointer); ZigType *array_type = value->value.type->data.pointer.child_type; assert(is_slice(wanted_type)); - bool is_const = wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; + bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; IrInstruction *result = ir_const(ira, source_instr, wanted_type); init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const); @@ -12775,7 +12775,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst // cast from [N]T to []const T // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) { - ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry; assert(ptr_type->id == ZigTypeIdPointer); if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, @@ -12792,7 +12792,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst actual_type->id == ZigTypeIdArray) { ZigType *ptr_type = - wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry; + wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index]->type_entry; assert(ptr_type->id == ZigTypeIdPointer); if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, @@ -12841,7 +12841,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst { ZigType *slice_type = (wanted_type->id == ZigTypeIdErrorUnion) ? wanted_type->data.error_union.payload_type : wanted_type; - ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; assert(slice_ptr_type->id == ZigTypeIdPointer); ZigType *array_type = actual_type->data.pointer.child_type; bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 @@ -12895,7 +12895,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst actual_type->data.pointer.child_type->id == ZigTypeIdArray) { ZigType *slice_type = wanted_type->data.error_union.payload_type; - ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; assert(slice_ptr_type->id == ZigTypeIdPointer); ZigType *array_type = actual_type->data.pointer.child_type; bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 @@ -12972,7 +12972,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst actual_type->id == ZigTypeIdArray) { ZigType *ptr_type = - wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry; + wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index]->type_entry; assert(ptr_type->id == ZigTypeIdPointer); if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, @@ -14817,7 +14817,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; op1_array_end = op1_array_val->type->data.array.len - 1; } else if (is_slice(op1_type)) { - ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry; child_type = ptr_type->data.pointer.child_type; ConstExprValue *ptr_val = op1_val->data.x_struct.fields[slice_ptr_index]; assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); @@ -14850,7 +14850,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; op2_array_end = op2_array_val->type->data.array.len - 1; } else if (is_slice(op2_type)) { - ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry; op2_type_valid = ptr_type->data.pointer.child_type == child_type; ConstExprValue *ptr_val = op2_val->data.x_struct.fields[slice_ptr_index]; assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); @@ -16458,18 +16458,10 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count; uint32_t new_field_count = old_field_count + 1; isf->inferred_struct_type->data.structure.src_field_count = new_field_count; - if (new_field_count > 16) { - // This thing with 16 is a hack to allow this functionality to work without - // modifying the ConstExprValue layout of structs. That reworking needs to be - // done, but this hack lets us do it separately, in the future. - zig_panic("TODO need to rework the layout of ZigTypeStruct. This realloc would have caused invalid pointer references"); - } - if (isf->inferred_struct_type->data.structure.fields == nullptr) { - isf->inferred_struct_type->data.structure.fields = allocate(16); - } + isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields( + isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count); - // This reference can't live long, don't keep it around outside this block. - TypeStructField *field = &isf->inferred_struct_type->data.structure.fields[old_field_count]; + TypeStructField *field = isf->inferred_struct_type->data.structure.fields[old_field_count]; field->name = isf->field_name; field->type_entry = uncasted_value->value.type; field->type_val = create_const_type(ira->codegen, field->type_entry); @@ -17900,7 +17892,7 @@ static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_ali static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) { assert(is_slice(slice_type)); - ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index].type_entry, + ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index]->type_entry, new_align); return get_slice_type(g, ptr_type); } @@ -17986,7 +17978,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct } return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); } else if (is_slice(array_type)) { - return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index].type_entry, + return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index]->type_entry, elem_ptr_instruction->ptr_len); } else if (array_type->id == ZigTypeIdArgTuple) { ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); @@ -18464,7 +18456,7 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction ConstExprValue *field_val = struct_val->data.x_struct.fields[i]; field_val->special = ConstValSpecialUndef; field_val->type = resolve_struct_field_type(ira->codegen, - &struct_type->data.structure.fields[i]); + struct_type->data.structure.fields[i]); field_val->parent.id = ConstParentIdStruct; field_val->parent.data.p_struct.struct_val = struct_val; field_val->parent.data.p_struct.field_index = i; @@ -20385,7 +20377,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc if (field_assign_nodes[i] != nullptr) continue; // look for a default field value - TypeStructField *field = &container_type->data.structure.fields[i]; + TypeStructField *field = container_type->data.structure.fields[i]; if (field->init_val == nullptr) { // it's not memoized. time to go analyze it AstNode *init_node; @@ -20396,7 +20388,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc } if (init_node == nullptr) { ir_add_error_node(ira, instruction->source_node, - buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); + buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i]->name))); any_missing = true; continue; } @@ -21198,7 +21190,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty ZigType *attrs_type; BuiltinPtrSize size_enum_index; if (is_slice(ptr_type_entry)) { - attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry; + attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index]->type_entry; size_enum_index = BuiltinPtrSizeSlice; } else if (ptr_type_entry->id == ZigTypeIdPointer) { attrs_type = ptr_type_entry; @@ -21691,7 +21683,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false); for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { - TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index]; + TypeStructField *struct_field = type_entry->data.structure.fields[struct_field_index]; ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index]; struct_field_val->special = ConstValSpecialStatic; @@ -22647,7 +22639,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru if ((err = resolve_ptr_align(ira, target->value.type, &src_ptr_align))) return ira->codegen->invalid_instruction; } else if (is_slice(target->value.type)) { - ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index]->type_entry; src_ptr_const = src_ptr_type->data.pointer.is_const; src_ptr_volatile = src_ptr_type->data.pointer.is_volatile; @@ -22740,7 +22732,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct return ira->codegen->invalid_instruction; } - ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index]->type_entry; uint32_t alignment; if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment))) @@ -23548,7 +23540,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction } } } else if (is_slice(array_type)) { - ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; return_type = get_slice_type(ira->codegen, ptr_type); } else { ir_add_error(ira, &instruction->base, @@ -23857,7 +23849,7 @@ static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstr member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); return ira->codegen->invalid_instruction; } - TypeStructField *field = &container_type->data.structure.fields[member_index]; + TypeStructField *field = container_type->data.structure.fields[member_index]; return ir_const_type(ira, &instruction->base, field->type_entry); } else if (container_type->id == ZigTypeIdUnion) { @@ -23899,7 +23891,7 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); return ira->codegen->invalid_instruction; } - TypeStructField *field = &container_type->data.structure.fields[member_index]; + TypeStructField *field = container_type->data.structure.fields[member_index]; IrInstruction *result = ir_const(ira, &instruction->base, nullptr); init_const_str_lit(ira->codegen, &result->value, field->name); @@ -24885,7 +24877,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id); result_type = get_optional_type(ira->codegen, fn_type); } else if (is_slice(target_type)) { - ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes))) return ira->codegen->invalid_instruction; ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); @@ -25130,7 +25122,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue case ContainerLayoutExtern: { size_t src_field_count = val->type->data.structure.src_field_count; for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { - TypeStructField *struct_field = &val->type->data.structure.fields[field_i]; + TypeStructField *struct_field = val->type->data.structure.fields[field_i]; if (struct_field->gen_index == SIZE_MAX) continue; ConstExprValue *field_val = val->data.x_struct.fields[field_i]; @@ -25159,7 +25151,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue bigint_init_unsigned(&big_int, 0); size_t used_bits = 0; while (src_i < src_field_count) { - TypeStructField *field = &val->type->data.structure.fields[src_i]; + TypeStructField *field = val->type->data.structure.fields[src_i]; assert(field->gen_index != SIZE_MAX); if (field->gen_index != gen_i) break; @@ -25306,7 +25298,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { ConstExprValue *field_val = val->data.x_struct.fields[field_i]; field_val->special = ConstValSpecialStatic; - TypeStructField *struct_field = &val->type->data.structure.fields[field_i]; + TypeStructField *struct_field = val->type->data.structure.fields[field_i]; field_val->type = struct_field->type_entry; if (struct_field->gen_index == SIZE_MAX) continue; @@ -25337,7 +25329,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou BigInt big_int; bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false); while (src_i < src_field_count) { - TypeStructField *field = &val->type->data.structure.fields[src_i]; + TypeStructField *field = val->type->data.structure.fields[src_i]; src_assert(field->gen_index != SIZE_MAX, source_node); if (field->gen_index != gen_i) break; @@ -25600,7 +25592,7 @@ static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstru ZigType *elem_type = nullptr; if (is_slice(target->value.type)) { - ZigType *slice_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; + ZigType *slice_ptr_type = target->value.type->data.structure.fields[slice_ptr_index]->type_entry; elem_type = slice_ptr_type->data.pointer.child_type; } else if (target->value.type->id == ZigTypeIdPointer) { elem_type = target->value.type->data.pointer.child_type; -- cgit v1.2.3 From a11da377347aea1085d3b43726040993952122c9 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 14 Nov 2019 10:20:57 +0100 Subject: Update discriminant value also for zero-sized unions Fixes #3681 --- src/codegen.cpp | 33 ++++++++++++++++++++++++--------- test/stage1/behavior/union.zig | 19 +++++++++++++++---- 2 files changed, 39 insertions(+), 13 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index a97f5cbd55..a288f397fd 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4351,17 +4351,32 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab TypeUnionField *field = instruction->field; if (!type_has_bits(field->type_entry)) { - if (union_type->data.unionation.gen_tag_index == SIZE_MAX) { + ZigType *tag_type = union_type->data.unionation.tag_type; + if (!instruction->initializing || !type_has_bits(tag_type)) return nullptr; + + // The field has no bits but we still have to change the discriminant + // value here + LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr); + + LLVMTypeRef tag_type_ref = get_llvm_type(g, tag_type); + LLVMValueRef tag_field_ptr = nullptr; + if (union_type->data.unionation.gen_field_count == 0) { + assert(union_type->data.unionation.gen_tag_index == SIZE_MAX); + // The whole union is collapsed into the discriminant + tag_field_ptr = LLVMBuildBitCast(g->builder, union_ptr, + LLVMPointerType(tag_type_ref, 0), ""); + } else { + assert(union_type->data.unionation.gen_tag_index != SIZE_MAX); + tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, + union_type->data.unionation.gen_tag_index, ""); } - if (instruction->initializing) { - LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr); - LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, - union_type->data.unionation.gen_tag_index, ""); - LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type), - &field->enum_field->value); - gen_store_untyped(g, tag_value, tag_field_ptr, 0, false); - } + + LLVMValueRef tag_value = bigint_to_llvm_const(tag_type_ref, + &field->enum_field->value); + assert(tag_field_ptr != nullptr); + gen_store_untyped(g, tag_value, tag_field_ptr, 0, false); + return nullptr; } diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index caad1d474f..d7481b21c7 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -110,7 +110,7 @@ fn doTest() void { } fn bar(value: Payload) i32 { - expect(@as(Letter,value) == Letter.A); + expect(@as(Letter, value) == Letter.A); return switch (value) { Payload.A => |x| return x - 1244, Payload.B => |x| if (x == 12.34) @as(i32, 20) else 21, @@ -208,7 +208,7 @@ test "cast union to tag type of union" { } fn testCastUnionToTagType(x: TheUnion) void { - expect(@as(TheTag,x) == TheTag.B); + expect(@as(TheTag, x) == TheTag.B); } test "cast tag type of union to union" { @@ -558,16 +558,27 @@ test "anonymous union literal syntax" { }; fn doTheTest() void { - var i: Number = .{.int = 42}; + var i: Number = .{ .int = 42 }; var f = makeNumber(); expect(i.int == 42); expect(f.float == 12.34); } fn makeNumber() Number { - return .{.float = 12.34}; + return .{ .float = 12.34 }; } }; S.doTheTest(); comptime S.doTheTest(); } + +test "update the tag value for zero-sized unions" { + const S = union(enum) { + U0: void, + U1: void, + }; + var x = S{ .U0 = {} }; + expect(x == .U0); + x = S{ .U1 = {} }; + expect(x == .U1); +} -- cgit v1.2.3 From 0b63573674c76bd45f641774c16e0d4e96ee74fd Mon Sep 17 00:00:00 2001 From: Vexu <15308111+Vexu@users.noreply.github.com> Date: Tue, 19 Nov 2019 13:18:08 +0200 Subject: improve broken llvm module error message --- src/codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index a288f397fd..f90777c983 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7725,7 +7725,7 @@ static void do_code_gen(CodeGen *g) { char *error = nullptr; if (LLVMVerifyModule(g->module, LLVMReturnStatusAction, &error)) { - zig_panic("broken LLVM module found: %s", error); + zig_panic("broken LLVM module found: %s\nThis is a bug in the Zig compiler.", error); } } -- cgit v1.2.3