From 6de33ded81981554ccffc3ecbfcd5b0f628cf502 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 23 Apr 2017 13:22:36 -0400 Subject: [PATCH] make undefined as a constant value lazy closes #268 --- src/all_types.hpp | 12 +++++- src/analyze.cpp | 76 ++++++++++++++++++++-------------- src/analyze.hpp | 5 ++- src/ast_render.cpp | 9 ++-- src/ast_render.hpp | 4 +- src/codegen.cpp | 13 ++++-- src/ir.cpp | 101 +++++++++++++++++++++++++-------------------- src/ir.hpp | 2 +- src/ir_print.cpp | 6 ++- src/ir_print.hpp | 2 +- src/main.cpp | 2 +- 11 files changed, 139 insertions(+), 93 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index e0f3e3961bc7..8608c11b1159 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -98,9 +98,17 @@ struct ConstStructValue { ConstParent parent; }; +enum ConstArraySpecial { + ConstArraySpecialNone, + ConstArraySpecialUndef, +}; + struct ConstArrayValue { - ConstExprValue *elements; - ConstParent parent; + ConstArraySpecial special; + struct { + ConstExprValue *elements; + ConstParent parent; + } s_none; }; enum ConstPtrSpecial { diff --git a/src/analyze.cpp b/src/analyze.cpp index b2ef1b64e8e8..d754535163bd 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2727,7 +2727,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ if (g->verbose) { fprintf(stderr, "{ // (analyzed)\n"); - ir_print(stderr, &fn_table_entry->analyzed_executable, 4); + ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4); fprintf(stderr, "}\n"); } @@ -2766,9 +2766,9 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { } if (g->verbose) { fprintf(stderr, "\n"); - ast_render(stderr, fn_table_entry->body_node, 4); + ast_render(g, stderr, fn_table_entry->body_node, 4); fprintf(stderr, "\n{ // (IR)\n"); - ir_print(stderr, &fn_table_entry->ir_executable, 4); + ir_print(g, stderr, &fn_table_entry->ir_executable, 4); fprintf(stderr, "}\n"); } @@ -3355,10 +3355,10 @@ bool type_requires_comptime(TypeTableEntry *type_entry) { void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { const_val->special = ConstValSpecialStatic; const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str)); - const_val->data.x_array.elements = allocate(buf_len(str)); + const_val->data.x_array.s_none.elements = allocate(buf_len(str)); for (size_t i = 0; i < buf_len(str); i += 1) { - ConstExprValue *this_char = &const_val->data.x_array.elements[i]; + ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i]; this_char->special = ConstValSpecialStatic; this_char->type = g->builtin_types.entry_u8; bignum_init_unsigned(&this_char->data.x_bignum, (uint8_t)buf_ptr(str)[i]); @@ -3377,14 +3377,14 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { ConstExprValue *array_val = allocate(1); array_val->special = ConstValSpecialStatic; array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null); - array_val->data.x_array.elements = allocate(len_with_null); + array_val->data.x_array.s_none.elements = allocate(len_with_null); for (size_t i = 0; i < buf_len(str); i += 1) { - ConstExprValue *this_char = &array_val->data.x_array.elements[i]; + ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i]; this_char->special = ConstValSpecialStatic; this_char->type = g->builtin_types.entry_u8; bignum_init_unsigned(&this_char->data.x_bignum, (uint8_t)buf_ptr(str)[i]); } - ConstExprValue *null_char = &array_val->data.x_array.elements[len_with_null - 1]; + ConstExprValue *null_char = &array_val->data.x_array.s_none.elements[len_with_null - 1]; null_char->special = ConstValSpecialStatic; null_char->type = g->builtin_types.entry_u8; bignum_init_unsigned(&null_char->data.x_bignum, 0); @@ -3564,19 +3564,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { TypeTableEntry *wanted_type = const_val->type; if (wanted_type->id == TypeTableEntryIdArray) { const_val->special = ConstValSpecialStatic; - size_t elem_count = wanted_type->data.array.len; - const_val->data.x_array.elements = allocate(elem_count); - for (size_t i = 0; i < elem_count; i += 1) { - ConstExprValue *element_val = &const_val->data.x_array.elements[i]; - element_val->type = wanted_type->data.array.child_type; - init_const_undefined(g, element_val); - ConstParent *parent = get_const_val_parent(element_val); - if (parent != nullptr) { - parent->id = ConstParentIdArray; - parent->data.p_array.array_val = const_val; - parent->data.p_array.elem_index = i; - } - } + const_val->data.x_array.special = ConstArraySpecialUndef; } else if (wanted_type->id == TypeTableEntryIdStruct) { ensure_complete_type(g, wanted_type); @@ -3588,7 +3576,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { field_val->type = wanted_type->data.structure.fields[i].type_entry; assert(field_val->type); init_const_undefined(g, field_val); - ConstParent *parent = get_const_val_parent(field_val); + ConstParent *parent = get_const_val_parent(g, field_val); if (parent != nullptr) { parent->id = ConstParentIdStruct; parent->data.p_struct.struct_val = const_val; @@ -3802,7 +3790,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue * } } -void render_const_value(Buf *buf, ConstExprValue *const_val) { +void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { switch (const_val->special) { case ConstValSpecialRuntime: buf_appendf(buf, "(runtime value)"); @@ -3872,7 +3860,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { case ConstPtrSpecialRef: case ConstPtrSpecialBaseStruct: buf_appendf(buf, "&"); - render_const_value(buf, const_ptr_pointee(const_val)); + render_const_value(g, buf, const_ptr_pointee(g, const_val)); return; case ConstPtrSpecialBaseArray: if (const_val->data.x_ptr.data.base_array.is_cstr) { @@ -3880,7 +3868,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { return; } else { buf_appendf(buf, "&"); - render_const_value(buf, const_ptr_pointee(const_val)); + render_const_value(g, buf, const_ptr_pointee(g, const_val)); return; } case ConstPtrSpecialHardCodedAddr: @@ -3910,6 +3898,11 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { TypeTableEntry *child_type = type_entry->data.array.child_type; uint64_t len = type_entry->data.array.len; + if (const_val->data.x_array.special == ConstArraySpecialUndef) { + buf_append_str(buf, "undefined"); + return; + } + // if it's []u8, assume UTF-8 and output a string if (child_type->id == TypeTableEntryIdInt && child_type->data.integral.bit_count == 8 && @@ -3917,7 +3910,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { { buf_append_char(buf, '"'); for (uint64_t i = 0; i < len; i += 1) { - ConstExprValue *child_value = &const_val->data.x_array.elements[i]; + ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i]; uint64_t big_c = child_value->data.x_bignum.data.x_uint; assert(big_c <= UINT8_MAX); uint8_t c = (uint8_t)big_c; @@ -3935,8 +3928,8 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { for (uint64_t i = 0; i < len; i += 1) { if (i != 0) buf_appendf(buf, ","); - ConstExprValue *child_value = &const_val->data.x_array.elements[i]; - render_const_value(buf, child_value); + ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i]; + render_const_value(g, buf, child_value); } buf_appendf(buf, "}"); return; @@ -3954,7 +3947,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) { case TypeTableEntryIdMaybe: { if (const_val->data.x_maybe) { - render_const_value(buf, const_val->data.x_maybe); + render_const_value(g, buf, const_val->data.x_maybe); } else { buf_appendf(buf, "null"); } @@ -4167,11 +4160,32 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { zig_unreachable(); } -ConstParent *get_const_val_parent(ConstExprValue *value) { +void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { + assert(const_val->type->id == TypeTableEntryIdArray); + if (const_val->data.x_array.special == ConstArraySpecialUndef) { + const_val->data.x_array.special = ConstArraySpecialNone; + size_t elem_count = const_val->type->data.array.len; + const_val->data.x_array.s_none.elements = allocate(elem_count); + for (size_t i = 0; i < elem_count; i += 1) { + ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i]; + element_val->type = const_val->type->data.array.child_type; + init_const_undefined(g, element_val); + ConstParent *parent = get_const_val_parent(g, element_val); + if (parent != nullptr) { + parent->id = ConstParentIdArray; + parent->data.p_array.array_val = const_val; + parent->data.p_array.elem_index = i; + } + } + } +} + +ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) { assert(value->type); TypeTableEntry *type_entry = value->type; if (type_entry->id == TypeTableEntryIdArray) { - return &value->data.x_array.parent; + expand_undef_array(g, value); + return &value->data.x_array.s_none.parent; } else if (type_entry->id == TypeTableEntryIdStruct) { return &value->data.x_struct.parent; } diff --git a/src/analyze.hpp b/src/analyze.hpp index f885b2711f79..f42c742d99b4 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -84,7 +84,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue * int64_t min_signed_val(TypeTableEntry *type_entry); uint64_t max_unsigned_val(TypeTableEntry *type_entry); -void render_const_value(Buf *buf, ConstExprValue *const_val); +void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val); void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entry, VariableTableEntry **arg_vars); void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_type_node); @@ -145,8 +145,9 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_ void init_const_undefined(CodeGen *g, ConstExprValue *const_val); TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits); -ConstParent *get_const_val_parent(ConstExprValue *value); +ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value); FnTableEntry *get_extern_panic_fn(CodeGen *g); TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type); +void expand_undef_array(CodeGen *g, ConstExprValue *const_val); #endif diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 3e939c43e5cc..37fb067067e6 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -273,6 +273,7 @@ void ast_print(FILE *f, AstNode *node, int indent) { struct AstRender { + CodeGen *codegen; int indent; int indent_size; FILE *f; @@ -924,8 +925,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { } -void ast_render(FILE *f, AstNode *node, int indent_size) { +void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size) { AstRender ar = {0}; + ar.codegen = codegen; ar.f = f; ar.indent_size = indent_size; ar.indent = 0; @@ -1030,15 +1032,16 @@ 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(ar->codegen, &buf, var->value); fprintf(ar->f, "%s", buf_ptr(&buf)); } fprintf(ar->f, ";\n"); } -void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) { +void ast_render_decls(CodeGen *codegen, FILE *f, int indent_size, ImportTableEntry *import) { AstRender ar = {0}; + ar.codegen = codegen; ar.f = f; ar.indent_size = indent_size; ar.indent = 0; diff --git a/src/ast_render.hpp b/src/ast_render.hpp index 168aba1bab16..555ce77c7aed 100644 --- a/src/ast_render.hpp +++ b/src/ast_render.hpp @@ -15,11 +15,11 @@ void ast_print(FILE *f, AstNode *node, int indent); -void ast_render(FILE *f, AstNode *node, int indent_size); +void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size); const char *container_string(ContainerKind kind); -void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import); +void ast_render_decls(CodeGen *codegen, FILE *f, int indent_size, ImportTableEntry *import); #endif diff --git a/src/codegen.cpp b/src/codegen.cpp index 8e040e8ba537..c89e9ad7e641 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3051,7 +3051,8 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent } static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) { - ConstParent *parent = &array_const_val->data.x_array.parent; + expand_undef_array(g, array_const_val); + ConstParent *parent = &array_const_val->data.x_array.s_none.parent; LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); TypeTableEntry *usize = g->builtin_types.entry_usize; @@ -3283,9 +3284,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) { case TypeTableEntryIdArray: { uint64_t len = type_entry->data.array.len; + if (const_val->data.x_array.special == ConstArraySpecialUndef) { + return LLVMGetUndef(type_entry->type_ref); + } + LLVMValueRef *values = allocate(len); for (uint64_t i = 0; i < len; i += 1) { - ConstExprValue *elem_value = &const_val->data.x_array.elements[i]; + ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i]; values[i] = gen_const_val(g, elem_value); } return LLVMConstArray(LLVMTypeOf(values[0]), values, (unsigned)len); @@ -4577,11 +4582,11 @@ static void define_builtin_compile_vars(CodeGen *g) { ConstExprValue *const_val = allocate(1); const_val->special = ConstValSpecialStatic; const_val->type = get_array_type(g, str_type, g->link_libs.length); - const_val->data.x_array.elements = allocate(g->link_libs.length); + const_val->data.x_array.s_none.elements = allocate(g->link_libs.length); for (size_t i = 0; i < g->link_libs.length; i += 1) { Buf *link_lib_buf = g->link_libs.at(i); ConstExprValue *array_val = create_const_str_lit(g, link_lib_buf); - init_const_slice(g, &const_val->data.x_array.elements[i], array_val, 0, buf_len(link_lib_buf), true); + init_const_slice(g, &const_val->data.x_array.s_none.elements[i], array_val, 0, buf_len(link_lib_buf), true); } add_compile_var(g, "link_libs", const_val); diff --git a/src/ir.cpp b/src/ir.cpp index a555d771a74b..daf96cef9edb 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -56,7 +56,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type); -ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) { +ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { assert(const_val->type->id == TypeTableEntryIdPointer); assert(const_val->special == ConstValSpecialStatic); switch (const_val->data.x_ptr.special) { @@ -65,7 +65,8 @@ ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) { case ConstPtrSpecialRef: return const_val->data.x_ptr.data.ref.pointee; case ConstPtrSpecialBaseArray: - return &const_val->data.x_ptr.data.base_array.array_val->data.x_array.elements[ + expand_undef_array(g, const_val->data.x_ptr.data.base_array.array_val); + return &const_val->data.x_ptr.data.base_array.array_val->data.x_array.s_none.elements[ const_val->data.x_ptr.data.base_array.elem_index]; case ConstPtrSpecialBaseStruct: return &const_val->data.x_ptr.data.base_struct.struct_val->data.x_struct.fields[ @@ -5503,16 +5504,16 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); } -static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope *inner_scope) { +static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { if (inner_scope == nullptr || inner_scope == outer_scope) return false; - bool need_comma = render_instance_name_recursive(name, outer_scope, inner_scope->parent); + bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent); if (inner_scope->id != ScopeIdVarDecl) return need_comma; ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; if (need_comma) buf_append_char(name, ','); - render_const_value(name, var_scope->var->value); + render_const_value(codegen, name, var_scope->var->value); return true; } @@ -5529,7 +5530,7 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, name = buf_alloc(); buf_append_buf(name, &fn_entry->symbol_name); buf_appendf(name, "("); - render_instance_name_recursive(name, &fn_entry->fndef_scope->base, irb->exec->begin_scope); + render_instance_name_recursive(irb->codegen, name, &fn_entry->fndef_scope->base, irb->exec->begin_scope); buf_appendf(name, ")"); } else { name = buf_sprintf("(anonymous %s at %s:%zu:%zu)", container_string(kind), @@ -6523,9 +6524,9 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node if (codegen->verbose) { fprintf(stderr, "\nSource: "); - ast_render(stderr, node, 4); + ast_render(codegen, stderr, node, 4); fprintf(stderr, "\n{ // (IR)\n"); - ir_print(stderr, &ir_executable, 4); + ir_print(codegen, stderr, &ir_executable, 4); fprintf(stderr, "}\n"); } IrExecutable analyzed_executable = {0}; @@ -6544,7 +6545,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node if (codegen->verbose) { fprintf(stderr, "{ // (analyzed)\n"); - ir_print(stderr, &analyzed_executable, 4); + ir_print(codegen, stderr, &analyzed_executable, 4); fprintf(stderr, "}\n"); } @@ -7305,7 +7306,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { - ConstExprValue *pointee = const_ptr_pointee(&ptr->value); + ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &ptr->value); if (pointee->special != ConstValSpecialRuntime) { IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, source_instruction->source_node, child_type); @@ -7441,12 +7442,17 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; + expand_undef_array(ira->codegen, array_val); size_t len = len_field->data.x_bignum.data.x_uint; Buf *result = buf_alloc(); buf_resize(result, len); for (size_t i = 0; i < len; i += 1) { size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; - ConstExprValue *char_val = &array_val->data.x_array.elements[new_index]; + ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index]; + if (char_val->special == ConstValSpecialUndef) { + ir_add_error(ira, casted_value, buf_sprintf("use of undefined value")); + return nullptr; + } uint64_t big_c = char_val->data.x_bignum.data.x_uint; assert(big_c <= UINT8_MAX); uint8_t c = (uint8_t)big_c; @@ -8007,17 +8013,19 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * out_val->data.x_ptr.data.base_array.array_val = out_array_val; out_val->data.x_ptr.data.base_array.elem_index = 0; } - out_array_val->data.x_array.elements = allocate(new_len); + out_array_val->data.x_array.s_none.elements = allocate(new_len); + + expand_undef_array(ira->codegen, op1_array_val); size_t next_index = 0; for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { - out_array_val->data.x_array.elements[next_index] = op1_array_val->data.x_array.elements[i]; + out_array_val->data.x_array.s_none.elements[next_index] = op1_array_val->data.x_array.s_none.elements[i]; } for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { - out_array_val->data.x_array.elements[next_index] = op2_array_val->data.x_array.elements[i]; + out_array_val->data.x_array.s_none.elements[next_index] = op2_array_val->data.x_array.s_none.elements[i]; } if (next_index < new_len) { - ConstExprValue *null_byte = &out_array_val->data.x_array.elements[next_index]; + ConstExprValue *null_byte = &out_array_val->data.x_array.s_none.elements[next_index]; init_const_unsigned_negative(null_byte, child_type, 0, false); next_index += 1; } @@ -8061,12 +8069,14 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); uint64_t new_array_len = array_len.data.x_uint; - out_val->data.x_array.elements = allocate(new_array_len); + out_val->data.x_array.s_none.elements = allocate(new_array_len); + + expand_undef_array(ira->codegen, array_val); uint64_t i = 0; for (uint64_t x = 0; x < mult_amt; x += 1) { for (uint64_t y = 0; y < old_array_len; y += 1) { - out_val->data.x_array.elements[i] = array_val->data.x_array.elements[y]; + out_val->data.x_array.s_none.elements[i] = array_val->data.x_array.s_none.elements[y]; i += 1; } } @@ -8848,7 +8858,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp // one of the ptr instructions if (instr_is_comptime(value)) { - ConstExprValue *pointee = const_ptr_pointee(&value->value); + ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); if (pointee->type == child_type) { ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); *out_val = *pointee; @@ -9222,7 +9232,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); if (!ptr_val) return ira->codegen->builtin_types.entry_invalid; - ConstExprValue *args_val = const_ptr_pointee(ptr_val); + ConstExprValue *args_val = const_ptr_pointee(ira->codegen, ptr_val); size_t start = args_val->data.x_arg_tuple.start_index; size_t end = args_val->data.x_arg_tuple.end_index; ConstExprValue *elem_index_val = ir_resolve_const(ira, elem_index, UndefBad); @@ -9276,7 +9286,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc ConstExprValue *array_ptr_val; if (array_ptr->value.special != ConstValSpecialRuntime && array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar && - (array_ptr_val = const_ptr_pointee(&array_ptr->value)) && + (array_ptr_val = const_ptr_pointee(ira->codegen, &array_ptr->value)) && array_ptr_val->special != ConstValSpecialRuntime && (array_type->id != TypeTableEntryIdPointer || array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) @@ -9431,7 +9441,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field return ira->codegen->builtin_types.entry_invalid; if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { - ConstExprValue *struct_val = const_ptr_pointee(ptr_val); + ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val); ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index]; TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type, is_const, is_volatile, 0, 0); @@ -9565,7 +9575,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru return ira->codegen->builtin_types.entry_invalid; assert(container_ptr->value.type->id == TypeTableEntryIdPointer); - ConstExprValue *child_val = const_ptr_pointee(container_ptr_val); + ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); if (buf_eql_str(field_name, "len")) { ConstExprValue *len_val = allocate(1); @@ -9594,7 +9604,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru assert(ptr_type->id == TypeTableEntryIdPointer); child_type = ptr_type->data.pointer.child_type; } else if (container_ptr->value.type->id == TypeTableEntryIdPointer) { - ConstExprValue *child_val = const_ptr_pointee(container_ptr_val); + ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); child_type = child_val->data.x_type; } else { zig_unreachable(); @@ -9688,7 +9698,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru if (!container_ptr_val) return ira->codegen->builtin_types.entry_invalid; - ConstExprValue *namespace_val = const_ptr_pointee(container_ptr_val); + ConstExprValue *namespace_val = const_ptr_pointee(ira->codegen, container_ptr_val); assert(namespace_val->special == ConstValSpecialStatic); ImportTableEntry *namespace_import = namespace_val->data.x_import; @@ -9761,7 +9771,7 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru } if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { if (instr_is_comptime(casted_value)) { - ConstExprValue *dest_val = const_ptr_pointee(&ptr->value); + ConstExprValue *dest_val = const_ptr_pointee(ira->codegen, &ptr->value); if (dest_val->special != ConstValSpecialRuntime) { *dest_val = casted_value->value; if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { @@ -10630,7 +10640,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira, TypeTableEntry *target_type = target_value_ptr->value.type->data.pointer.child_type; ConstExprValue *pointee_val = nullptr; if (instr_is_comptime(target_value_ptr)) { - pointee_val = const_ptr_pointee(&target_value_ptr->value); + pointee_val = const_ptr_pointee(ira->codegen, &target_value_ptr->value); if (pointee_val->special == ConstValSpecialRuntime) pointee_val = nullptr; } @@ -10730,7 +10740,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr if (!target_value_ptr) return ira->codegen->builtin_types.entry_invalid; - ConstExprValue *pointee_val = const_ptr_pointee(target_val_ptr); + ConstExprValue *pointee_val = const_ptr_pointee(ira->codegen, target_val_ptr); if (pointee_val->type->id == TypeTableEntryIdEnum) { ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); out_val->data.x_ptr.special = ConstPtrSpecialRef; @@ -10982,7 +10992,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru for (size_t i = 0; i < instr_field_count; i += 1) { ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; - ConstParent *parent = get_const_val_parent(field_val); + ConstParent *parent = get_const_val_parent(ira->codegen, field_val); if (parent != nullptr) { parent->id = ConstParentIdStruct; parent->data.p_struct.field_index = i; @@ -11031,7 +11041,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira ConstExprValue const_val = {}; const_val.special = ConstValSpecialStatic; const_val.type = fixed_size_array_type; - const_val.data.x_array.elements = allocate(elem_count); + const_val.data.x_array.s_none.elements = allocate(elem_count); bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); @@ -11056,7 +11066,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira if (!elem_val) return ira->codegen->builtin_types.entry_invalid; - const_val.data.x_array.elements[i] = *elem_val; + const_val.data.x_array.s_none.elements[i] = *elem_val; } else { first_non_const_instruction = casted_arg; const_val.special = ConstValSpecialRuntime; @@ -11068,8 +11078,8 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); *out_val = const_val; for (size_t i = 0; i < elem_count; i += 1) { - ConstExprValue *elem_val = &out_val->data.x_array.elements[i]; - ConstParent *parent = get_const_val_parent(elem_val); + ConstExprValue *elem_val = &out_val->data.x_array.s_none.elements[i]; + ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); if (parent != nullptr) { parent->id = ConstParentIdArray; parent->data.p_array.array_val = out_val; @@ -11254,7 +11264,7 @@ static TypeTableEntry *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInst if (type_is_invalid(msg->value.type)) return ira->codegen->builtin_types.entry_invalid; buf_resize(&buf, 0); - render_const_value(&buf, &msg->value); + render_const_value(ira->codegen, &buf, &msg->value); const char *comma_str = (i != 0) ? ", " : ""; fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf)); } @@ -11526,7 +11536,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc if (ira->codegen->verbose) { fprintf(stderr, "\nC imports:\n"); fprintf(stderr, "-----------\n"); - ast_render_decls(stderr, 4, child_import); + ast_render_decls(ira->codegen, stderr, 4, child_import); } ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); @@ -11925,7 +11935,8 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi case ConstPtrSpecialBaseArray: { ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; - dest_elements = array_val->data.x_array.elements; + expand_undef_array(ira->codegen, array_val); + dest_elements = array_val->data.x_array.s_none.elements; start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; bound_end = array_val->type->data.array.len; break; @@ -12016,7 +12027,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi case ConstPtrSpecialBaseArray: { ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; - dest_elements = array_val->data.x_array.elements; + expand_undef_array(ira->codegen, array_val); + dest_elements = array_val->data.x_array.s_none.elements; dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; dest_end = array_val->type->data.array.len; break; @@ -12049,7 +12061,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi case ConstPtrSpecialBaseArray: { ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; - src_elements = array_val->data.x_array.elements; + expand_undef_array(ira->codegen, array_val); + src_elements = array_val->data.x_array.s_none.elements; src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; src_end = array_val->type->data.array.len; break; @@ -12138,12 +12151,12 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio size_t abs_offset; size_t rel_end; if (array_type->id == TypeTableEntryIdArray) { - array_val = const_ptr_pointee(&ptr_ptr->value); + array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value); abs_offset = 0; rel_end = array_type->data.array.len; parent_ptr = nullptr; } else if (array_type->id == TypeTableEntryIdPointer) { - parent_ptr = const_ptr_pointee(&ptr_ptr->value); + parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value); switch (parent_ptr->data.x_ptr.special) { case ConstPtrSpecialInvalid: case ConstPtrSpecialDiscard: @@ -12165,7 +12178,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio break; } } else if (is_slice(array_type)) { - ConstExprValue *slice_ptr = const_ptr_pointee(&ptr_ptr->value); + ConstExprValue *slice_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value); parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index]; @@ -12371,7 +12384,7 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); BigNum *op1_bignum = &casted_op1->value.data.x_bignum; BigNum *op2_bignum = &casted_op2->value.data.x_bignum; - ConstExprValue *pointee_val = const_ptr_pointee(&casted_result_ptr->value); + ConstExprValue *pointee_val = const_ptr_pointee(ira->codegen, &casted_result_ptr->value); BigNum *dest_bignum = &pointee_val->data.x_bignum; switch (instruction->op) { case IrOverflowOpAdd: @@ -12455,7 +12468,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); if (!ptr_val) return ira->codegen->builtin_types.entry_invalid; - ConstExprValue *err_union_val = const_ptr_pointee(ptr_val); + ConstExprValue *err_union_val = const_ptr_pointee(ira->codegen, ptr_val); if (err_union_val->special != ConstValSpecialRuntime) { ErrorTableEntry *err = err_union_val->data.x_err_union.err; assert(err); @@ -12498,7 +12511,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); if (!ptr_val) return ira->codegen->builtin_types.entry_invalid; - ConstExprValue *err_union_val = const_ptr_pointee(ptr_val); + ConstExprValue *err_union_val = const_ptr_pointee(ira->codegen, ptr_val); if (err_union_val->special != ConstValSpecialRuntime) { ErrorTableEntry *err = err_union_val->data.x_err_union.err; if (err != nullptr) { @@ -13248,7 +13261,7 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE if (codegen->verbose) { fprintf(stderr, "{\n"); - ir_print(stderr, &fn_entry->ir_executable, 4); + ir_print(codegen, stderr, &fn_entry->ir_executable, 4); fprintf(stderr, "}\n"); } diff --git a/src/ir.hpp b/src/ir.hpp index 8df905e872c4..4a9de7e57415 100644 --- a/src/ir.hpp +++ b/src/ir.hpp @@ -22,7 +22,7 @@ TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutabl TypeTableEntry *expected_type, AstNode *expected_type_source_node); bool ir_has_side_effects(IrInstruction *instruction); -ConstExprValue *const_ptr_pointee(ConstExprValue *const_val); +ConstExprValue *const_ptr_pointee(CodeGen *codegen, ConstExprValue *const_val); FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableEntry *var, Scope *parent_scope); diff --git a/src/ir_print.cpp b/src/ir_print.cpp index da00289e1708..d81584bddff9 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -10,6 +10,7 @@ #include "ir_print.hpp" struct IrPrint { + CodeGen *codegen; FILE *f; int indent; int indent_size; @@ -34,7 +35,7 @@ static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) { static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) { Buf buf = BUF_INIT; buf_resize(&buf, 0); - render_const_value(&buf, const_val); + render_const_value(irp->codegen, &buf, const_val); fprintf(irp->f, "%s", buf_ptr(&buf)); } @@ -1188,9 +1189,10 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { fprintf(irp->f, "\n"); } -void ir_print(FILE *f, IrExecutable *executable, int indent_size) { +void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size) { IrPrint ir_print = {}; IrPrint *irp = &ir_print; + irp->codegen = codegen; irp->f = f; irp->indent = indent_size; irp->indent_size = indent_size; diff --git a/src/ir_print.hpp b/src/ir_print.hpp index 7126b1e57f57..5ff33e306892 100644 --- a/src/ir_print.hpp +++ b/src/ir_print.hpp @@ -12,6 +12,6 @@ #include -void ir_print(FILE *f, IrExecutable *executable, int indent_size); +void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size); #endif diff --git a/src/main.cpp b/src/main.cpp index bf2dbcf683c9..5713847e4cd1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -609,7 +609,7 @@ int main(int argc, char **argv) { return EXIT_SUCCESS; } else if (cmd == CmdParseH) { codegen_parseh(g, &root_source_dir, &root_source_name, &root_source_code); - ast_render_decls(stdout, 4, g->root_import); + ast_render_decls(g, stdout, 4, g->root_import); return EXIT_SUCCESS; } else if (cmd == CmdTest) { codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code);