authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-23 13:22:36-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-23 14:34:40-04:00
log6de33ded81981554ccffc3ecbfcd5b0f628cf502
tree520cfac3890b90d5357866a6c4b6e7e9509ee735
parent2ed47070efa5933365da724e79f6ed87d603ee27

make undefined as a constant value lazy

closes #268

11 files changed, 139 insertions(+), 93 deletions(-)

src/all_types.hpp+10-2
...@@ -98,9 +98,17 @@ struct ConstStructValue {...@@ -98,9 +98,17 @@ struct ConstStructValue {
98 ConstParent parent;98 ConstParent parent;
99};99};
100100
101enum ConstArraySpecial {
102 ConstArraySpecialNone,
103 ConstArraySpecialUndef,
104};
105
101struct ConstArrayValue {106struct ConstArrayValue {
102 ConstExprValue *elements;107 ConstArraySpecial special;
103 ConstParent parent;108 struct {
109 ConstExprValue *elements;
110 ConstParent parent;
111 } s_none;
104};112};
105113
106enum ConstPtrSpecial {114enum ConstPtrSpecial {
src/analyze.cpp+45-31
...@@ -2727,7 +2727,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ...@@ -2727,7 +2727,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ
27272727
2728 if (g->verbose) {2728 if (g->verbose) {
2729 fprintf(stderr, "{ // (analyzed)\n");2729 fprintf(stderr, "{ // (analyzed)\n");
2730 ir_print(stderr, &fn_table_entry->analyzed_executable, 4);2730 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
2731 fprintf(stderr, "}\n");2731 fprintf(stderr, "}\n");
2732 }2732 }
27332733
...@@ -2766,9 +2766,9 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -2766,9 +2766,9 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
2766 }2766 }
2767 if (g->verbose) {2767 if (g->verbose) {
2768 fprintf(stderr, "\n");2768 fprintf(stderr, "\n");
2769 ast_render(stderr, fn_table_entry->body_node, 4);2769 ast_render(g, stderr, fn_table_entry->body_node, 4);
2770 fprintf(stderr, "\n{ // (IR)\n");2770 fprintf(stderr, "\n{ // (IR)\n");
2771 ir_print(stderr, &fn_table_entry->ir_executable, 4);2771 ir_print(g, stderr, &fn_table_entry->ir_executable, 4);
2772 fprintf(stderr, "}\n");2772 fprintf(stderr, "}\n");
2773 }2773 }
27742774
...@@ -3355,10 +3355,10 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {...@@ -3355,10 +3355,10 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
3355void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {3355void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
3356 const_val->special = ConstValSpecialStatic;3356 const_val->special = ConstValSpecialStatic;
3357 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));3357 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));
3358 const_val->data.x_array.elements = allocate<ConstExprValue>(buf_len(str));3358 const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(buf_len(str));
33593359
3360 for (size_t i = 0; i < buf_len(str); i += 1) {3360 for (size_t i = 0; i < buf_len(str); i += 1) {
3361 ConstExprValue *this_char = &const_val->data.x_array.elements[i];3361 ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i];
3362 this_char->special = ConstValSpecialStatic;3362 this_char->special = ConstValSpecialStatic;
3363 this_char->type = g->builtin_types.entry_u8;3363 this_char->type = g->builtin_types.entry_u8;
3364 bignum_init_unsigned(&this_char->data.x_bignum, (uint8_t)buf_ptr(str)[i]);3364 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) {...@@ -3377,14 +3377,14 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
3377 ConstExprValue *array_val = allocate<ConstExprValue>(1);3377 ConstExprValue *array_val = allocate<ConstExprValue>(1);
3378 array_val->special = ConstValSpecialStatic;3378 array_val->special = ConstValSpecialStatic;
3379 array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);3379 array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);
3380 array_val->data.x_array.elements = allocate<ConstExprValue>(len_with_null);3380 array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(len_with_null);
3381 for (size_t i = 0; i < buf_len(str); i += 1) {3381 for (size_t i = 0; i < buf_len(str); i += 1) {
3382 ConstExprValue *this_char = &array_val->data.x_array.elements[i];3382 ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i];
3383 this_char->special = ConstValSpecialStatic;3383 this_char->special = ConstValSpecialStatic;
3384 this_char->type = g->builtin_types.entry_u8;3384 this_char->type = g->builtin_types.entry_u8;
3385 bignum_init_unsigned(&this_char->data.x_bignum, (uint8_t)buf_ptr(str)[i]);3385 bignum_init_unsigned(&this_char->data.x_bignum, (uint8_t)buf_ptr(str)[i]);
3386 }3386 }
3387 ConstExprValue *null_char = &array_val->data.x_array.elements[len_with_null - 1];3387 ConstExprValue *null_char = &array_val->data.x_array.s_none.elements[len_with_null - 1];
3388 null_char->special = ConstValSpecialStatic;3388 null_char->special = ConstValSpecialStatic;
3389 null_char->type = g->builtin_types.entry_u8;3389 null_char->type = g->builtin_types.entry_u8;
3390 bignum_init_unsigned(&null_char->data.x_bignum, 0);3390 bignum_init_unsigned(&null_char->data.x_bignum, 0);
...@@ -3564,19 +3564,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {...@@ -3564,19 +3564,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
3564 TypeTableEntry *wanted_type = const_val->type;3564 TypeTableEntry *wanted_type = const_val->type;
3565 if (wanted_type->id == TypeTableEntryIdArray) {3565 if (wanted_type->id == TypeTableEntryIdArray) {
3566 const_val->special = ConstValSpecialStatic;3566 const_val->special = ConstValSpecialStatic;
3567 size_t elem_count = wanted_type->data.array.len;3567 const_val->data.x_array.special = ConstArraySpecialUndef;
3568 const_val->data.x_array.elements = allocate<ConstExprValue>(elem_count);
3569 for (size_t i = 0; i < elem_count; i += 1) {
3570 ConstExprValue *element_val = &const_val->data.x_array.elements[i];
3571 element_val->type = wanted_type->data.array.child_type;
3572 init_const_undefined(g, element_val);
3573 ConstParent *parent = get_const_val_parent(element_val);
3574 if (parent != nullptr) {
3575 parent->id = ConstParentIdArray;
3576 parent->data.p_array.array_val = const_val;
3577 parent->data.p_array.elem_index = i;
3578 }
3579 }
3580 } else if (wanted_type->id == TypeTableEntryIdStruct) {3568 } else if (wanted_type->id == TypeTableEntryIdStruct) {
3581 ensure_complete_type(g, wanted_type);3569 ensure_complete_type(g, wanted_type);
35823570
...@@ -3588,7 +3576,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {...@@ -3588,7 +3576,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
3588 field_val->type = wanted_type->data.structure.fields[i].type_entry;3576 field_val->type = wanted_type->data.structure.fields[i].type_entry;
3589 assert(field_val->type);3577 assert(field_val->type);
3590 init_const_undefined(g, field_val);3578 init_const_undefined(g, field_val);
3591 ConstParent *parent = get_const_val_parent(field_val);3579 ConstParent *parent = get_const_val_parent(g, field_val);
3592 if (parent != nullptr) {3580 if (parent != nullptr) {
3593 parent->id = ConstParentIdStruct;3581 parent->id = ConstParentIdStruct;
3594 parent->data.p_struct.struct_val = const_val;3582 parent->data.p_struct.struct_val = const_val;
...@@ -3802,7 +3790,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *...@@ -3802,7 +3790,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *
3802 }3790 }
3803}3791}
38043792
3805void render_const_value(Buf *buf, ConstExprValue *const_val) {3793void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
3806 switch (const_val->special) {3794 switch (const_val->special) {
3807 case ConstValSpecialRuntime:3795 case ConstValSpecialRuntime:
3808 buf_appendf(buf, "(runtime value)");3796 buf_appendf(buf, "(runtime value)");
...@@ -3872,7 +3860,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {...@@ -3872,7 +3860,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
3872 case ConstPtrSpecialRef:3860 case ConstPtrSpecialRef:
3873 case ConstPtrSpecialBaseStruct:3861 case ConstPtrSpecialBaseStruct:
3874 buf_appendf(buf, "&");3862 buf_appendf(buf, "&");
3875 render_const_value(buf, const_ptr_pointee(const_val));3863 render_const_value(g, buf, const_ptr_pointee(g, const_val));
3876 return;3864 return;
3877 case ConstPtrSpecialBaseArray:3865 case ConstPtrSpecialBaseArray:
3878 if (const_val->data.x_ptr.data.base_array.is_cstr) {3866 if (const_val->data.x_ptr.data.base_array.is_cstr) {
...@@ -3880,7 +3868,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {...@@ -3880,7 +3868,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
3880 return;3868 return;
3881 } else {3869 } else {
3882 buf_appendf(buf, "&");3870 buf_appendf(buf, "&");
3883 render_const_value(buf, const_ptr_pointee(const_val));3871 render_const_value(g, buf, const_ptr_pointee(g, const_val));
3884 return;3872 return;
3885 }3873 }
3886 case ConstPtrSpecialHardCodedAddr:3874 case ConstPtrSpecialHardCodedAddr:
...@@ -3910,6 +3898,11 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {...@@ -3910,6 +3898,11 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
3910 TypeTableEntry *child_type = type_entry->data.array.child_type;3898 TypeTableEntry *child_type = type_entry->data.array.child_type;
3911 uint64_t len = type_entry->data.array.len;3899 uint64_t len = type_entry->data.array.len;
39123900
3901 if (const_val->data.x_array.special == ConstArraySpecialUndef) {
3902 buf_append_str(buf, "undefined");
3903 return;
3904 }
3905
3913 // if it's []u8, assume UTF-8 and output a string3906 // if it's []u8, assume UTF-8 and output a string
3914 if (child_type->id == TypeTableEntryIdInt &&3907 if (child_type->id == TypeTableEntryIdInt &&
3915 child_type->data.integral.bit_count == 8 &&3908 child_type->data.integral.bit_count == 8 &&
...@@ -3917,7 +3910,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {...@@ -3917,7 +3910,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
3917 {3910 {
3918 buf_append_char(buf, '"');3911 buf_append_char(buf, '"');
3919 for (uint64_t i = 0; i < len; i += 1) {3912 for (uint64_t i = 0; i < len; i += 1) {
3920 ConstExprValue *child_value = &const_val->data.x_array.elements[i];3913 ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];
3921 uint64_t big_c = child_value->data.x_bignum.data.x_uint;3914 uint64_t big_c = child_value->data.x_bignum.data.x_uint;
3922 assert(big_c <= UINT8_MAX);3915 assert(big_c <= UINT8_MAX);
3923 uint8_t c = (uint8_t)big_c;3916 uint8_t c = (uint8_t)big_c;
...@@ -3935,8 +3928,8 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {...@@ -3935,8 +3928,8 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
3935 for (uint64_t i = 0; i < len; i += 1) {3928 for (uint64_t i = 0; i < len; i += 1) {
3936 if (i != 0)3929 if (i != 0)
3937 buf_appendf(buf, ",");3930 buf_appendf(buf, ",");
3938 ConstExprValue *child_value = &const_val->data.x_array.elements[i];3931 ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];
3939 render_const_value(buf, child_value);3932 render_const_value(g, buf, child_value);
3940 }3933 }
3941 buf_appendf(buf, "}");3934 buf_appendf(buf, "}");
3942 return;3935 return;
...@@ -3954,7 +3947,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {...@@ -3954,7 +3947,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
3954 case TypeTableEntryIdMaybe:3947 case TypeTableEntryIdMaybe:
3955 {3948 {
3956 if (const_val->data.x_maybe) {3949 if (const_val->data.x_maybe) {
3957 render_const_value(buf, const_val->data.x_maybe);3950 render_const_value(g, buf, const_val->data.x_maybe);
3958 } else {3951 } else {
3959 buf_appendf(buf, "null");3952 buf_appendf(buf, "null");
3960 }3953 }
...@@ -4167,11 +4160,32 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {...@@ -4167,11 +4160,32 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
4167 zig_unreachable();4160 zig_unreachable();
4168}4161}
41694162
4170ConstParent *get_const_val_parent(ConstExprValue *value) {4163void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
4164 assert(const_val->type->id == TypeTableEntryIdArray);
4165 if (const_val->data.x_array.special == ConstArraySpecialUndef) {
4166 const_val->data.x_array.special = ConstArraySpecialNone;
4167 size_t elem_count = const_val->type->data.array.len;
4168 const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count);
4169 for (size_t i = 0; i < elem_count; i += 1) {
4170 ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i];
4171 element_val->type = const_val->type->data.array.child_type;
4172 init_const_undefined(g, element_val);
4173 ConstParent *parent = get_const_val_parent(g, element_val);
4174 if (parent != nullptr) {
4175 parent->id = ConstParentIdArray;
4176 parent->data.p_array.array_val = const_val;
4177 parent->data.p_array.elem_index = i;
4178 }
4179 }
4180 }
4181}
4182
4183ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
4171 assert(value->type);4184 assert(value->type);
4172 TypeTableEntry *type_entry = value->type;4185 TypeTableEntry *type_entry = value->type;
4173 if (type_entry->id == TypeTableEntryIdArray) {4186 if (type_entry->id == TypeTableEntryIdArray) {
4174 return &value->data.x_array.parent;4187 expand_undef_array(g, value);
4188 return &value->data.x_array.s_none.parent;
4175 } else if (type_entry->id == TypeTableEntryIdStruct) {4189 } else if (type_entry->id == TypeTableEntryIdStruct) {
4176 return &value->data.x_struct.parent;4190 return &value->data.x_struct.parent;
4177 }4191 }
src/analyze.hpp+3-2
...@@ -84,7 +84,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *...@@ -84,7 +84,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *
84int64_t min_signed_val(TypeTableEntry *type_entry);84int64_t min_signed_val(TypeTableEntry *type_entry);
85uint64_t max_unsigned_val(TypeTableEntry *type_entry);85uint64_t max_unsigned_val(TypeTableEntry *type_entry);
8686
87void render_const_value(Buf *buf, ConstExprValue *const_val);87void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val);
88void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entry, VariableTableEntry **arg_vars);88void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entry, VariableTableEntry **arg_vars);
89void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_type_node);89void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_type_node);
9090
...@@ -145,8 +145,9 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_...@@ -145,8 +145,9 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
145void init_const_undefined(CodeGen *g, ConstExprValue *const_val);145void init_const_undefined(CodeGen *g, ConstExprValue *const_val);
146146
147TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);147TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
148ConstParent *get_const_val_parent(ConstExprValue *value);148ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
149FnTableEntry *get_extern_panic_fn(CodeGen *g);149FnTableEntry *get_extern_panic_fn(CodeGen *g);
150TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type);150TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type);
151void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
151152
152#endif153#endif
src/ast_render.cpp+6-3
...@@ -273,6 +273,7 @@ void ast_print(FILE *f, AstNode *node, int indent) {...@@ -273,6 +273,7 @@ void ast_print(FILE *f, AstNode *node, int indent) {
273273
274274
275struct AstRender {275struct AstRender {
276 CodeGen *codegen;
276 int indent;277 int indent;
277 int indent_size;278 int indent_size;
278 FILE *f;279 FILE *f;
...@@ -924,8 +925,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -924,8 +925,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
924}925}
925926
926927
927void ast_render(FILE *f, AstNode *node, int indent_size) {928void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size) {
928 AstRender ar = {0};929 AstRender ar = {0};
930 ar.codegen = codegen;
929 ar.f = f;931 ar.f = f;
930 ar.indent_size = indent_size;932 ar.indent_size = indent_size;
931 ar.indent = 0;933 ar.indent = 0;
...@@ -1030,15 +1032,16 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {...@@ -1030,15 +1032,16 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
1030 } else {1032 } else {
1031 Buf buf = BUF_INIT;1033 Buf buf = BUF_INIT;
1032 buf_resize(&buf, 0);1034 buf_resize(&buf, 0);
1033 render_const_value(&buf, var->value);1035 render_const_value(ar->codegen, &buf, var->value);
1034 fprintf(ar->f, "%s", buf_ptr(&buf));1036 fprintf(ar->f, "%s", buf_ptr(&buf));
1035 }1037 }
10361038
1037 fprintf(ar->f, ";\n");1039 fprintf(ar->f, ";\n");
1038}1040}
10391041
1040void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {1042void ast_render_decls(CodeGen *codegen, FILE *f, int indent_size, ImportTableEntry *import) {
1041 AstRender ar = {0};1043 AstRender ar = {0};
1044 ar.codegen = codegen;
1042 ar.f = f;1045 ar.f = f;
1043 ar.indent_size = indent_size;1046 ar.indent_size = indent_size;
1044 ar.indent = 0;1047 ar.indent = 0;
src/ast_render.hpp+2-2
...@@ -15,11 +15,11 @@...@@ -15,11 +15,11 @@
1515
16void ast_print(FILE *f, AstNode *node, int indent);16void ast_print(FILE *f, AstNode *node, int indent);
1717
18void ast_render(FILE *f, AstNode *node, int indent_size);18void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size);
1919
20const char *container_string(ContainerKind kind);20const char *container_string(ContainerKind kind);
2121
22void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import);22void ast_render_decls(CodeGen *codegen, FILE *f, int indent_size, ImportTableEntry *import);
2323
24#endif24#endif
2525
src/codegen.cpp+9-4
...@@ -3051,7 +3051,8 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent...@@ -3051,7 +3051,8 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent
3051}3051}
30523052
3053static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {3053static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {
3054 ConstParent *parent = &array_const_val->data.x_array.parent;3054 expand_undef_array(g, array_const_val);
3055 ConstParent *parent = &array_const_val->data.x_array.s_none.parent;
3055 LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);3056 LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);
30563057
3057 TypeTableEntry *usize = g->builtin_types.entry_usize;3058 TypeTableEntry *usize = g->builtin_types.entry_usize;
...@@ -3283,9 +3284,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {...@@ -3283,9 +3284,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
3283 case TypeTableEntryIdArray:3284 case TypeTableEntryIdArray:
3284 {3285 {
3285 uint64_t len = type_entry->data.array.len;3286 uint64_t len = type_entry->data.array.len;
3287 if (const_val->data.x_array.special == ConstArraySpecialUndef) {
3288 return LLVMGetUndef(type_entry->type_ref);
3289 }
3290
3286 LLVMValueRef *values = allocate<LLVMValueRef>(len);3291 LLVMValueRef *values = allocate<LLVMValueRef>(len);
3287 for (uint64_t i = 0; i < len; i += 1) {3292 for (uint64_t i = 0; i < len; i += 1) {
3288 ConstExprValue *elem_value = &const_val->data.x_array.elements[i];3293 ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i];
3289 values[i] = gen_const_val(g, elem_value);3294 values[i] = gen_const_val(g, elem_value);
3290 }3295 }
3291 return LLVMConstArray(LLVMTypeOf(values[0]), values, (unsigned)len);3296 return LLVMConstArray(LLVMTypeOf(values[0]), values, (unsigned)len);
...@@ -4577,11 +4582,11 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -4577,11 +4582,11 @@ static void define_builtin_compile_vars(CodeGen *g) {
4577 ConstExprValue *const_val = allocate<ConstExprValue>(1);4582 ConstExprValue *const_val = allocate<ConstExprValue>(1);
4578 const_val->special = ConstValSpecialStatic;4583 const_val->special = ConstValSpecialStatic;
4579 const_val->type = get_array_type(g, str_type, g->link_libs.length);4584 const_val->type = get_array_type(g, str_type, g->link_libs.length);
4580 const_val->data.x_array.elements = allocate<ConstExprValue>(g->link_libs.length);4585 const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(g->link_libs.length);
4581 for (size_t i = 0; i < g->link_libs.length; i += 1) {4586 for (size_t i = 0; i < g->link_libs.length; i += 1) {
4582 Buf *link_lib_buf = g->link_libs.at(i);4587 Buf *link_lib_buf = g->link_libs.at(i);
4583 ConstExprValue *array_val = create_const_str_lit(g, link_lib_buf);4588 ConstExprValue *array_val = create_const_str_lit(g, link_lib_buf);
4584 init_const_slice(g, &const_val->data.x_array.elements[i], array_val, 0, buf_len(link_lib_buf), true);4589 init_const_slice(g, &const_val->data.x_array.s_none.elements[i], array_val, 0, buf_len(link_lib_buf), true);
4585 }4590 }
45864591
4587 add_compile_var(g, "link_libs", const_val);4592 add_compile_var(g, "link_libs", const_val);
src/ir.cpp+57-44
...@@ -56,7 +56,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc...@@ -56,7 +56,7 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc
56static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction);56static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction);
57static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type);57static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type);
5858
59ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) {59ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
60 assert(const_val->type->id == TypeTableEntryIdPointer);60 assert(const_val->type->id == TypeTableEntryIdPointer);
61 assert(const_val->special == ConstValSpecialStatic);61 assert(const_val->special == ConstValSpecialStatic);
62 switch (const_val->data.x_ptr.special) {62 switch (const_val->data.x_ptr.special) {
...@@ -65,7 +65,8 @@ ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) {...@@ -65,7 +65,8 @@ ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) {
65 case ConstPtrSpecialRef:65 case ConstPtrSpecialRef:
66 return const_val->data.x_ptr.data.ref.pointee;66 return const_val->data.x_ptr.data.ref.pointee;
67 case ConstPtrSpecialBaseArray:67 case ConstPtrSpecialBaseArray:
68 return &const_val->data.x_ptr.data.base_array.array_val->data.x_array.elements[68 expand_undef_array(g, const_val->data.x_ptr.data.base_array.array_val);
69 return &const_val->data.x_ptr.data.base_array.array_val->data.x_array.s_none.elements[
69 const_val->data.x_ptr.data.base_array.elem_index];70 const_val->data.x_ptr.data.base_array.elem_index];
70 case ConstPtrSpecialBaseStruct:71 case ConstPtrSpecialBaseStruct:
71 return &const_val->data.x_ptr.data.base_struct.struct_val->data.x_struct.fields[72 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...@@ -5503,16 +5504,16 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
5503 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);5504 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values);
5504}5505}
55055506
5506static bool render_instance_name_recursive(Buf *name, Scope *outer_scope, Scope *inner_scope) {5507static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) {
5507 if (inner_scope == nullptr || inner_scope == outer_scope) return false;5508 if (inner_scope == nullptr || inner_scope == outer_scope) return false;
5508 bool need_comma = render_instance_name_recursive(name, outer_scope, inner_scope->parent);5509 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent);
5509 if (inner_scope->id != ScopeIdVarDecl)5510 if (inner_scope->id != ScopeIdVarDecl)
5510 return need_comma;5511 return need_comma;
55115512
5512 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;5513 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;
5513 if (need_comma)5514 if (need_comma)
5514 buf_append_char(name, ',');5515 buf_append_char(name, ',');
5515 render_const_value(name, var_scope->var->value);5516 render_const_value(codegen, name, var_scope->var->value);
5516 return true;5517 return true;
5517}5518}
55185519
...@@ -5529,7 +5530,7 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,...@@ -5529,7 +5530,7 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,
5529 name = buf_alloc();5530 name = buf_alloc();
5530 buf_append_buf(name, &fn_entry->symbol_name);5531 buf_append_buf(name, &fn_entry->symbol_name);
5531 buf_appendf(name, "(");5532 buf_appendf(name, "(");
5532 render_instance_name_recursive(name, &fn_entry->fndef_scope->base, irb->exec->begin_scope);5533 render_instance_name_recursive(irb->codegen, name, &fn_entry->fndef_scope->base, irb->exec->begin_scope);
5533 buf_appendf(name, ")");5534 buf_appendf(name, ")");
5534 } else {5535 } else {
5535 name = buf_sprintf("(anonymous %s at %s:%zu:%zu)", container_string(kind),5536 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...@@ -6523,9 +6524,9 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
65236524
6524 if (codegen->verbose) {6525 if (codegen->verbose) {
6525 fprintf(stderr, "\nSource: ");6526 fprintf(stderr, "\nSource: ");
6526 ast_render(stderr, node, 4);6527 ast_render(codegen, stderr, node, 4);
6527 fprintf(stderr, "\n{ // (IR)\n");6528 fprintf(stderr, "\n{ // (IR)\n");
6528 ir_print(stderr, &ir_executable, 4);6529 ir_print(codegen, stderr, &ir_executable, 4);
6529 fprintf(stderr, "}\n");6530 fprintf(stderr, "}\n");
6530 }6531 }
6531 IrExecutable analyzed_executable = {0};6532 IrExecutable analyzed_executable = {0};
...@@ -6544,7 +6545,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node...@@ -6544,7 +6545,7 @@ IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node
65446545
6545 if (codegen->verbose) {6546 if (codegen->verbose) {
6546 fprintf(stderr, "{ // (analyzed)\n");6547 fprintf(stderr, "{ // (analyzed)\n");
6547 ir_print(stderr, &analyzed_executable, 4);6548 ir_print(codegen, stderr, &analyzed_executable, 4);
6548 fprintf(stderr, "}\n");6549 fprintf(stderr, "}\n");
6549 }6550 }
65506551
...@@ -7305,7 +7306,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc...@@ -7305,7 +7306,7 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
7305 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst ||7306 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst ||
7306 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar)7307 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar)
7307 {7308 {
7308 ConstExprValue *pointee = const_ptr_pointee(&ptr->value);7309 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &ptr->value);
7309 if (pointee->special != ConstValSpecialRuntime) {7310 if (pointee->special != ConstValSpecialRuntime) {
7310 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,7311 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,
7311 source_instruction->source_node, child_type);7312 source_instruction->source_node, child_type);
...@@ -7441,12 +7442,17 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {...@@ -7441,12 +7442,17 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
74417442
7442 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);7443 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
7443 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;7444 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
7445 expand_undef_array(ira->codegen, array_val);
7444 size_t len = len_field->data.x_bignum.data.x_uint;7446 size_t len = len_field->data.x_bignum.data.x_uint;
7445 Buf *result = buf_alloc();7447 Buf *result = buf_alloc();
7446 buf_resize(result, len);7448 buf_resize(result, len);
7447 for (size_t i = 0; i < len; i += 1) {7449 for (size_t i = 0; i < len; i += 1) {
7448 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;7450 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;
7449 ConstExprValue *char_val = &array_val->data.x_array.elements[new_index];7451 ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index];
7452 if (char_val->special == ConstValSpecialUndef) {
7453 ir_add_error(ira, casted_value, buf_sprintf("use of undefined value"));
7454 return nullptr;
7455 }
7450 uint64_t big_c = char_val->data.x_bignum.data.x_uint;7456 uint64_t big_c = char_val->data.x_bignum.data.x_uint;
7451 assert(big_c <= UINT8_MAX);7457 assert(big_c <= UINT8_MAX);
7452 uint8_t c = (uint8_t)big_c;7458 uint8_t c = (uint8_t)big_c;
...@@ -8007,17 +8013,19 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *...@@ -8007,17 +8013,19 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *
8007 out_val->data.x_ptr.data.base_array.array_val = out_array_val;8013 out_val->data.x_ptr.data.base_array.array_val = out_array_val;
8008 out_val->data.x_ptr.data.base_array.elem_index = 0;8014 out_val->data.x_ptr.data.base_array.elem_index = 0;
8009 }8015 }
8010 out_array_val->data.x_array.elements = allocate<ConstExprValue>(new_len);8016 out_array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(new_len);
8017
8018 expand_undef_array(ira->codegen, op1_array_val);
80118019
8012 size_t next_index = 0;8020 size_t next_index = 0;
8013 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {8021 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {
8014 out_array_val->data.x_array.elements[next_index] = op1_array_val->data.x_array.elements[i];8022 out_array_val->data.x_array.s_none.elements[next_index] = op1_array_val->data.x_array.s_none.elements[i];
8015 }8023 }
8016 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {8024 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {
8017 out_array_val->data.x_array.elements[next_index] = op2_array_val->data.x_array.elements[i];8025 out_array_val->data.x_array.s_none.elements[next_index] = op2_array_val->data.x_array.s_none.elements[i];
8018 }8026 }
8019 if (next_index < new_len) {8027 if (next_index < new_len) {
8020 ConstExprValue *null_byte = &out_array_val->data.x_array.elements[next_index];8028 ConstExprValue *null_byte = &out_array_val->data.x_array.s_none.elements[next_index];
8021 init_const_unsigned_negative(null_byte, child_type, 0, false);8029 init_const_unsigned_negative(null_byte, child_type, 0, false);
8022 next_index += 1;8030 next_index += 1;
8023 }8031 }
...@@ -8061,12 +8069,14 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp...@@ -8061,12 +8069,14 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp
8061 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);8069 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
80628070
8063 uint64_t new_array_len = array_len.data.x_uint;8071 uint64_t new_array_len = array_len.data.x_uint;
8064 out_val->data.x_array.elements = allocate<ConstExprValue>(new_array_len);8072 out_val->data.x_array.s_none.elements = allocate<ConstExprValue>(new_array_len);
8073
8074 expand_undef_array(ira->codegen, array_val);
80658075
8066 uint64_t i = 0;8076 uint64_t i = 0;
8067 for (uint64_t x = 0; x < mult_amt; x += 1) {8077 for (uint64_t x = 0; x < mult_amt; x += 1) {
8068 for (uint64_t y = 0; y < old_array_len; y += 1) {8078 for (uint64_t y = 0; y < old_array_len; y += 1) {
8069 out_val->data.x_array.elements[i] = array_val->data.x_array.elements[y];8079 out_val->data.x_array.s_none.elements[i] = array_val->data.x_array.s_none.elements[y];
8070 i += 1;8080 i += 1;
8071 }8081 }
8072 }8082 }
...@@ -8848,7 +8858,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp...@@ -8848,7 +8858,7 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp
8848 // one of the ptr instructions8858 // one of the ptr instructions
88498859
8850 if (instr_is_comptime(value)) {8860 if (instr_is_comptime(value)) {
8851 ConstExprValue *pointee = const_ptr_pointee(&value->value);8861 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value);
8852 if (pointee->type == child_type) {8862 if (pointee->type == child_type) {
8853 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);8863 ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base);
8854 *out_val = *pointee;8864 *out_val = *pointee;
...@@ -9222,7 +9232,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -9222,7 +9232,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
9222 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);9232 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
9223 if (!ptr_val)9233 if (!ptr_val)
9224 return ira->codegen->builtin_types.entry_invalid;9234 return ira->codegen->builtin_types.entry_invalid;
9225 ConstExprValue *args_val = const_ptr_pointee(ptr_val);9235 ConstExprValue *args_val = const_ptr_pointee(ira->codegen, ptr_val);
9226 size_t start = args_val->data.x_arg_tuple.start_index;9236 size_t start = args_val->data.x_arg_tuple.start_index;
9227 size_t end = args_val->data.x_arg_tuple.end_index;9237 size_t end = args_val->data.x_arg_tuple.end_index;
9228 ConstExprValue *elem_index_val = ir_resolve_const(ira, elem_index, UndefBad);9238 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...@@ -9276,7 +9286,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
9276 ConstExprValue *array_ptr_val;9286 ConstExprValue *array_ptr_val;
9277 if (array_ptr->value.special != ConstValSpecialRuntime &&9287 if (array_ptr->value.special != ConstValSpecialRuntime &&
9278 array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar &&9288 array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar &&
9279 (array_ptr_val = const_ptr_pointee(&array_ptr->value)) &&9289 (array_ptr_val = const_ptr_pointee(ira->codegen, &array_ptr->value)) &&
9280 array_ptr_val->special != ConstValSpecialRuntime &&9290 array_ptr_val->special != ConstValSpecialRuntime &&
9281 (array_type->id != TypeTableEntryIdPointer ||9291 (array_type->id != TypeTableEntryIdPointer ||
9282 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))9292 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))
...@@ -9431,7 +9441,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -9431,7 +9441,7 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
9431 return ira->codegen->builtin_types.entry_invalid;9441 return ira->codegen->builtin_types.entry_invalid;
94329442
9433 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {9443 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
9434 ConstExprValue *struct_val = const_ptr_pointee(ptr_val);9444 ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val);
9435 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];9445 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
9436 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,9446 TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,
9437 is_const, is_volatile, 0, 0);9447 is_const, is_volatile, 0, 0);
...@@ -9565,7 +9575,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -9565,7 +9575,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
9565 return ira->codegen->builtin_types.entry_invalid;9575 return ira->codegen->builtin_types.entry_invalid;
95669576
9567 assert(container_ptr->value.type->id == TypeTableEntryIdPointer);9577 assert(container_ptr->value.type->id == TypeTableEntryIdPointer);
9568 ConstExprValue *child_val = const_ptr_pointee(container_ptr_val);9578 ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val);
95699579
9570 if (buf_eql_str(field_name, "len")) {9580 if (buf_eql_str(field_name, "len")) {
9571 ConstExprValue *len_val = allocate<ConstExprValue>(1);9581 ConstExprValue *len_val = allocate<ConstExprValue>(1);
...@@ -9594,7 +9604,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -9594,7 +9604,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
9594 assert(ptr_type->id == TypeTableEntryIdPointer);9604 assert(ptr_type->id == TypeTableEntryIdPointer);
9595 child_type = ptr_type->data.pointer.child_type;9605 child_type = ptr_type->data.pointer.child_type;
9596 } else if (container_ptr->value.type->id == TypeTableEntryIdPointer) {9606 } else if (container_ptr->value.type->id == TypeTableEntryIdPointer) {
9597 ConstExprValue *child_val = const_ptr_pointee(container_ptr_val);9607 ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val);
9598 child_type = child_val->data.x_type;9608 child_type = child_val->data.x_type;
9599 } else {9609 } else {
9600 zig_unreachable();9610 zig_unreachable();
...@@ -9688,7 +9698,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru...@@ -9688,7 +9698,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru
9688 if (!container_ptr_val)9698 if (!container_ptr_val)
9689 return ira->codegen->builtin_types.entry_invalid;9699 return ira->codegen->builtin_types.entry_invalid;
96909700
9691 ConstExprValue *namespace_val = const_ptr_pointee(container_ptr_val);9701 ConstExprValue *namespace_val = const_ptr_pointee(ira->codegen, container_ptr_val);
9692 assert(namespace_val->special == ConstValSpecialStatic);9702 assert(namespace_val->special == ConstValSpecialStatic);
96939703
9694 ImportTableEntry *namespace_import = namespace_val->data.x_import;9704 ImportTableEntry *namespace_import = namespace_val->data.x_import;
...@@ -9761,7 +9771,7 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru...@@ -9761,7 +9771,7 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru
9761 }9771 }
9762 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) {9772 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) {
9763 if (instr_is_comptime(casted_value)) {9773 if (instr_is_comptime(casted_value)) {
9764 ConstExprValue *dest_val = const_ptr_pointee(&ptr->value);9774 ConstExprValue *dest_val = const_ptr_pointee(ira->codegen, &ptr->value);
9765 if (dest_val->special != ConstValSpecialRuntime) {9775 if (dest_val->special != ConstValSpecialRuntime) {
9766 *dest_val = casted_value->value;9776 *dest_val = casted_value->value;
9767 if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) {9777 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,...@@ -10630,7 +10640,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
10630 TypeTableEntry *target_type = target_value_ptr->value.type->data.pointer.child_type;10640 TypeTableEntry *target_type = target_value_ptr->value.type->data.pointer.child_type;
10631 ConstExprValue *pointee_val = nullptr;10641 ConstExprValue *pointee_val = nullptr;
10632 if (instr_is_comptime(target_value_ptr)) {10642 if (instr_is_comptime(target_value_ptr)) {
10633 pointee_val = const_ptr_pointee(&target_value_ptr->value);10643 pointee_val = const_ptr_pointee(ira->codegen, &target_value_ptr->value);
10634 if (pointee_val->special == ConstValSpecialRuntime)10644 if (pointee_val->special == ConstValSpecialRuntime)
10635 pointee_val = nullptr;10645 pointee_val = nullptr;
10636 }10646 }
...@@ -10730,7 +10740,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr...@@ -10730,7 +10740,7 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr
10730 if (!target_value_ptr)10740 if (!target_value_ptr)
10731 return ira->codegen->builtin_types.entry_invalid;10741 return ira->codegen->builtin_types.entry_invalid;
1073210742
10733 ConstExprValue *pointee_val = const_ptr_pointee(target_val_ptr);10743 ConstExprValue *pointee_val = const_ptr_pointee(ira->codegen, target_val_ptr);
10734 if (pointee_val->type->id == TypeTableEntryIdEnum) {10744 if (pointee_val->type->id == TypeTableEntryIdEnum) {
10735 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);10745 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
10736 out_val->data.x_ptr.special = ConstPtrSpecialRef;10746 out_val->data.x_ptr.special = ConstPtrSpecialRef;
...@@ -10982,7 +10992,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru...@@ -10982,7 +10992,7 @@ static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstru
1098210992
10983 for (size_t i = 0; i < instr_field_count; i += 1) {10993 for (size_t i = 0; i < instr_field_count; i += 1) {
10984 ConstExprValue *field_val = &out_val->data.x_struct.fields[i];10994 ConstExprValue *field_val = &out_val->data.x_struct.fields[i];
10985 ConstParent *parent = get_const_val_parent(field_val);10995 ConstParent *parent = get_const_val_parent(ira->codegen, field_val);
10986 if (parent != nullptr) {10996 if (parent != nullptr) {
10987 parent->id = ConstParentIdStruct;10997 parent->id = ConstParentIdStruct;
10988 parent->data.p_struct.field_index = i;10998 parent->data.p_struct.field_index = i;
...@@ -11031,7 +11041,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -11031,7 +11041,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
11031 ConstExprValue const_val = {};11041 ConstExprValue const_val = {};
11032 const_val.special = ConstValSpecialStatic;11042 const_val.special = ConstValSpecialStatic;
11033 const_val.type = fixed_size_array_type;11043 const_val.type = fixed_size_array_type;
11034 const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count);11044 const_val.data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count);
1103511045
11036 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);11046 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
1103711047
...@@ -11056,7 +11066,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -11056,7 +11066,7 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
11056 if (!elem_val)11066 if (!elem_val)
11057 return ira->codegen->builtin_types.entry_invalid;11067 return ira->codegen->builtin_types.entry_invalid;
1105811068
11059 const_val.data.x_array.elements[i] = *elem_val;11069 const_val.data.x_array.s_none.elements[i] = *elem_val;
11060 } else {11070 } else {
11061 first_non_const_instruction = casted_arg;11071 first_non_const_instruction = casted_arg;
11062 const_val.special = ConstValSpecialRuntime;11072 const_val.special = ConstValSpecialRuntime;
...@@ -11068,8 +11078,8 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira...@@ -11068,8 +11078,8 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
11068 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);11078 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
11069 *out_val = const_val;11079 *out_val = const_val;
11070 for (size_t i = 0; i < elem_count; i += 1) {11080 for (size_t i = 0; i < elem_count; i += 1) {
11071 ConstExprValue *elem_val = &out_val->data.x_array.elements[i];11081 ConstExprValue *elem_val = &out_val->data.x_array.s_none.elements[i];
11072 ConstParent *parent = get_const_val_parent(elem_val);11082 ConstParent *parent = get_const_val_parent(ira->codegen, elem_val);
11073 if (parent != nullptr) {11083 if (parent != nullptr) {
11074 parent->id = ConstParentIdArray;11084 parent->id = ConstParentIdArray;
11075 parent->data.p_array.array_val = out_val;11085 parent->data.p_array.array_val = out_val;
...@@ -11254,7 +11264,7 @@ static TypeTableEntry *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInst...@@ -11254,7 +11264,7 @@ static TypeTableEntry *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInst
11254 if (type_is_invalid(msg->value.type))11264 if (type_is_invalid(msg->value.type))
11255 return ira->codegen->builtin_types.entry_invalid;11265 return ira->codegen->builtin_types.entry_invalid;
11256 buf_resize(&buf, 0);11266 buf_resize(&buf, 0);
11257 render_const_value(&buf, &msg->value);11267 render_const_value(ira->codegen, &buf, &msg->value);
11258 const char *comma_str = (i != 0) ? ", " : "";11268 const char *comma_str = (i != 0) ? ", " : "";
11259 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf));11269 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf));
11260 }11270 }
...@@ -11526,7 +11536,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc...@@ -11526,7 +11536,7 @@ static TypeTableEntry *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruc
11526 if (ira->codegen->verbose) {11536 if (ira->codegen->verbose) {
11527 fprintf(stderr, "\nC imports:\n");11537 fprintf(stderr, "\nC imports:\n");
11528 fprintf(stderr, "-----------\n");11538 fprintf(stderr, "-----------\n");
11529 ast_render_decls(stderr, 4, child_import);11539 ast_render_decls(ira->codegen, stderr, 4, child_import);
11530 }11540 }
1153111541
11532 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);11542 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
...@@ -11925,7 +11935,8 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi...@@ -11925,7 +11935,8 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi
11925 case ConstPtrSpecialBaseArray:11935 case ConstPtrSpecialBaseArray:
11926 {11936 {
11927 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;11937 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
11928 dest_elements = array_val->data.x_array.elements;11938 expand_undef_array(ira->codegen, array_val);
11939 dest_elements = array_val->data.x_array.s_none.elements;
11929 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;11940 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;
11930 bound_end = array_val->type->data.array.len;11941 bound_end = array_val->type->data.array.len;
11931 break;11942 break;
...@@ -12016,7 +12027,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi...@@ -12016,7 +12027,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
12016 case ConstPtrSpecialBaseArray:12027 case ConstPtrSpecialBaseArray:
12017 {12028 {
12018 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;12029 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
12019 dest_elements = array_val->data.x_array.elements;12030 expand_undef_array(ira->codegen, array_val);
12031 dest_elements = array_val->data.x_array.s_none.elements;
12020 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;12032 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;
12021 dest_end = array_val->type->data.array.len;12033 dest_end = array_val->type->data.array.len;
12022 break;12034 break;
...@@ -12049,7 +12061,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi...@@ -12049,7 +12061,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi
12049 case ConstPtrSpecialBaseArray:12061 case ConstPtrSpecialBaseArray:
12050 {12062 {
12051 ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val;12063 ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val;
12052 src_elements = array_val->data.x_array.elements;12064 expand_undef_array(ira->codegen, array_val);
12065 src_elements = array_val->data.x_array.s_none.elements;
12053 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index;12066 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index;
12054 src_end = array_val->type->data.array.len;12067 src_end = array_val->type->data.array.len;
12055 break;12068 break;
...@@ -12138,12 +12151,12 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -12138,12 +12151,12 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
12138 size_t abs_offset;12151 size_t abs_offset;
12139 size_t rel_end;12152 size_t rel_end;
12140 if (array_type->id == TypeTableEntryIdArray) {12153 if (array_type->id == TypeTableEntryIdArray) {
12141 array_val = const_ptr_pointee(&ptr_ptr->value);12154 array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
12142 abs_offset = 0;12155 abs_offset = 0;
12143 rel_end = array_type->data.array.len;12156 rel_end = array_type->data.array.len;
12144 parent_ptr = nullptr;12157 parent_ptr = nullptr;
12145 } else if (array_type->id == TypeTableEntryIdPointer) {12158 } else if (array_type->id == TypeTableEntryIdPointer) {
12146 parent_ptr = const_ptr_pointee(&ptr_ptr->value);12159 parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
12147 switch (parent_ptr->data.x_ptr.special) {12160 switch (parent_ptr->data.x_ptr.special) {
12148 case ConstPtrSpecialInvalid:12161 case ConstPtrSpecialInvalid:
12149 case ConstPtrSpecialDiscard:12162 case ConstPtrSpecialDiscard:
...@@ -12165,7 +12178,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -12165,7 +12178,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
12165 break;12178 break;
12166 }12179 }
12167 } else if (is_slice(array_type)) {12180 } else if (is_slice(array_type)) {
12168 ConstExprValue *slice_ptr = const_ptr_pointee(&ptr_ptr->value);12181 ConstExprValue *slice_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
12169 parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index];12182 parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index];
12170 ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index];12183 ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index];
1217112184
...@@ -12371,7 +12384,7 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst...@@ -12371,7 +12384,7 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst
12371 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);12384 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
12372 BigNum *op1_bignum = &casted_op1->value.data.x_bignum;12385 BigNum *op1_bignum = &casted_op1->value.data.x_bignum;
12373 BigNum *op2_bignum = &casted_op2->value.data.x_bignum;12386 BigNum *op2_bignum = &casted_op2->value.data.x_bignum;
12374 ConstExprValue *pointee_val = const_ptr_pointee(&casted_result_ptr->value);12387 ConstExprValue *pointee_val = const_ptr_pointee(ira->codegen, &casted_result_ptr->value);
12375 BigNum *dest_bignum = &pointee_val->data.x_bignum;12388 BigNum *dest_bignum = &pointee_val->data.x_bignum;
12376 switch (instruction->op) {12389 switch (instruction->op) {
12377 case IrOverflowOpAdd:12390 case IrOverflowOpAdd:
...@@ -12455,7 +12468,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,...@@ -12455,7 +12468,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,
12455 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);12468 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
12456 if (!ptr_val)12469 if (!ptr_val)
12457 return ira->codegen->builtin_types.entry_invalid;12470 return ira->codegen->builtin_types.entry_invalid;
12458 ConstExprValue *err_union_val = const_ptr_pointee(ptr_val);12471 ConstExprValue *err_union_val = const_ptr_pointee(ira->codegen, ptr_val);
12459 if (err_union_val->special != ConstValSpecialRuntime) {12472 if (err_union_val->special != ConstValSpecialRuntime) {
12460 ErrorTableEntry *err = err_union_val->data.x_err_union.err;12473 ErrorTableEntry *err = err_union_val->data.x_err_union.err;
12461 assert(err);12474 assert(err);
...@@ -12498,7 +12511,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,...@@ -12498,7 +12511,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
12498 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);12511 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
12499 if (!ptr_val)12512 if (!ptr_val)
12500 return ira->codegen->builtin_types.entry_invalid;12513 return ira->codegen->builtin_types.entry_invalid;
12501 ConstExprValue *err_union_val = const_ptr_pointee(ptr_val);12514 ConstExprValue *err_union_val = const_ptr_pointee(ira->codegen, ptr_val);
12502 if (err_union_val->special != ConstValSpecialRuntime) {12515 if (err_union_val->special != ConstValSpecialRuntime) {
12503 ErrorTableEntry *err = err_union_val->data.x_err_union.err;12516 ErrorTableEntry *err = err_union_val->data.x_err_union.err;
12504 if (err != nullptr) {12517 if (err != nullptr) {
...@@ -13248,7 +13261,7 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE...@@ -13248,7 +13261,7 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE
1324813261
13249 if (codegen->verbose) {13262 if (codegen->verbose) {
13250 fprintf(stderr, "{\n");13263 fprintf(stderr, "{\n");
13251 ir_print(stderr, &fn_entry->ir_executable, 4);13264 ir_print(codegen, stderr, &fn_entry->ir_executable, 4);
13252 fprintf(stderr, "}\n");13265 fprintf(stderr, "}\n");
13253 }13266 }
1325413267
src/ir.hpp+1-1
...@@ -22,7 +22,7 @@ TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutabl...@@ -22,7 +22,7 @@ TypeTableEntry *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutabl
22 TypeTableEntry *expected_type, AstNode *expected_type_source_node);22 TypeTableEntry *expected_type, AstNode *expected_type_source_node);
2323
24bool ir_has_side_effects(IrInstruction *instruction);24bool ir_has_side_effects(IrInstruction *instruction);
25ConstExprValue *const_ptr_pointee(ConstExprValue *const_val);25ConstExprValue *const_ptr_pointee(CodeGen *codegen, ConstExprValue *const_val);
2626
27FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableEntry *var, Scope *parent_scope);27FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableEntry *var, Scope *parent_scope);
2828
src/ir_print.cpp+4-2
...@@ -10,6 +10,7 @@...@@ -10,6 +10,7 @@
10#include "ir_print.hpp"10#include "ir_print.hpp"
1111
12struct IrPrint {12struct IrPrint {
13 CodeGen *codegen;
13 FILE *f;14 FILE *f;
14 int indent;15 int indent;
15 int indent_size;16 int indent_size;
...@@ -34,7 +35,7 @@ static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) {...@@ -34,7 +35,7 @@ static void ir_print_prefix(IrPrint *irp, IrInstruction *instruction) {
34static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) {35static void ir_print_const_value(IrPrint *irp, ConstExprValue *const_val) {
35 Buf buf = BUF_INIT;36 Buf buf = BUF_INIT;
36 buf_resize(&buf, 0);37 buf_resize(&buf, 0);
37 render_const_value(&buf, const_val);38 render_const_value(irp->codegen, &buf, const_val);
38 fprintf(irp->f, "%s", buf_ptr(&buf));39 fprintf(irp->f, "%s", buf_ptr(&buf));
39}40}
4041
...@@ -1188,9 +1189,10 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1188,9 +1189,10 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1188 fprintf(irp->f, "\n");1189 fprintf(irp->f, "\n");
1189}1190}
11901191
1191void ir_print(FILE *f, IrExecutable *executable, int indent_size) {1192void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size) {
1192 IrPrint ir_print = {};1193 IrPrint ir_print = {};
1193 IrPrint *irp = &ir_print;1194 IrPrint *irp = &ir_print;
1195 irp->codegen = codegen;
1194 irp->f = f;1196 irp->f = f;
1195 irp->indent = indent_size;1197 irp->indent = indent_size;
1196 irp->indent_size = indent_size;1198 irp->indent_size = indent_size;
src/ir_print.hpp+1-1
...@@ -12,6 +12,6 @@...@@ -12,6 +12,6 @@
1212
13#include <stdio.h>13#include <stdio.h>
1414
15void ir_print(FILE *f, IrExecutable *executable, int indent_size);15void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size);
1616
17#endif17#endif
src/main.cpp+1-1
...@@ -609,7 +609,7 @@ int main(int argc, char **argv) {...@@ -609,7 +609,7 @@ int main(int argc, char **argv) {
609 return EXIT_SUCCESS;609 return EXIT_SUCCESS;
610 } else if (cmd == CmdParseH) {610 } else if (cmd == CmdParseH) {
611 codegen_parseh(g, &root_source_dir, &root_source_name, &root_source_code);611 codegen_parseh(g, &root_source_dir, &root_source_name, &root_source_code);
612 ast_render_decls(stdout, 4, g->root_import);612 ast_render_decls(g, stdout, 4, g->root_import);
613 return EXIT_SUCCESS;613 return EXIT_SUCCESS;
614 } else if (cmd == CmdTest) {614 } else if (cmd == CmdTest) {
615 codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code);615 codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code);