Commit 1195994880
Changed files (7)
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;
src/analyze.cpp
@@ -2085,7 +2085,7 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent
assert(value);
VariableTableEntry *variable_entry = allocate<VariableTableEntry>(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;
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));
}
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);
}
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<ConstExprValue>(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;
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) {
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);
+}