diff --git a/src/all_types.hpp b/src/all_types.hpp index 7d9e0003e9..6ef0156bd6 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1430,7 +1430,7 @@ enum VarLinkage { struct VariableTableEntry { Buf name; - ConstExprValue value; + ConstExprValue *value; LLVMValueRef value_ref; bool src_is_const; bool gen_is_const; diff --git a/src/analyze.cpp b/src/analyze.cpp index 03da4a26c7..453cefc2f8 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2085,7 +2085,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent assert(value); VariableTableEntry *variable_entry = allocate(1); - variable_entry->value = *value; + variable_entry->value = value; variable_entry->parent_scope = parent_scope; variable_entry->shadowable = false; variable_entry->mem_slot_index = SIZE_MAX; @@ -2101,21 +2101,21 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent ErrorMsg *msg = add_node_error(g, source_node, buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); - variable_entry->value.type = g->builtin_types.entry_invalid; + variable_entry->value->type = g->builtin_types.entry_invalid; } else { auto primitive_table_entry = g->primitive_type_table.maybe_get(name); if (primitive_table_entry) { TypeTableEntry *type = primitive_table_entry->value; add_node_error(g, source_node, buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); - variable_entry->value.type = g->builtin_types.entry_invalid; + variable_entry->value->type = g->builtin_types.entry_invalid; } else { Tld *tld = find_decl(g, parent_scope, name); if (tld && tld->id != TldIdVar) { ErrorMsg *msg = add_node_error(g, source_node, buf_sprintf("redefinition of '%s'", buf_ptr(name))); add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here")); - variable_entry->value.type = g->builtin_types.entry_invalid; + variable_entry->value->type = g->builtin_types.entry_invalid; } } } @@ -3181,7 +3181,7 @@ uint32_t fn_eval_hash(Scope* scope) { while (scope) { if (scope->id == ScopeIdVarDecl) { ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; - result += hash_const_val(&var_scope->var->value); + result += hash_const_val(var_scope->var->value); } else if (scope->id == ScopeIdFnDef) { ScopeFnDef *fn_scope = (ScopeFnDef *)scope; result += hash_ptr(fn_scope->fn_entry); @@ -3203,9 +3203,9 @@ bool fn_eval_eql(Scope *a, Scope *b) { if (a->id == ScopeIdVarDecl) { ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a; ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b; - if (a_var_scope->var->value.type != b_var_scope->var->value.type) + if (a_var_scope->var->value->type != b_var_scope->var->value->type) return false; - if (!const_values_equal(&a_var_scope->var->value, &b_var_scope->var->value)) + if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value)) return false; } else if (a->id == ScopeIdFnDef) { ScopeFnDef *a_fn_scope = (ScopeFnDef *)a; diff --git a/src/ast_render.cpp b/src/ast_render.cpp index b1e1306c7c..8a17cc4cf5 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -964,26 +964,26 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { const char *extern_str = extern_string(var->linkage == VarLinkageExternal); fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(name)); - if (var->value.type->id == TypeTableEntryIdNumLitFloat || - var->value.type->id == TypeTableEntryIdNumLitInt || - var->value.type->id == TypeTableEntryIdMetaType) + if (var->value->type->id == TypeTableEntryIdNumLitFloat || + var->value->type->id == TypeTableEntryIdNumLitInt || + var->value->type->id == TypeTableEntryIdMetaType) { // skip type } else { - fprintf(ar->f, ": %s", buf_ptr(&var->value.type->name)); + fprintf(ar->f, ": %s", buf_ptr(&var->value->type->name)); } - if (var->value.special == ConstValSpecialRuntime) { + if (var->value->special == ConstValSpecialRuntime) { fprintf(ar->f, ";\n"); return; } fprintf(ar->f, " = "); - if (var->value.special == ConstValSpecialStatic && - var->value.type->id == TypeTableEntryIdMetaType) + if (var->value->special == ConstValSpecialStatic && + var->value->type->id == TypeTableEntryIdMetaType) { - TypeTableEntry *type_entry = var->value.data.x_type; + TypeTableEntry *type_entry = var->value->data.x_type; if (type_entry->id == TypeTableEntryIdStruct) { const char *layout_str = layout_string(type_entry->data.structure.layout); fprintf(ar->f, "%sstruct {\n", layout_str); @@ -1022,7 +1022,7 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { } else { Buf buf = BUF_INIT; buf_resize(&buf, 0); - render_const_value(&buf, &var->value); + render_const_value(&buf, var->value); fprintf(ar->f, "%s", buf_ptr(&buf)); } diff --git a/src/codegen.cpp b/src/codegen.cpp index 99e095ffbc..14d2f68116 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1316,7 +1316,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, { VariableTableEntry *var = decl_var_instruction->var; - if (!type_has_bits(var->value.type)) + if (!type_has_bits(var->value->type)) return nullptr; if (var->ref_count == 0 && g->is_release_build) @@ -1331,16 +1331,16 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, have_init_expr = true; if (have_init_expr) { - assert(var->value.type == init_value->value.type); - gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value.type); + assert(var->value->type == init_value->value.type); + gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value->type); } else { bool ignore_uninit = false; // handle runtime stack allocation bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base); if (!ignore_uninit && want_safe) { TypeTableEntry *usize = g->builtin_types.entry_usize; - uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value.type->type_ref); - uint64_t align_bytes = get_type_alignment(g, var->value.type); + uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref); + uint64_t align_bytes = get_type_alignment(g, var->value->type); // memset uninitialized memory to 0xa LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); @@ -1437,7 +1437,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { VariableTableEntry *var = instruction->var; - if (type_has_bits(var->value.type)) { + if (type_has_bits(var->value->type)) { assert(var->value_ref); return var->value_ref; } else { @@ -3203,9 +3203,9 @@ static void do_code_gen(CodeGen *g) { TldVar *tld_var = g->global_vars.at(i); VariableTableEntry *var = tld_var->var; - if (var->value.type->id == TypeTableEntryIdNumLitFloat) { + if (var->value->type->id == TypeTableEntryIdNumLitFloat) { // Generate debug info for it but that's it. - ConstExprValue *const_val = &var->value; + ConstExprValue *const_val = var->value; assert(const_val->special != ConstValSpecialRuntime); TypeTableEntry *var_type = g->builtin_types.entry_f64; LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float); @@ -3213,9 +3213,9 @@ static void do_code_gen(CodeGen *g) { continue; } - if (var->value.type->id == TypeTableEntryIdNumLitInt) { + if (var->value->type->id == TypeTableEntryIdNumLitInt) { // Generate debug info for it but that's it. - ConstExprValue *const_val = &var->value; + ConstExprValue *const_val = var->value; assert(const_val->special != ConstValSpecialRuntime); TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ? g->builtin_types.entry_isize : g->builtin_types.entry_usize; @@ -3225,22 +3225,22 @@ static void do_code_gen(CodeGen *g) { continue; } - if (!type_has_bits(var->value.type)) + if (!type_has_bits(var->value->type)) continue; assert(var->decl_node); LLVMValueRef global_value; if (var->linkage == VarLinkageExternal) { - global_value = LLVMAddGlobal(g->module, var->value.type->type_ref, buf_ptr(&var->name)); + global_value = LLVMAddGlobal(g->module, var->value->type->type_ref, buf_ptr(&var->name)); // TODO debug info for the extern variable LLVMSetLinkage(global_value, LLVMExternalLinkage); } else { - render_const_val(g, &var->value); - render_const_val_global(g, &var->value, buf_ptr(&var->name)); - global_value = var->value.llvm_global; + render_const_val(g, var->value); + render_const_val_global(g, var->value, buf_ptr(&var->name)); + global_value = var->value->llvm_global; if (var->linkage == VarLinkageExport) { LLVMSetLinkage(global_value, LLVMExternalLinkage); @@ -3249,11 +3249,11 @@ static void do_code_gen(CodeGen *g) { LLVMSetSection(global_value, buf_ptr(tld_var->section_name)); } LLVMSetAlignment(global_value, tld_var->alignment ? - tld_var->alignment : get_type_alignment(g, var->value.type)); + tld_var->alignment : get_type_alignment(g, var->value->type)); // TODO debug info for function pointers - if (var->gen_is_const && var->value.type->id != TypeTableEntryIdFn) { - gen_global_var(g, var, var->value.llvm_value, var->value.type); + if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) { + gen_global_var(g, var, var->value->llvm_value, var->value->type); } } @@ -3432,30 +3432,30 @@ static void do_code_gen(CodeGen *g) { for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) { VariableTableEntry *var = fn_table_entry->variable_list.at(var_i); - if (!type_has_bits(var->value.type)) { + if (!type_has_bits(var->value->type)) { continue; } if (ir_get_var_is_comptime(var)) continue; - if (type_requires_comptime(var->value.type)) + if (type_requires_comptime(var->value->type)) continue; if (var->src_arg_index == SIZE_MAX) { - var->value_ref = build_alloca(g, var->value.type, buf_ptr(&var->name)); + var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name)); var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), buf_ptr(&var->name), import->di_file, var->decl_node->line + 1, - var->value.type->di_type, !g->strip_debug_symbols, 0); + var->value->type->di_type, !g->strip_debug_symbols, 0); } else { assert(var->gen_arg_index != SIZE_MAX); TypeTableEntry *gen_type; - if (handle_is_ptr(var->value.type)) { + if (handle_is_ptr(var->value->type)) { gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type; var->value_ref = LLVMGetParam(fn, var->gen_arg_index); } else { - gen_type = var->value.type; - var->value_ref = build_alloca(g, var->value.type, buf_ptr(&var->name)); + gen_type = var->value->type; + var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name)); } if (var->decl_node) { var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope), @@ -3483,7 +3483,7 @@ static void do_code_gen(CodeGen *g) { assert(variable); assert(variable->value_ref); - if (!handle_is_ptr(variable->value.type)) { + if (!handle_is_ptr(variable->value->type)) { clear_debug_source_node(g); LLVMBuildStore(g->builder, LLVMGetParam(fn, variable->gen_arg_index), variable->value_ref); } diff --git a/src/ir.cpp b/src/ir.cpp index 8e614298ea..6fbea22b09 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3164,6 +3164,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco variable_entry->mem_slot_index = SIZE_MAX; variable_entry->is_comptime = is_comptime; variable_entry->src_arg_index = SIZE_MAX; + variable_entry->value = allocate(1); if (name) { buf_init_from_buf(&variable_entry->name, name); @@ -3173,21 +3174,21 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco ErrorMsg *msg = add_node_error(codegen, node, buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); - variable_entry->value.type = codegen->builtin_types.entry_invalid; + variable_entry->value->type = codegen->builtin_types.entry_invalid; } else { auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name); if (primitive_table_entry) { TypeTableEntry *type = primitive_table_entry->value; add_node_error(codegen, node, buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); - variable_entry->value.type = codegen->builtin_types.entry_invalid; + variable_entry->value->type = codegen->builtin_types.entry_invalid; } else { Tld *tld = find_decl(codegen, parent_scope, name); if (tld && tld->id != TldIdVar) { ErrorMsg *msg = add_node_error(codegen, node, buf_sprintf("redefinition of '%s'", buf_ptr(name))); add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); - variable_entry->value.type = codegen->builtin_types.entry_invalid; + variable_entry->value->type = codegen->builtin_types.entry_invalid; } } } @@ -4516,7 +4517,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod // is inside var->child_scope if (!is_extern && !variable_declaration->expr) { - var->value.type = irb->codegen->builtin_types.entry_invalid; + var->value->type = irb->codegen->builtin_types.entry_invalid; add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); return irb->codegen->invalid_instruction; } @@ -5387,7 +5388,7 @@ static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; if (need_comma) buf_append_char(name, ','); - render_const_value(name, &var_scope->var->value); + render_const_value(name, var_scope->var->value); return true; } @@ -7827,8 +7828,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc IrInstruction *init_value = decl_var_instruction->init_value->other; if (type_is_invalid(init_value->value.type)) { - var->value.type = ira->codegen->builtin_types.entry_invalid; - return var->value.type; + var->value->type = ira->codegen->builtin_types.entry_invalid; + return var->value->type; } AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration; @@ -7844,8 +7845,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc TypeTableEntry *proposed_type = ir_resolve_type(ira, var_type); explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); if (type_is_invalid(explicit_type)) { - var->value.type = ira->codegen->builtin_types.entry_invalid; - return var->value.type; + var->value->type = ira->codegen->builtin_types.entry_invalid; + return var->value->type; } } @@ -7906,8 +7907,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc break; } - var->value.type = result_type; - assert(var->value.type); + var->value->type = result_type; + assert(var->value->type); if (type_is_invalid(result_type)) { decl_var_instruction->base.other = &decl_var_instruction->base; @@ -7930,7 +7931,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc } else if (is_comptime) { ir_add_error(ira, &decl_var_instruction->base, buf_sprintf("cannot store runtime value in compile time variable")); - var->value.type = ira->codegen->builtin_types.entry_invalid; + var->value->type = ira->codegen->builtin_types.entry_invalid; return ira->codegen->builtin_types.entry_invalid; } @@ -8766,24 +8767,24 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction, VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr) { - assert(var->value.type); - if (type_is_invalid(var->value.type)) - return var->value.type; + assert(var->value->type); + if (type_is_invalid(var->value->type)) + return var->value->type; bool comptime_var_mem = ir_get_var_is_comptime(var); ConstExprValue *mem_slot = nullptr; FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope); - if (var->value.special == ConstValSpecialStatic) { - mem_slot = &var->value; + if (var->value->special == ConstValSpecialStatic) { + mem_slot = var->value; } else if (fn_entry) { // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; } - bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; - bool is_volatile = (var->value.type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false; + bool is_const = (var->value->type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; + bool is_volatile = (var->value->type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false; if (mem_slot && mem_slot->special != ConstValSpecialRuntime) { ConstPtrMut ptr_mut; if (comptime_var_mem) { @@ -8794,11 +8795,11 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc assert(!comptime_var_mem); ptr_mut = ConstPtrMutRuntimeVar; } - return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type, ptr_mut, is_const, is_volatile); + return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value->type, ptr_mut, is_const, is_volatile); } else { ir_build_var_ptr_from(&ira->new_irb, instruction, var, is_const, is_volatile); - type_ensure_zero_bits_known(ira->codegen, var->value.type); - return get_pointer_to_type(ira->codegen, var->value.type, var->src_is_const); + type_ensure_zero_bits_known(ira->codegen, var->value->type); + return get_pointer_to_type(ira->codegen, var->value->type, var->src_is_const); } } @@ -12520,8 +12521,8 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry); fn_entry->child_scope = &fn_entry->fndef_scope->base; - assert(var->value.type->id == TypeTableEntryIdMaybe); - TypeTableEntry *src_fn_type = var->value.type->data.maybe.child_type; + assert(var->value->type->id == TypeTableEntryIdMaybe); + TypeTableEntry *src_fn_type = var->value->type->data.maybe.child_type; assert(src_fn_type->id == TypeTableEntryIdFn); FnTypeId new_fn_type = src_fn_type->data.fn.fn_type_id; diff --git a/src/parseh.cpp b/src/parseh.cpp index 5c641e4660..ca7d9e1cd8 100644 --- a/src/parseh.cpp +++ b/src/parseh.cpp @@ -1235,7 +1235,7 @@ static void process_symbol_macros(Context *c) { // variable is non-null and calls it. if (existing_tld->id == TldIdVar) { TldVar *tld_var = (TldVar *)existing_tld; - TypeTableEntry *var_type = tld_var->var->value.type; + TypeTableEntry *var_type = tld_var->var->value->type; if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) { TypeTableEntry *child_type = var_type->data.maybe.child_type; if (child_type->id == TypeTableEntryIdFn) { diff --git a/test/cases/array.zig b/test/cases/array.zig index 814c360eca..3b91efbc20 100644 --- a/test/cases/array.zig +++ b/test/cases/array.zig @@ -72,24 +72,23 @@ fn nestedArrays() { } -// TODO -//var s_array: [8]Sub = undefined; -//const Sub = struct { -// b: u8, -//}; -//const Str = struct { -// a: []Sub, -//}; -//fn setGlobalVarArrayViaSliceEmbeddedInStruct() { -// @setFnTest(this); -// -// var s = Str { .a = s_array[0...]}; -// -// s.a[0].b = 1; -// s.a[1].b = 2; -// s.a[2].b = 3; -// -// assert(s_array[0].b == 1); -// assert(s_array[1].b == 2); -// assert(s_array[2].b == 3); -//} +var s_array: [8]Sub = undefined; +const Sub = struct { + b: u8, +}; +const Str = struct { + a: []Sub, +}; +fn setGlobalVarArrayViaSliceEmbeddedInStruct() { + @setFnTest(this); + + var s = Str { .a = s_array[0...]}; + + s.a[0].b = 1; + s.a[1].b = 2; + s.a[2].b = 3; + + assert(s_array[0].b == 1); + assert(s_array[1].b == 2); + assert(s_array[2].b == 3); +}