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