| author | |
| committer | |
| log | 1195994880b6a83e61807381df2721ac5256e876 |
| tree | 7ca30412d5c1ad7a3df15633ac3303b74b49eaf6 |
| parent | 25761570f1bb4413020ebbfc959caa3429453517 |
before, when we initialized a variable by copying the
initialization value, it made the internal const value
references point to a duplicate value, resulting in
a phony duplicate global value being updated instead of
the real on. now the behavior is as expected.
thanks to hoppetosse for pointing out this bug on IRC.7 files changed, 89 insertions(+), 89 deletions(-)
src/all_types.hpp+1-1| ... | @@ -1430,7 +1430,7 @@ enum VarLinkage { | ... | @@ -1430,7 +1430,7 @@ enum VarLinkage { |
| 1430 | 1430 | ||
| 1431 | struct VariableTableEntry { | 1431 | struct VariableTableEntry { |
| 1432 | Buf name; | 1432 | Buf name; |
| 1433 | ConstExprValue value; | 1433 | ConstExprValue *value; |
| 1434 | LLVMValueRef value_ref; | 1434 | LLVMValueRef value_ref; |
| 1435 | bool src_is_const; | 1435 | bool src_is_const; |
| 1436 | bool gen_is_const; | 1436 | bool gen_is_const; |
src/analyze.cpp+7-7| ... | @@ -2085,7 +2085,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent | ... | @@ -2085,7 +2085,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent |
| 2085 | assert(value); | 2085 | assert(value); |
| 2086 | 2086 | ||
| 2087 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); | 2087 | VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); |
| 2088 | variable_entry->value = *value; | 2088 | variable_entry->value = value; |
| 2089 | variable_entry->parent_scope = parent_scope; | 2089 | variable_entry->parent_scope = parent_scope; |
| 2090 | variable_entry->shadowable = false; | 2090 | variable_entry->shadowable = false; |
| 2091 | variable_entry->mem_slot_index = SIZE_MAX; | 2091 | variable_entry->mem_slot_index = SIZE_MAX; |
| ... | @@ -2101,21 +2101,21 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent | ... | @@ -2101,21 +2101,21 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent |
| 2101 | ErrorMsg *msg = add_node_error(g, source_node, | 2101 | ErrorMsg *msg = add_node_error(g, source_node, |
| 2102 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); | 2102 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); |
| 2103 | add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); | 2103 | add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); |
| 2104 | variable_entry->value.type = g->builtin_types.entry_invalid; | 2104 | variable_entry->value->type = g->builtin_types.entry_invalid; |
| 2105 | } else { | 2105 | } else { |
| 2106 | auto primitive_table_entry = g->primitive_type_table.maybe_get(name); | 2106 | auto primitive_table_entry = g->primitive_type_table.maybe_get(name); |
| 2107 | if (primitive_table_entry) { | 2107 | if (primitive_table_entry) { |
| 2108 | TypeTableEntry *type = primitive_table_entry->value; | 2108 | TypeTableEntry *type = primitive_table_entry->value; |
| 2109 | add_node_error(g, source_node, | 2109 | add_node_error(g, source_node, |
| 2110 | buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); | 2110 | buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); |
| 2111 | variable_entry->value.type = g->builtin_types.entry_invalid; | 2111 | variable_entry->value->type = g->builtin_types.entry_invalid; |
| 2112 | } else { | 2112 | } else { |
| 2113 | Tld *tld = find_decl(g, parent_scope, name); | 2113 | Tld *tld = find_decl(g, parent_scope, name); |
| 2114 | if (tld && tld->id != TldIdVar) { | 2114 | if (tld && tld->id != TldIdVar) { |
| 2115 | ErrorMsg *msg = add_node_error(g, source_node, | 2115 | ErrorMsg *msg = add_node_error(g, source_node, |
| 2116 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); | 2116 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); |
| 2117 | add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here")); | 2117 | add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here")); |
| 2118 | variable_entry->value.type = g->builtin_types.entry_invalid; | 2118 | variable_entry->value->type = g->builtin_types.entry_invalid; |
| 2119 | } | 2119 | } |
| 2120 | } | 2120 | } |
| 2121 | } | 2121 | } |
| ... | @@ -3181,7 +3181,7 @@ uint32_t fn_eval_hash(Scope* scope) { | ... | @@ -3181,7 +3181,7 @@ uint32_t fn_eval_hash(Scope* scope) { |
| 3181 | while (scope) { | 3181 | while (scope) { |
| 3182 | if (scope->id == ScopeIdVarDecl) { | 3182 | if (scope->id == ScopeIdVarDecl) { |
| 3183 | ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; | 3183 | ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; |
| 3184 | result += hash_const_val(&var_scope->var->value); | 3184 | result += hash_const_val(var_scope->var->value); |
| 3185 | } else if (scope->id == ScopeIdFnDef) { | 3185 | } else if (scope->id == ScopeIdFnDef) { |
| 3186 | ScopeFnDef *fn_scope = (ScopeFnDef *)scope; | 3186 | ScopeFnDef *fn_scope = (ScopeFnDef *)scope; |
| 3187 | result += hash_ptr(fn_scope->fn_entry); | 3187 | result += hash_ptr(fn_scope->fn_entry); |
| ... | @@ -3203,9 +3203,9 @@ bool fn_eval_eql(Scope *a, Scope *b) { | ... | @@ -3203,9 +3203,9 @@ bool fn_eval_eql(Scope *a, Scope *b) { |
| 3203 | if (a->id == ScopeIdVarDecl) { | 3203 | if (a->id == ScopeIdVarDecl) { |
| 3204 | ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a; | 3204 | ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a; |
| 3205 | ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b; | 3205 | ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b; |
| 3206 | if (a_var_scope->var->value.type != b_var_scope->var->value.type) | 3206 | if (a_var_scope->var->value->type != b_var_scope->var->value->type) |
| 3207 | return false; | 3207 | return false; |
| 3208 | if (!const_values_equal(&a_var_scope->var->value, &b_var_scope->var->value)) | 3208 | if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value)) |
| 3209 | return false; | 3209 | return false; |
| 3210 | } else if (a->id == ScopeIdFnDef) { | 3210 | } else if (a->id == ScopeIdFnDef) { |
| 3211 | ScopeFnDef *a_fn_scope = (ScopeFnDef *)a; | 3211 | ScopeFnDef *a_fn_scope = (ScopeFnDef *)a; |
src/ast_render.cpp+9-9| ... | @@ -964,26 +964,26 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { | ... | @@ -964,26 +964,26 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { |
| 964 | const char *extern_str = extern_string(var->linkage == VarLinkageExternal); | 964 | const char *extern_str = extern_string(var->linkage == VarLinkageExternal); |
| 965 | fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(name)); | 965 | fprintf(ar->f, "%s%s%s %s", visib_mod_str, extern_str, const_or_var, buf_ptr(name)); |
| 966 | 966 | ||
| 967 | if (var->value.type->id == TypeTableEntryIdNumLitFloat || | 967 | if (var->value->type->id == TypeTableEntryIdNumLitFloat || |
| 968 | var->value.type->id == TypeTableEntryIdNumLitInt || | 968 | var->value->type->id == TypeTableEntryIdNumLitInt || |
| 969 | var->value.type->id == TypeTableEntryIdMetaType) | 969 | var->value->type->id == TypeTableEntryIdMetaType) |
| 970 | { | 970 | { |
| 971 | // skip type | 971 | // skip type |
| 972 | } else { | 972 | } else { |
| 973 | fprintf(ar->f, ": %s", buf_ptr(&var->value.type->name)); | 973 | fprintf(ar->f, ": %s", buf_ptr(&var->value->type->name)); |
| 974 | } | 974 | } |
| 975 | 975 | ||
| 976 | if (var->value.special == ConstValSpecialRuntime) { | 976 | if (var->value->special == ConstValSpecialRuntime) { |
| 977 | fprintf(ar->f, ";\n"); | 977 | fprintf(ar->f, ";\n"); |
| 978 | return; | 978 | return; |
| 979 | } | 979 | } |
| 980 | 980 | ||
| 981 | fprintf(ar->f, " = "); | 981 | fprintf(ar->f, " = "); |
| 982 | 982 | ||
| 983 | if (var->value.special == ConstValSpecialStatic && | 983 | if (var->value->special == ConstValSpecialStatic && |
| 984 | var->value.type->id == TypeTableEntryIdMetaType) | 984 | var->value->type->id == TypeTableEntryIdMetaType) |
| 985 | { | 985 | { |
| 986 | TypeTableEntry *type_entry = var->value.data.x_type; | 986 | TypeTableEntry *type_entry = var->value->data.x_type; |
| 987 | if (type_entry->id == TypeTableEntryIdStruct) { | 987 | if (type_entry->id == TypeTableEntryIdStruct) { |
| 988 | const char *layout_str = layout_string(type_entry->data.structure.layout); | 988 | const char *layout_str = layout_string(type_entry->data.structure.layout); |
| 989 | fprintf(ar->f, "%sstruct {\n", layout_str); | 989 | fprintf(ar->f, "%sstruct {\n", layout_str); |
| ... | @@ -1022,7 +1022,7 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { | ... | @@ -1022,7 +1022,7 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) { |
| 1022 | } else { | 1022 | } else { |
| 1023 | Buf buf = BUF_INIT; | 1023 | Buf buf = BUF_INIT; |
| 1024 | buf_resize(&buf, 0); | 1024 | buf_resize(&buf, 0); |
| 1025 | render_const_value(&buf, &var->value); | 1025 | render_const_value(&buf, var->value); |
| 1026 | fprintf(ar->f, "%s", buf_ptr(&buf)); | 1026 | fprintf(ar->f, "%s", buf_ptr(&buf)); |
| 1027 | } | 1027 | } |
| 1028 | 1028 |
src/codegen.cpp+26-26| ... | @@ -1316,7 +1316,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, | ... | @@ -1316,7 +1316,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, |
| 1316 | { | 1316 | { |
| 1317 | VariableTableEntry *var = decl_var_instruction->var; | 1317 | VariableTableEntry *var = decl_var_instruction->var; |
| 1318 | 1318 | ||
| 1319 | if (!type_has_bits(var->value.type)) | 1319 | if (!type_has_bits(var->value->type)) |
| 1320 | return nullptr; | 1320 | return nullptr; |
| 1321 | 1321 | ||
| 1322 | if (var->ref_count == 0 && g->is_release_build) | 1322 | if (var->ref_count == 0 && g->is_release_build) |
| ... | @@ -1331,16 +1331,16 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, | ... | @@ -1331,16 +1331,16 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, |
| 1331 | have_init_expr = true; | 1331 | have_init_expr = true; |
| 1332 | 1332 | ||
| 1333 | if (have_init_expr) { | 1333 | if (have_init_expr) { |
| 1334 | assert(var->value.type == init_value->value.type); | 1334 | assert(var->value->type == init_value->value.type); |
| 1335 | gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value.type); | 1335 | gen_assign_raw(g, var->value_ref, ir_llvm_value(g, init_value), var->value->type); |
| 1336 | } else { | 1336 | } else { |
| 1337 | bool ignore_uninit = false; | 1337 | bool ignore_uninit = false; |
| 1338 | // handle runtime stack allocation | 1338 | // handle runtime stack allocation |
| 1339 | bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base); | 1339 | bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base); |
| 1340 | if (!ignore_uninit && want_safe) { | 1340 | if (!ignore_uninit && want_safe) { |
| 1341 | TypeTableEntry *usize = g->builtin_types.entry_usize; | 1341 | TypeTableEntry *usize = g->builtin_types.entry_usize; |
| 1342 | uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value.type->type_ref); | 1342 | uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref); |
| 1343 | uint64_t align_bytes = get_type_alignment(g, var->value.type); | 1343 | uint64_t align_bytes = get_type_alignment(g, var->value->type); |
| 1344 | 1344 | ||
| 1345 | // memset uninitialized memory to 0xa | 1345 | // memset uninitialized memory to 0xa |
| 1346 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); | 1346 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); |
| ... | @@ -1437,7 +1437,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir | ... | @@ -1437,7 +1437,7 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir |
| 1437 | 1437 | ||
| 1438 | static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { | 1438 | static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { |
| 1439 | VariableTableEntry *var = instruction->var; | 1439 | VariableTableEntry *var = instruction->var; |
| 1440 | if (type_has_bits(var->value.type)) { | 1440 | if (type_has_bits(var->value->type)) { |
| 1441 | assert(var->value_ref); | 1441 | assert(var->value_ref); |
| 1442 | return var->value_ref; | 1442 | return var->value_ref; |
| 1443 | } else { | 1443 | } else { |
| ... | @@ -3203,9 +3203,9 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -3203,9 +3203,9 @@ static void do_code_gen(CodeGen *g) { |
| 3203 | TldVar *tld_var = g->global_vars.at(i); | 3203 | TldVar *tld_var = g->global_vars.at(i); |
| 3204 | VariableTableEntry *var = tld_var->var; | 3204 | VariableTableEntry *var = tld_var->var; |
| 3205 | 3205 | ||
| 3206 | if (var->value.type->id == TypeTableEntryIdNumLitFloat) { | 3206 | if (var->value->type->id == TypeTableEntryIdNumLitFloat) { |
| 3207 | // Generate debug info for it but that's it. | 3207 | // Generate debug info for it but that's it. |
| 3208 | ConstExprValue *const_val = &var->value; | 3208 | ConstExprValue *const_val = var->value; |
| 3209 | assert(const_val->special != ConstValSpecialRuntime); | 3209 | assert(const_val->special != ConstValSpecialRuntime); |
| 3210 | TypeTableEntry *var_type = g->builtin_types.entry_f64; | 3210 | TypeTableEntry *var_type = g->builtin_types.entry_f64; |
| 3211 | LLVMValueRef init_val = LLVMConstReal(var_type->type_ref, const_val->data.x_bignum.data.x_float); | 3211 | 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) { | ... | @@ -3213,9 +3213,9 @@ static void do_code_gen(CodeGen *g) { |
| 3213 | continue; | 3213 | continue; |
| 3214 | } | 3214 | } |
| 3215 | 3215 | ||
| 3216 | if (var->value.type->id == TypeTableEntryIdNumLitInt) { | 3216 | if (var->value->type->id == TypeTableEntryIdNumLitInt) { |
| 3217 | // Generate debug info for it but that's it. | 3217 | // Generate debug info for it but that's it. |
| 3218 | ConstExprValue *const_val = &var->value; | 3218 | ConstExprValue *const_val = var->value; |
| 3219 | assert(const_val->special != ConstValSpecialRuntime); | 3219 | assert(const_val->special != ConstValSpecialRuntime); |
| 3220 | TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ? | 3220 | TypeTableEntry *var_type = const_val->data.x_bignum.is_negative ? |
| 3221 | g->builtin_types.entry_isize : g->builtin_types.entry_usize; | 3221 | g->builtin_types.entry_isize : g->builtin_types.entry_usize; |
| ... | @@ -3225,22 +3225,22 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -3225,22 +3225,22 @@ static void do_code_gen(CodeGen *g) { |
| 3225 | continue; | 3225 | continue; |
| 3226 | } | 3226 | } |
| 3227 | 3227 | ||
| 3228 | if (!type_has_bits(var->value.type)) | 3228 | if (!type_has_bits(var->value->type)) |
| 3229 | continue; | 3229 | continue; |
| 3230 | 3230 | ||
| 3231 | assert(var->decl_node); | 3231 | assert(var->decl_node); |
| 3232 | 3232 | ||
| 3233 | LLVMValueRef global_value; | 3233 | LLVMValueRef global_value; |
| 3234 | if (var->linkage == VarLinkageExternal) { | 3234 | if (var->linkage == VarLinkageExternal) { |
| 3235 | global_value = LLVMAddGlobal(g->module, var->value.type->type_ref, buf_ptr(&var->name)); | 3235 | global_value = LLVMAddGlobal(g->module, var->value->type->type_ref, buf_ptr(&var->name)); |
| 3236 | 3236 | ||
| 3237 | // TODO debug info for the extern variable | 3237 | // TODO debug info for the extern variable |
| 3238 | 3238 | ||
| 3239 | LLVMSetLinkage(global_value, LLVMExternalLinkage); | 3239 | LLVMSetLinkage(global_value, LLVMExternalLinkage); |
| 3240 | } else { | 3240 | } else { |
| 3241 | render_const_val(g, &var->value); | 3241 | render_const_val(g, var->value); |
| 3242 | render_const_val_global(g, &var->value, buf_ptr(&var->name)); | 3242 | render_const_val_global(g, var->value, buf_ptr(&var->name)); |
| 3243 | global_value = var->value.llvm_global; | 3243 | global_value = var->value->llvm_global; |
| 3244 | 3244 | ||
| 3245 | if (var->linkage == VarLinkageExport) { | 3245 | if (var->linkage == VarLinkageExport) { |
| 3246 | LLVMSetLinkage(global_value, LLVMExternalLinkage); | 3246 | LLVMSetLinkage(global_value, LLVMExternalLinkage); |
| ... | @@ -3249,11 +3249,11 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -3249,11 +3249,11 @@ static void do_code_gen(CodeGen *g) { |
| 3249 | LLVMSetSection(global_value, buf_ptr(tld_var->section_name)); | 3249 | LLVMSetSection(global_value, buf_ptr(tld_var->section_name)); |
| 3250 | } | 3250 | } |
| 3251 | LLVMSetAlignment(global_value, tld_var->alignment ? | 3251 | LLVMSetAlignment(global_value, tld_var->alignment ? |
| 3252 | tld_var->alignment : get_type_alignment(g, var->value.type)); | 3252 | tld_var->alignment : get_type_alignment(g, var->value->type)); |
| 3253 | 3253 | ||
| 3254 | // TODO debug info for function pointers | 3254 | // TODO debug info for function pointers |
| 3255 | if (var->gen_is_const && var->value.type->id != TypeTableEntryIdFn) { | 3255 | if (var->gen_is_const && var->value->type->id != TypeTableEntryIdFn) { |
| 3256 | gen_global_var(g, var, var->value.llvm_value, var->value.type); | 3256 | gen_global_var(g, var, var->value->llvm_value, var->value->type); |
| 3257 | } | 3257 | } |
| 3258 | } | 3258 | } |
| 3259 | 3259 | ||
| ... | @@ -3432,30 +3432,30 @@ static void do_code_gen(CodeGen *g) { | ... | @@ -3432,30 +3432,30 @@ static void do_code_gen(CodeGen *g) { |
| 3432 | for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) { | 3432 | for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) { |
| 3433 | VariableTableEntry *var = fn_table_entry->variable_list.at(var_i); | 3433 | VariableTableEntry *var = fn_table_entry->variable_list.at(var_i); |
| 3434 | 3434 | ||
| 3435 | if (!type_has_bits(var->value.type)) { | 3435 | if (!type_has_bits(var->value->type)) { |
| 3436 | continue; | 3436 | continue; |
| 3437 | } | 3437 | } |
| 3438 | if (ir_get_var_is_comptime(var)) | 3438 | if (ir_get_var_is_comptime(var)) |
| 3439 | continue; | 3439 | continue; |
| 3440 | if (type_requires_comptime(var->value.type)) | 3440 | if (type_requires_comptime(var->value->type)) |
| 3441 | continue; | 3441 | continue; |
| 3442 | 3442 | ||
| 3443 | if (var->src_arg_index == SIZE_MAX) { | 3443 | if (var->src_arg_index == SIZE_MAX) { |
| 3444 | var->value_ref = build_alloca(g, var->value.type, buf_ptr(&var->name)); | 3444 | var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name)); |
| 3445 | 3445 | ||
| 3446 | var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), | 3446 | var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), |
| 3447 | buf_ptr(&var->name), import->di_file, var->decl_node->line + 1, | 3447 | buf_ptr(&var->name), import->di_file, var->decl_node->line + 1, |
| 3448 | var->value.type->di_type, !g->strip_debug_symbols, 0); | 3448 | var->value->type->di_type, !g->strip_debug_symbols, 0); |
| 3449 | 3449 | ||
| 3450 | } else { | 3450 | } else { |
| 3451 | assert(var->gen_arg_index != SIZE_MAX); | 3451 | assert(var->gen_arg_index != SIZE_MAX); |
| 3452 | TypeTableEntry *gen_type; | 3452 | TypeTableEntry *gen_type; |
| 3453 | if (handle_is_ptr(var->value.type)) { | 3453 | if (handle_is_ptr(var->value->type)) { |
| 3454 | gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type; | 3454 | gen_type = fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index].type; |
| 3455 | var->value_ref = LLVMGetParam(fn, var->gen_arg_index); | 3455 | var->value_ref = LLVMGetParam(fn, var->gen_arg_index); |
| 3456 | } else { | 3456 | } else { |
| 3457 | gen_type = var->value.type; | 3457 | gen_type = var->value->type; |
| 3458 | var->value_ref = build_alloca(g, var->value.type, buf_ptr(&var->name)); | 3458 | var->value_ref = build_alloca(g, var->value->type, buf_ptr(&var->name)); |
| 3459 | } | 3459 | } |
| 3460 | if (var->decl_node) { | 3460 | if (var->decl_node) { |
| 3461 | var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope), | 3461 | 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) { | ... | @@ -3483,7 +3483,7 @@ static void do_code_gen(CodeGen *g) { |
| 3483 | assert(variable); | 3483 | assert(variable); |
| 3484 | assert(variable->value_ref); | 3484 | assert(variable->value_ref); |
| 3485 | 3485 | ||
| 3486 | if (!handle_is_ptr(variable->value.type)) { | 3486 | if (!handle_is_ptr(variable->value->type)) { |
| 3487 | clear_debug_source_node(g); | 3487 | clear_debug_source_node(g); |
| 3488 | LLVMBuildStore(g->builder, LLVMGetParam(fn, variable->gen_arg_index), variable->value_ref); | 3488 | LLVMBuildStore(g->builder, LLVMGetParam(fn, variable->gen_arg_index), variable->value_ref); |
| 3489 | } | 3489 | } |
src/ir.cpp+25-24| ... | @@ -3164,6 +3164,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco | ... | @@ -3164,6 +3164,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco |
| 3164 | variable_entry->mem_slot_index = SIZE_MAX; | 3164 | variable_entry->mem_slot_index = SIZE_MAX; |
| 3165 | variable_entry->is_comptime = is_comptime; | 3165 | variable_entry->is_comptime = is_comptime; |
| 3166 | variable_entry->src_arg_index = SIZE_MAX; | 3166 | variable_entry->src_arg_index = SIZE_MAX; |
| 3167 | variable_entry->value = allocate<ConstExprValue>(1); | ||
| 3167 | 3168 | ||
| 3168 | if (name) { | 3169 | if (name) { |
| 3169 | buf_init_from_buf(&variable_entry->name, name); | 3170 | buf_init_from_buf(&variable_entry->name, name); |
| ... | @@ -3173,21 +3174,21 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco | ... | @@ -3173,21 +3174,21 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco |
| 3173 | ErrorMsg *msg = add_node_error(codegen, node, | 3174 | ErrorMsg *msg = add_node_error(codegen, node, |
| 3174 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); | 3175 | buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); |
| 3175 | add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); | 3176 | add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); |
| 3176 | variable_entry->value.type = codegen->builtin_types.entry_invalid; | 3177 | variable_entry->value->type = codegen->builtin_types.entry_invalid; |
| 3177 | } else { | 3178 | } else { |
| 3178 | auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name); | 3179 | auto primitive_table_entry = codegen->primitive_type_table.maybe_get(name); |
| 3179 | if (primitive_table_entry) { | 3180 | if (primitive_table_entry) { |
| 3180 | TypeTableEntry *type = primitive_table_entry->value; | 3181 | TypeTableEntry *type = primitive_table_entry->value; |
| 3181 | add_node_error(codegen, node, | 3182 | add_node_error(codegen, node, |
| 3182 | buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); | 3183 | buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); |
| 3183 | variable_entry->value.type = codegen->builtin_types.entry_invalid; | 3184 | variable_entry->value->type = codegen->builtin_types.entry_invalid; |
| 3184 | } else { | 3185 | } else { |
| 3185 | Tld *tld = find_decl(codegen, parent_scope, name); | 3186 | Tld *tld = find_decl(codegen, parent_scope, name); |
| 3186 | if (tld && tld->id != TldIdVar) { | 3187 | if (tld && tld->id != TldIdVar) { |
| 3187 | ErrorMsg *msg = add_node_error(codegen, node, | 3188 | ErrorMsg *msg = add_node_error(codegen, node, |
| 3188 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); | 3189 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); |
| 3189 | add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); | 3190 | add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); |
| 3190 | variable_entry->value.type = codegen->builtin_types.entry_invalid; | 3191 | variable_entry->value->type = codegen->builtin_types.entry_invalid; |
| 3191 | } | 3192 | } |
| 3192 | } | 3193 | } |
| 3193 | } | 3194 | } |
| ... | @@ -4516,7 +4517,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod | ... | @@ -4516,7 +4517,7 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod |
| 4516 | // is inside var->child_scope | 4517 | // is inside var->child_scope |
| 4517 | 4518 | ||
| 4518 | if (!is_extern && !variable_declaration->expr) { | 4519 | if (!is_extern && !variable_declaration->expr) { |
| 4519 | var->value.type = irb->codegen->builtin_types.entry_invalid; | 4520 | var->value->type = irb->codegen->builtin_types.entry_invalid; |
| 4520 | add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); | 4521 | add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); |
| 4521 | return irb->codegen->invalid_instruction; | 4522 | return irb->codegen->invalid_instruction; |
| 4522 | } | 4523 | } |
| ... | @@ -5387,7 +5388,7 @@ static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope | ... | @@ -5387,7 +5388,7 @@ static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope |
| 5387 | ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; | 5388 | ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; |
| 5388 | if (need_comma) | 5389 | if (need_comma) |
| 5389 | buf_append_char(name, ','); | 5390 | buf_append_char(name, ','); |
| 5390 | render_const_value(name, &var_scope->var->value); | 5391 | render_const_value(name, var_scope->var->value); |
| 5391 | return true; | 5392 | return true; |
| 5392 | } | 5393 | } |
| 5393 | 5394 | ||
| ... | @@ -7827,8 +7828,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -7827,8 +7828,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 7827 | 7828 | ||
| 7828 | IrInstruction *init_value = decl_var_instruction->init_value->other; | 7829 | IrInstruction *init_value = decl_var_instruction->init_value->other; |
| 7829 | if (type_is_invalid(init_value->value.type)) { | 7830 | if (type_is_invalid(init_value->value.type)) { |
| 7830 | var->value.type = ira->codegen->builtin_types.entry_invalid; | 7831 | var->value->type = ira->codegen->builtin_types.entry_invalid; |
| 7831 | return var->value.type; | 7832 | return var->value->type; |
| 7832 | } | 7833 | } |
| 7833 | 7834 | ||
| 7834 | AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration; | 7835 | AstNodeVariableDeclaration *variable_declaration = &var->decl_node->data.variable_declaration; |
| ... | @@ -7844,8 +7845,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -7844,8 +7845,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 7844 | TypeTableEntry *proposed_type = ir_resolve_type(ira, var_type); | 7845 | TypeTableEntry *proposed_type = ir_resolve_type(ira, var_type); |
| 7845 | explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); | 7846 | explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); |
| 7846 | if (type_is_invalid(explicit_type)) { | 7847 | if (type_is_invalid(explicit_type)) { |
| 7847 | var->value.type = ira->codegen->builtin_types.entry_invalid; | 7848 | var->value->type = ira->codegen->builtin_types.entry_invalid; |
| 7848 | return var->value.type; | 7849 | return var->value->type; |
| 7849 | } | 7850 | } |
| 7850 | } | 7851 | } |
| 7851 | 7852 | ||
| ... | @@ -7906,8 +7907,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -7906,8 +7907,8 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 7906 | break; | 7907 | break; |
| 7907 | } | 7908 | } |
| 7908 | 7909 | ||
| 7909 | var->value.type = result_type; | 7910 | var->value->type = result_type; |
| 7910 | assert(var->value.type); | 7911 | assert(var->value->type); |
| 7911 | 7912 | ||
| 7912 | if (type_is_invalid(result_type)) { | 7913 | if (type_is_invalid(result_type)) { |
| 7913 | decl_var_instruction->base.other = &decl_var_instruction->base; | 7914 | decl_var_instruction->base.other = &decl_var_instruction->base; |
| ... | @@ -7930,7 +7931,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc | ... | @@ -7930,7 +7931,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc |
| 7930 | } else if (is_comptime) { | 7931 | } else if (is_comptime) { |
| 7931 | ir_add_error(ira, &decl_var_instruction->base, | 7932 | ir_add_error(ira, &decl_var_instruction->base, |
| 7932 | buf_sprintf("cannot store runtime value in compile time variable")); | 7933 | buf_sprintf("cannot store runtime value in compile time variable")); |
| 7933 | var->value.type = ira->codegen->builtin_types.entry_invalid; | 7934 | var->value->type = ira->codegen->builtin_types.entry_invalid; |
| 7934 | return ira->codegen->builtin_types.entry_invalid; | 7935 | return ira->codegen->builtin_types.entry_invalid; |
| 7935 | } | 7936 | } |
| 7936 | 7937 | ||
| ... | @@ -8766,24 +8767,24 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP | ... | @@ -8766,24 +8767,24 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP |
| 8766 | static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | 8767 | static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 8767 | VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr) | 8768 | VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr) |
| 8768 | { | 8769 | { |
| 8769 | assert(var->value.type); | 8770 | assert(var->value->type); |
| 8770 | if (type_is_invalid(var->value.type)) | 8771 | if (type_is_invalid(var->value->type)) |
| 8771 | return var->value.type; | 8772 | return var->value->type; |
| 8772 | 8773 | ||
| 8773 | bool comptime_var_mem = ir_get_var_is_comptime(var); | 8774 | bool comptime_var_mem = ir_get_var_is_comptime(var); |
| 8774 | 8775 | ||
| 8775 | ConstExprValue *mem_slot = nullptr; | 8776 | ConstExprValue *mem_slot = nullptr; |
| 8776 | FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope); | 8777 | FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope); |
| 8777 | if (var->value.special == ConstValSpecialStatic) { | 8778 | if (var->value->special == ConstValSpecialStatic) { |
| 8778 | mem_slot = &var->value; | 8779 | mem_slot = var->value; |
| 8779 | } else if (fn_entry) { | 8780 | } else if (fn_entry) { |
| 8780 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. | 8781 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. |
| 8781 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) | 8782 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) |
| 8782 | mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; | 8783 | mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; |
| 8783 | } | 8784 | } |
| 8784 | 8785 | ||
| 8785 | bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; | 8786 | bool is_const = (var->value->type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; |
| 8786 | bool is_volatile = (var->value.type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false; | 8787 | bool is_volatile = (var->value->type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false; |
| 8787 | if (mem_slot && mem_slot->special != ConstValSpecialRuntime) { | 8788 | if (mem_slot && mem_slot->special != ConstValSpecialRuntime) { |
| 8788 | ConstPtrMut ptr_mut; | 8789 | ConstPtrMut ptr_mut; |
| 8789 | if (comptime_var_mem) { | 8790 | if (comptime_var_mem) { |
| ... | @@ -8794,11 +8795,11 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -8794,11 +8795,11 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc |
| 8794 | assert(!comptime_var_mem); | 8795 | assert(!comptime_var_mem); |
| 8795 | ptr_mut = ConstPtrMutRuntimeVar; | 8796 | ptr_mut = ConstPtrMutRuntimeVar; |
| 8796 | } | 8797 | } |
| 8797 | return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type, ptr_mut, is_const, is_volatile); | 8798 | return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value->type, ptr_mut, is_const, is_volatile); |
| 8798 | } else { | 8799 | } else { |
| 8799 | ir_build_var_ptr_from(&ira->new_irb, instruction, var, is_const, is_volatile); | 8800 | ir_build_var_ptr_from(&ira->new_irb, instruction, var, is_const, is_volatile); |
| 8800 | type_ensure_zero_bits_known(ira->codegen, var->value.type); | 8801 | type_ensure_zero_bits_known(ira->codegen, var->value->type); |
| 8801 | return get_pointer_to_type(ira->codegen, var->value.type, var->src_is_const); | 8802 | return get_pointer_to_type(ira->codegen, var->value->type, var->src_is_const); |
| 8802 | } | 8803 | } |
| 8803 | } | 8804 | } |
| 8804 | 8805 | ||
| ... | @@ -12520,8 +12521,8 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE | ... | @@ -12520,8 +12521,8 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE |
| 12520 | fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry); | 12521 | fn_entry->fndef_scope = create_fndef_scope(nullptr, parent_scope, fn_entry); |
| 12521 | fn_entry->child_scope = &fn_entry->fndef_scope->base; | 12522 | fn_entry->child_scope = &fn_entry->fndef_scope->base; |
| 12522 | 12523 | ||
| 12523 | assert(var->value.type->id == TypeTableEntryIdMaybe); | 12524 | assert(var->value->type->id == TypeTableEntryIdMaybe); |
| 12524 | TypeTableEntry *src_fn_type = var->value.type->data.maybe.child_type; | 12525 | TypeTableEntry *src_fn_type = var->value->type->data.maybe.child_type; |
| 12525 | assert(src_fn_type->id == TypeTableEntryIdFn); | 12526 | assert(src_fn_type->id == TypeTableEntryIdFn); |
| 12526 | 12527 | ||
| 12527 | FnTypeId new_fn_type = src_fn_type->data.fn.fn_type_id; | 12528 | FnTypeId new_fn_type = src_fn_type->data.fn.fn_type_id; |
src/parseh.cpp+1-1| ... | @@ -1235,7 +1235,7 @@ static void process_symbol_macros(Context *c) { | ... | @@ -1235,7 +1235,7 @@ static void process_symbol_macros(Context *c) { |
| 1235 | // variable is non-null and calls it. | 1235 | // variable is non-null and calls it. |
| 1236 | if (existing_tld->id == TldIdVar) { | 1236 | if (existing_tld->id == TldIdVar) { |
| 1237 | TldVar *tld_var = (TldVar *)existing_tld; | 1237 | TldVar *tld_var = (TldVar *)existing_tld; |
| 1238 | TypeTableEntry *var_type = tld_var->var->value.type; | 1238 | TypeTableEntry *var_type = tld_var->var->value->type; |
| 1239 | if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) { | 1239 | if (var_type->id == TypeTableEntryIdMaybe && !tld_var->var->src_is_const) { |
| 1240 | TypeTableEntry *child_type = var_type->data.maybe.child_type; | 1240 | TypeTableEntry *child_type = var_type->data.maybe.child_type; |
| 1241 | if (child_type->id == TypeTableEntryIdFn) { | 1241 | if (child_type->id == TypeTableEntryIdFn) { |
test/cases/array.zig+20-21| ... | @@ -72,24 +72,23 @@ fn nestedArrays() { | ... | @@ -72,24 +72,23 @@ fn nestedArrays() { |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | 74 | ||
| 75 | // TODO | 75 | var s_array: [8]Sub = undefined; |
| 76 | //var s_array: [8]Sub = undefined; | 76 | const Sub = struct { |
| 77 | //const Sub = struct { | 77 | b: u8, |
| 78 | // b: u8, | 78 | }; |
| 79 | //}; | 79 | const Str = struct { |
| 80 | //const Str = struct { | 80 | a: []Sub, |
| 81 | // a: []Sub, | 81 | }; |
| 82 | //}; | 82 | fn setGlobalVarArrayViaSliceEmbeddedInStruct() { |
| 83 | //fn setGlobalVarArrayViaSliceEmbeddedInStruct() { | 83 | @setFnTest(this); |
| 84 | // @setFnTest(this); | 84 | |
| 85 | // | 85 | var s = Str { .a = s_array[0...]}; |
| 86 | // var s = Str { .a = s_array[0...]}; | 86 | |
| 87 | // | 87 | s.a[0].b = 1; |
| 88 | // s.a[0].b = 1; | 88 | s.a[1].b = 2; |
| 89 | // s.a[1].b = 2; | 89 | s.a[2].b = 3; |
| 90 | // s.a[2].b = 3; | 90 | |
| 91 | // | 91 | assert(s_array[0].b == 1); |
| 92 | // assert(s_array[0].b == 1); | 92 | assert(s_array[1].b == 2); |
| 93 | // assert(s_array[1].b == 2); | 93 | assert(s_array[2].b == 3); |
| 94 | // assert(s_array[2].b == 3); | 94 | } |
| 95 | //} |