authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-20 11:04:31-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-20 11:04:31-04:00
logf8fe517d126d582e37ab4537fe9fd42f0531f44b
tree040baa17d21eb30b1dc7d2a4ef470fe7aea08e85
parent492821781dc34659f694577aacbc853c8839406f
signaturelock-open Commit is signed but in an unrecognized format.

better string literal caching implementation

We were caching the ConstExprValue of string literals, which works if you can never modify ConstExprValues. This premise is broken with `comptime var ...`. So I implemented an optimization in ConstExprValue arrays, where it stores a `Buf *` directly rather than an array of ConstExprValues for the elements, and then similar to array of undefined, it is expanded into the canonical form when necessary. However many operations can happen directly on the `Buf *`, which is faster. Furthermore, before a ConstExprValue array is expanded into canonical form, it removes itself from the string literal cache. This fixes the issue, because before an array element is modified it would have to be expanded. closes #1076

8 files changed, 278 insertions(+), 210 deletions(-)

src/all_types.hpp+12-5
...@@ -130,14 +130,18 @@ struct ConstUnionValue {...@@ -130,14 +130,18 @@ struct ConstUnionValue {
130enum ConstArraySpecial {130enum ConstArraySpecial {
131 ConstArraySpecialNone,131 ConstArraySpecialNone,
132 ConstArraySpecialUndef,132 ConstArraySpecialUndef,
133 ConstArraySpecialBuf,
133};134};
134135
135struct ConstArrayValue {136struct ConstArrayValue {
136 ConstArraySpecial special;137 ConstArraySpecial special;
137 struct {138 union {
138 ConstExprValue *elements;139 struct {
139 ConstParent parent;140 ConstExprValue *elements;
140 } s_none;141 ConstParent parent;
142 } s_none;
143 Buf *s_buf;
144 } data;
141};145};
142146
143enum ConstPtrSpecial {147enum ConstPtrSpecial {
...@@ -983,6 +987,7 @@ struct FnTypeParamInfo {...@@ -983,6 +987,7 @@ struct FnTypeParamInfo {
983};987};
984988
985struct GenericFnTypeId {989struct GenericFnTypeId {
990 CodeGen *codegen;
986 ZigFn *fn_entry;991 ZigFn *fn_entry;
987 ConstExprValue *params;992 ConstExprValue *params;
988 size_t param_count;993 size_t param_count;
...@@ -1291,6 +1296,7 @@ struct FnExport {...@@ -1291,6 +1296,7 @@ struct FnExport {
1291};1296};
12921297
1293struct ZigFn {1298struct ZigFn {
1299 CodeGen *codegen;
1294 LLVMValueRef llvm_value;1300 LLVMValueRef llvm_value;
1295 const char *llvm_name;1301 const char *llvm_name;
1296 AstNode *proto_node;1302 AstNode *proto_node;
...@@ -1848,13 +1854,14 @@ enum ScopeId {...@@ -1848,13 +1854,14 @@ enum ScopeId {
1848};1854};
18491855
1850struct Scope {1856struct Scope {
1851 ScopeId id;1857 CodeGen *codegen;
1852 AstNode *source_node;1858 AstNode *source_node;
18531859
1854 // if the scope has a parent, this is it1860 // if the scope has a parent, this is it
1855 Scope *parent;1861 Scope *parent;
18561862
1857 ZigLLVMDIScope *di_scope;1863 ZigLLVMDIScope *di_scope;
1864 ScopeId id;
1858};1865};
18591866
1860// This scope comes from global declarations or from1867// This scope comes from global declarations or from
src/analyze.cpp+135-104
...@@ -92,62 +92,63 @@ ScopeDecls *get_container_scope(ZigType *type_entry) {...@@ -92,62 +92,63 @@ ScopeDecls *get_container_scope(ZigType *type_entry) {
92 return *get_container_scope_ptr(type_entry);92 return *get_container_scope_ptr(type_entry);
93}93}
9494
95void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) {95void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) {
96 dest->codegen = g;
96 dest->id = id;97 dest->id = id;
97 dest->source_node = source_node;98 dest->source_node = source_node;
98 dest->parent = parent;99 dest->parent = parent;
99}100}
100101
101ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) {102ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) {
102 assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr);103 assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr);
103 ScopeDecls *scope = allocate<ScopeDecls>(1);104 ScopeDecls *scope = allocate<ScopeDecls>(1);
104 init_scope(&scope->base, ScopeIdDecls, node, parent);105 init_scope(g, &scope->base, ScopeIdDecls, node, parent);
105 scope->decl_table.init(4);106 scope->decl_table.init(4);
106 scope->container_type = container_type;107 scope->container_type = container_type;
107 scope->import = import;108 scope->import = import;
108 return scope;109 return scope;
109}110}
110111
111ScopeBlock *create_block_scope(AstNode *node, Scope *parent) {112ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent) {
112 assert(node->type == NodeTypeBlock);113 assert(node->type == NodeTypeBlock);
113 ScopeBlock *scope = allocate<ScopeBlock>(1);114 ScopeBlock *scope = allocate<ScopeBlock>(1);
114 init_scope(&scope->base, ScopeIdBlock, node, parent);115 init_scope(g, &scope->base, ScopeIdBlock, node, parent);
115 scope->name = node->data.block.name;116 scope->name = node->data.block.name;
116 return scope;117 return scope;
117}118}
118119
119ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) {120ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent) {
120 assert(node->type == NodeTypeDefer);121 assert(node->type == NodeTypeDefer);
121 ScopeDefer *scope = allocate<ScopeDefer>(1);122 ScopeDefer *scope = allocate<ScopeDefer>(1);
122 init_scope(&scope->base, ScopeIdDefer, node, parent);123 init_scope(g, &scope->base, ScopeIdDefer, node, parent);
123 return scope;124 return scope;
124}125}
125126
126ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent) {127ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent) {
127 assert(node->type == NodeTypeDefer);128 assert(node->type == NodeTypeDefer);
128 ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1);129 ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1);
129 init_scope(&scope->base, ScopeIdDeferExpr, node, parent);130 init_scope(g, &scope->base, ScopeIdDeferExpr, node, parent);
130 return scope;131 return scope;
131}132}
132133
133Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var) {134Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var) {
134 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);135 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1);
135 init_scope(&scope->base, ScopeIdVarDecl, node, parent);136 init_scope(g, &scope->base, ScopeIdVarDecl, node, parent);
136 scope->var = var;137 scope->var = var;
137 return &scope->base;138 return &scope->base;
138}139}
139140
140ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) {141ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent) {
141 assert(node->type == NodeTypeFnCallExpr);142 assert(node->type == NodeTypeFnCallExpr);
142 ScopeCImport *scope = allocate<ScopeCImport>(1);143 ScopeCImport *scope = allocate<ScopeCImport>(1);
143 init_scope(&scope->base, ScopeIdCImport, node, parent);144 init_scope(g, &scope->base, ScopeIdCImport, node, parent);
144 buf_resize(&scope->buf, 0);145 buf_resize(&scope->buf, 0);
145 return scope;146 return scope;
146}147}
147148
148ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) {149ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent) {
149 ScopeLoop *scope = allocate<ScopeLoop>(1);150 ScopeLoop *scope = allocate<ScopeLoop>(1);
150 init_scope(&scope->base, ScopeIdLoop, node, parent);151 init_scope(g, &scope->base, ScopeIdLoop, node, parent);
151 if (node->type == NodeTypeWhileExpr) {152 if (node->type == NodeTypeWhileExpr) {
152 scope->name = node->data.while_expr.name;153 scope->name = node->data.while_expr.name;
153 } else if (node->type == NodeTypeForExpr) {154 } else if (node->type == NodeTypeForExpr) {
...@@ -158,37 +159,37 @@ ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) {...@@ -158,37 +159,37 @@ ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) {
158 return scope;159 return scope;
159}160}
160161
161Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime) {162Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime) {
162 ScopeRuntime *scope = allocate<ScopeRuntime>(1);163 ScopeRuntime *scope = allocate<ScopeRuntime>(1);
163 scope->is_comptime = is_comptime;164 scope->is_comptime = is_comptime;
164 init_scope(&scope->base, ScopeIdRuntime, node, parent);165 init_scope(g, &scope->base, ScopeIdRuntime, node, parent);
165 return &scope->base;166 return &scope->base;
166}167}
167168
168ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent) {169ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
169 assert(node->type == NodeTypeSuspend);170 assert(node->type == NodeTypeSuspend);
170 ScopeSuspend *scope = allocate<ScopeSuspend>(1);171 ScopeSuspend *scope = allocate<ScopeSuspend>(1);
171 init_scope(&scope->base, ScopeIdSuspend, node, parent);172 init_scope(g, &scope->base, ScopeIdSuspend, node, parent);
172 return scope;173 return scope;
173}174}
174175
175ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry) {176ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry) {
176 ScopeFnDef *scope = allocate<ScopeFnDef>(1);177 ScopeFnDef *scope = allocate<ScopeFnDef>(1);
177 init_scope(&scope->base, ScopeIdFnDef, node, parent);178 init_scope(g, &scope->base, ScopeIdFnDef, node, parent);
178 scope->fn_entry = fn_entry;179 scope->fn_entry = fn_entry;
179 return scope;180 return scope;
180}181}
181182
182Scope *create_comptime_scope(AstNode *node, Scope *parent) {183Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
183 assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr);184 assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr);
184 ScopeCompTime *scope = allocate<ScopeCompTime>(1);185 ScopeCompTime *scope = allocate<ScopeCompTime>(1);
185 init_scope(&scope->base, ScopeIdCompTime, node, parent);186 init_scope(g, &scope->base, ScopeIdCompTime, node, parent);
186 return &scope->base;187 return &scope->base;
187}188}
188189
189Scope *create_coro_prelude_scope(AstNode *node, Scope *parent) {190Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent) {
190 ScopeCoroPrelude *scope = allocate<ScopeCoroPrelude>(1);191 ScopeCoroPrelude *scope = allocate<ScopeCoroPrelude>(1);
191 init_scope(&scope->base, ScopeIdCoroPrelude, node, parent);192 init_scope(g, &scope->base, ScopeIdCoroPrelude, node, parent);
192 return &scope->base;193 return &scope->base;
193}194}
194195
...@@ -204,9 +205,9 @@ ImportTableEntry *get_scope_import(Scope *scope) {...@@ -204,9 +205,9 @@ ImportTableEntry *get_scope_import(Scope *scope) {
204 zig_unreachable();205 zig_unreachable();
205}206}
206207
207static ZigType *new_container_type_entry(ZigTypeId id, AstNode *source_node, Scope *parent_scope) {208static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *source_node, Scope *parent_scope) {
208 ZigType *entry = new_type_table_entry(id);209 ZigType *entry = new_type_table_entry(id);
209 *get_container_scope_ptr(entry) = create_decls_scope(source_node, parent_scope, entry, get_scope_import(parent_scope));210 *get_container_scope_ptr(entry) = create_decls_scope(g, source_node, parent_scope, entry, get_scope_import(parent_scope));
210 return entry;211 return entry;
211}212}
212213
...@@ -1245,7 +1246,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind...@@ -1245,7 +1246,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind
1245 AstNode *decl_node, const char *name, ContainerLayout layout)1246 AstNode *decl_node, const char *name, ContainerLayout layout)
1246{1247{
1247 ZigTypeId type_id = container_to_type(kind);1248 ZigTypeId type_id = container_to_type(kind);
1248 ZigType *entry = new_container_type_entry(type_id, decl_node, scope);1249 ZigType *entry = new_container_type_entry(g, type_id, decl_node, scope);
12491250
1250 switch (kind) {1251 switch (kind) {
1251 case ContainerKindStruct:1252 case ContainerKindStruct:
...@@ -1372,13 +1373,17 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **...@@ -1372,13 +1373,17 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
13721373
1373 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);1374 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
1374 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;1375 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
1376 if (array_val->data.x_array.special == ConstArraySpecialBuf) {
1377 *out_buffer = array_val->data.x_array.data.s_buf;
1378 return true;
1379 }
1375 expand_undef_array(g, array_val);1380 expand_undef_array(g, array_val);
1376 size_t len = bigint_as_unsigned(&len_field->data.x_bigint);1381 size_t len = bigint_as_unsigned(&len_field->data.x_bigint);
1377 Buf *result = buf_alloc();1382 Buf *result = buf_alloc();
1378 buf_resize(result, len);1383 buf_resize(result, len);
1379 for (size_t i = 0; i < len; i += 1) {1384 for (size_t i = 0; i < len; i += 1) {
1380 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;1385 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;
1381 ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index];1386 ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index];
1382 if (char_val->special == ConstValSpecialUndef) {1387 if (char_val->special == ConstValSpecialUndef) {
1383 add_node_error(g, node, buf_sprintf("use of undefined value"));1388 add_node_error(g, node, buf_sprintf("use of undefined value"));
1384 return false;1389 return false;
...@@ -3093,9 +3098,10 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) {...@@ -3093,9 +3098,10 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) {
3093 buf_append_buf(buf, tld->name);3098 buf_append_buf(buf, tld->name);
3094}3099}
30953100
3096ZigFn *create_fn_raw(FnInline inline_value) {3101ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) {
3097 ZigFn *fn_entry = allocate<ZigFn>(1);3102 ZigFn *fn_entry = allocate<ZigFn>(1);
30983103
3104 fn_entry->codegen = g;
3099 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;3105 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
3100 fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;3106 fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;
3101 fn_entry->analyzed_executable.fn_entry = fn_entry;3107 fn_entry->analyzed_executable.fn_entry = fn_entry;
...@@ -3105,12 +3111,12 @@ ZigFn *create_fn_raw(FnInline inline_value) {...@@ -3105,12 +3111,12 @@ ZigFn *create_fn_raw(FnInline inline_value) {
3105 return fn_entry;3111 return fn_entry;
3106}3112}
31073113
3108ZigFn *create_fn(AstNode *proto_node) {3114ZigFn *create_fn(CodeGen *g, AstNode *proto_node) {
3109 assert(proto_node->type == NodeTypeFnProto);3115 assert(proto_node->type == NodeTypeFnProto);
3110 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;3116 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
31113117
3112 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;3118 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto;
3113 ZigFn *fn_entry = create_fn_raw(inline_value);3119 ZigFn *fn_entry = create_fn_raw(g, inline_value);
31143120
3115 fn_entry->proto_node = proto_node;3121 fn_entry->proto_node = proto_node;
3116 fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :3122 fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr :
...@@ -3209,7 +3215,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3209,7 +3215,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
32093215
3210 AstNode *fn_def_node = fn_proto->fn_def_node;3216 AstNode *fn_def_node = fn_proto->fn_def_node;
32113217
3212 ZigFn *fn_table_entry = create_fn(source_node);3218 ZigFn *fn_table_entry = create_fn(g, source_node);
3213 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');3219 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
32143220
3215 if (fn_proto->is_export) {3221 if (fn_proto->is_export) {
...@@ -3220,7 +3226,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3220,7 +3226,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3220 tld_fn->fn_entry = fn_table_entry;3226 tld_fn->fn_entry = fn_table_entry;
32213227
3222 if (fn_table_entry->body_node) {3228 if (fn_table_entry->body_node) {
3223 fn_table_entry->fndef_scope = create_fndef_scope(3229 fn_table_entry->fndef_scope = create_fndef_scope(g,
3224 fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry);3230 fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry);
32253231
3226 for (size_t i = 0; i < fn_proto->params.length; i += 1) {3232 for (size_t i = 0; i < fn_proto->params.length; i += 1) {
...@@ -3270,14 +3276,14 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3270,14 +3276,14 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3270 }3276 }
3271 }3277 }
3272 } else if (source_node->type == NodeTypeTestDecl) {3278 } else if (source_node->type == NodeTypeTestDecl) {
3273 ZigFn *fn_table_entry = create_fn_raw(FnInlineAuto);3279 ZigFn *fn_table_entry = create_fn_raw(g, FnInlineAuto);
32743280
3275 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');3281 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_');
32763282
3277 tld_fn->fn_entry = fn_table_entry;3283 tld_fn->fn_entry = fn_table_entry;
32783284
3279 fn_table_entry->proto_node = source_node;3285 fn_table_entry->proto_node = source_node;
3280 fn_table_entry->fndef_scope = create_fndef_scope(source_node, tld_fn->base.parent_scope, fn_table_entry);3286 fn_table_entry->fndef_scope = create_fndef_scope(g, source_node, tld_fn->base.parent_scope, fn_table_entry);
3281 fn_table_entry->type_entry = get_test_fn_type(g);3287 fn_table_entry->type_entry = get_test_fn_type(g);
3282 fn_table_entry->body_node = source_node->data.test_decl.body;3288 fn_table_entry->body_node = source_node->data.test_decl.body;
3283 fn_table_entry->is_test = true;3289 fn_table_entry->is_test = true;
...@@ -3606,7 +3612,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf...@@ -3606,7 +3612,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
36063612
3607 Scope *child_scope;3613 Scope *child_scope;
3608 if (source_node && source_node->type == NodeTypeParamDecl) {3614 if (source_node && source_node->type == NodeTypeParamDecl) {
3609 child_scope = create_var_scope(source_node, parent_scope, variable_entry);3615 child_scope = create_var_scope(g, source_node, parent_scope, variable_entry);
3610 } else {3616 } else {
3611 // it's already in the decls table3617 // it's already in the decls table
3612 child_scope = parent_scope;3618 child_scope = parent_scope;
...@@ -4329,7 +4335,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r...@@ -4329,7 +4335,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r
4329 g->import_table.put(resolved_path, import_entry);4335 g->import_table.put(resolved_path, import_entry);
4330 g->import_queue.append(import_entry);4336 g->import_queue.append(import_entry);
43314337
4332 import_entry->decls_scope = create_decls_scope(import_entry->root, nullptr, nullptr, import_entry);4338 import_entry->decls_scope = create_decls_scope(g, import_entry->root, nullptr, nullptr, import_entry);
43334339
43344340
4335 assert(import_entry->root->type == NodeTypeRoot);4341 assert(import_entry->root->type == NodeTypeRoot);
...@@ -4880,7 +4886,7 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {...@@ -4880,7 +4886,7 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) {
4880 if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) {4886 if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) {
4881 assert(a_val->special == ConstValSpecialStatic);4887 assert(a_val->special == ConstValSpecialStatic);
4882 assert(b_val->special == ConstValSpecialStatic);4888 assert(b_val->special == ConstValSpecialStatic);
4883 if (!const_values_equal(a_val, b_val)) {4889 if (!const_values_equal(a->fn_entry->codegen, a_val, b_val)) {
4884 return false;4890 return false;
4885 }4891 }
4886 } else {4892 } else {
...@@ -4920,14 +4926,18 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {...@@ -4920,14 +4926,18 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
4920 case ZigTypeIdArray:4926 case ZigTypeIdArray:
4921 if (value->type->data.array.len == 0)4927 if (value->type->data.array.len == 0)
4922 return false;4928 return false;
4923 if (value->data.x_array.special == ConstArraySpecialUndef)4929 switch (value->data.x_array.special) {
4924 return false;4930 case ConstArraySpecialUndef:
4925 for (uint32_t i = 0; i < value->type->data.array.len; i += 1) {4931 case ConstArraySpecialBuf:
4926 if (can_mutate_comptime_var_state(&value->data.x_array.s_none.elements[i]))4932 return false;
4927 return true;4933 case ConstArraySpecialNone:
4934 for (uint32_t i = 0; i < value->type->data.array.len; i += 1) {
4935 if (can_mutate_comptime_var_state(&value->data.x_array.data.s_none.elements[i]))
4936 return true;
4937 }
4938 return false;
4928 }4939 }
4929 return false;4940 zig_unreachable();
4930
4931 case ZigTypeIdStruct:4941 case ZigTypeIdStruct:
4932 for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) {4942 for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) {
4933 if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i]))4943 if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i]))
...@@ -5039,6 +5049,8 @@ uint32_t fn_eval_hash(Scope* scope) {...@@ -5039,6 +5049,8 @@ uint32_t fn_eval_hash(Scope* scope) {
5039}5049}
50405050
5041bool fn_eval_eql(Scope *a, Scope *b) {5051bool fn_eval_eql(Scope *a, Scope *b) {
5052 assert(a->codegen != nullptr);
5053 assert(b->codegen != nullptr);
5042 while (a && b) {5054 while (a && b) {
5043 if (a->id != b->id)5055 if (a->id != b->id)
5044 return false;5056 return false;
...@@ -5048,7 +5060,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {...@@ -5048,7 +5060,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {
5048 ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b;5060 ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b;
5049 if (a_var_scope->var->value->type != b_var_scope->var->value->type)5061 if (a_var_scope->var->value->type != b_var_scope->var->value->type)
5050 return false;5062 return false;
5051 if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value))5063 if (!const_values_equal(a->codegen, a_var_scope->var->value, b_var_scope->var->value))
5052 return false;5064 return false;
5053 } else if (a->id == ScopeIdFnDef) {5065 } else if (a->id == ScopeIdFnDef) {
5054 ScopeFnDef *a_fn_scope = (ScopeFnDef *)a;5066 ScopeFnDef *a_fn_scope = (ScopeFnDef *)a;
...@@ -5130,14 +5142,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {...@@ -5130,14 +5142,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
51305142
5131 const_val->special = ConstValSpecialStatic;5143 const_val->special = ConstValSpecialStatic;
5132 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));5144 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));
5133 const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str));5145 const_val->data.x_array.special = ConstArraySpecialBuf;
51345146 const_val->data.x_array.data.s_buf = str;
5135 for (size_t i = 0; i < buf_len(str); i += 1) {
5136 ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i];
5137 this_char->special = ConstValSpecialStatic;
5138 this_char->type = g->builtin_types.entry_u8;
5139 bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);
5140 }
51415147
5142 g->string_literals_table.put(str, const_val);5148 g->string_literals_table.put(str, const_val);
5143}5149}
...@@ -5154,14 +5160,15 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {...@@ -5154,14 +5160,15 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
5154 ConstExprValue *array_val = create_const_vals(1);5160 ConstExprValue *array_val = create_const_vals(1);
5155 array_val->special = ConstValSpecialStatic;5161 array_val->special = ConstValSpecialStatic;
5156 array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);5162 array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);
5157 array_val->data.x_array.s_none.elements = create_const_vals(len_with_null);5163 // TODO buf optimization
5164 array_val->data.x_array.data.s_none.elements = create_const_vals(len_with_null);
5158 for (size_t i = 0; i < buf_len(str); i += 1) {5165 for (size_t i = 0; i < buf_len(str); i += 1) {
5159 ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i];5166 ConstExprValue *this_char = &array_val->data.x_array.data.s_none.elements[i];
5160 this_char->special = ConstValSpecialStatic;5167 this_char->special = ConstValSpecialStatic;
5161 this_char->type = g->builtin_types.entry_u8;5168 this_char->type = g->builtin_types.entry_u8;
5162 bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);5169 bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);
5163 }5170 }
5164 ConstExprValue *null_char = &array_val->data.x_array.s_none.elements[len_with_null - 1];5171 ConstExprValue *null_char = &array_val->data.x_array.data.s_none.elements[len_with_null - 1];
5165 null_char->special = ConstValSpecialStatic;5172 null_char->special = ConstValSpecialStatic;
5166 null_char->type = g->builtin_types.entry_u8;5173 null_char->type = g->builtin_types.entry_u8;
5167 bigint_init_unsigned(&null_char->data.x_bigint, 0);5174 bigint_init_unsigned(&null_char->data.x_bigint, 0);
...@@ -5535,7 +5542,7 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) {...@@ -5535,7 +5542,7 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) {
5535 zig_unreachable();5542 zig_unreachable();
5536}5543}
55375544
5538bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {5545bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
5539 assert(a->type->id == b->type->id);5546 assert(a->type->id == b->type->id);
5540 assert(a->special == ConstValSpecialStatic);5547 assert(a->special == ConstValSpecialStatic);
5541 assert(b->special == ConstValSpecialStatic);5548 assert(b->special == ConstValSpecialStatic);
...@@ -5593,13 +5600,20 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -5593,13 +5600,20 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
5593 assert(a->type->data.array.len == b->type->data.array.len);5600 assert(a->type->data.array.len == b->type->data.array.len);
5594 assert(a->data.x_array.special != ConstArraySpecialUndef);5601 assert(a->data.x_array.special != ConstArraySpecialUndef);
5595 assert(b->data.x_array.special != ConstArraySpecialUndef);5602 assert(b->data.x_array.special != ConstArraySpecialUndef);
5603 if (a->data.x_array.special == ConstArraySpecialBuf &&
5604 b->data.x_array.special == ConstArraySpecialBuf)
5605 {
5606 return buf_eql_buf(a->data.x_array.data.s_buf, b->data.x_array.data.s_buf);
5607 }
5608 expand_undef_array(g, a);
5609 expand_undef_array(g, b);
55965610
5597 size_t len = a->type->data.array.len;5611 size_t len = a->type->data.array.len;
5598 ConstExprValue *a_elems = a->data.x_array.s_none.elements;5612 ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
5599 ConstExprValue *b_elems = b->data.x_array.s_none.elements;5613 ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;
56005614
5601 for (size_t i = 0; i < len; ++i) {5615 for (size_t i = 0; i < len; ++i) {
5602 if (!const_values_equal(&a_elems[i], &b_elems[i]))5616 if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
5603 return false;5617 return false;
5604 }5618 }
56055619
...@@ -5609,7 +5623,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -5609,7 +5623,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
5609 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {5623 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
5610 ConstExprValue *field_a = &a->data.x_struct.fields[i];5624 ConstExprValue *field_a = &a->data.x_struct.fields[i];
5611 ConstExprValue *field_b = &b->data.x_struct.fields[i];5625 ConstExprValue *field_b = &b->data.x_struct.fields[i];
5612 if (!const_values_equal(field_a, field_b))5626 if (!const_values_equal(g, field_a, field_b))
5613 return false;5627 return false;
5614 }5628 }
5615 return true;5629 return true;
...@@ -5623,7 +5637,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -5623,7 +5637,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
5623 if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) {5637 if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) {
5624 return (a->data.x_optional == nullptr && b->data.x_optional == nullptr);5638 return (a->data.x_optional == nullptr && b->data.x_optional == nullptr);
5625 } else {5639 } else {
5626 return const_values_equal(a->data.x_optional, b->data.x_optional);5640 return const_values_equal(g, a->data.x_optional, b->data.x_optional);
5627 }5641 }
5628 case ZigTypeIdErrorUnion:5642 case ZigTypeIdErrorUnion:
5629 zig_panic("TODO");5643 zig_panic("TODO");
...@@ -5808,26 +5822,15 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -5808,26 +5822,15 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
5808 case ZigTypeIdPointer:5822 case ZigTypeIdPointer:
5809 return render_const_val_ptr(g, buf, const_val, type_entry);5823 return render_const_val_ptr(g, buf, const_val, type_entry);
5810 case ZigTypeIdArray:5824 case ZigTypeIdArray:
5811 {5825 switch (const_val->data.x_array.special) {
5812 ZigType *child_type = type_entry->data.array.child_type;5826 case ConstArraySpecialUndef:
5813 uint64_t len = type_entry->data.array.len;
5814
5815 if (const_val->data.x_array.special == ConstArraySpecialUndef) {
5816 buf_append_str(buf, "undefined");5827 buf_append_str(buf, "undefined");
5817 return;5828 return;
5818 }5829 case ConstArraySpecialBuf: {
58195830 Buf *array_buf = const_val->data.x_array.data.s_buf;
5820 // if it's []u8, assume UTF-8 and output a string
5821 if (child_type->id == ZigTypeIdInt &&
5822 child_type->data.integral.bit_count == 8 &&
5823 !child_type->data.integral.is_signed)
5824 {
5825 buf_append_char(buf, '"');5831 buf_append_char(buf, '"');
5826 for (uint64_t i = 0; i < len; i += 1) {5832 for (size_t i = 0; i < buf_len(array_buf); i += 1) {
5827 ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];5833 uint8_t c = buf_ptr(array_buf)[i];
5828 uint64_t big_c = bigint_as_unsigned(&child_value->data.x_bigint);
5829 assert(big_c <= UINT8_MAX);
5830 uint8_t c = (uint8_t)big_c;
5831 if (c == '"') {5834 if (c == '"') {
5832 buf_append_str(buf, "\\\"");5835 buf_append_str(buf, "\\\"");
5833 } else {5836 } else {
...@@ -5837,17 +5840,20 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -5837,17 +5840,20 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
5837 buf_append_char(buf, '"');5840 buf_append_char(buf, '"');
5838 return;5841 return;
5839 }5842 }
58405843 case ConstArraySpecialNone: {
5841 buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));5844 buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
5842 for (uint64_t i = 0; i < len; i += 1) {5845 uint64_t len = type_entry->data.array.len;
5843 if (i != 0)5846 for (uint64_t i = 0; i < len; i += 1) {
5844 buf_appendf(buf, ",");5847 if (i != 0)
5845 ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];5848 buf_appendf(buf, ",");
5846 render_const_value(g, buf, child_value);5849 ConstExprValue *child_value = &const_val->data.x_array.data.s_none.elements[i];
5850 render_const_value(g, buf, child_value);
5851 }
5852 buf_appendf(buf, "}");
5853 return;
5847 }5854 }
5848 buf_appendf(buf, "}");
5849 return;
5850 }5855 }
5856 zig_unreachable();
5851 case ZigTypeIdNull:5857 case ZigTypeIdNull:
5852 {5858 {
5853 buf_appendf(buf, "null");5859 buf_appendf(buf, "null");
...@@ -6102,24 +6108,49 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {...@@ -6102,24 +6108,49 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
6102 zig_unreachable();6108 zig_unreachable();
6103}6109}
61046110
6111// Canonicalize the array value as ConstArraySpecialNone
6105void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {6112void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
6106 assert(const_val->type->id == ZigTypeIdArray);6113 assert(const_val->type->id == ZigTypeIdArray);
6107 if (const_val->data.x_array.special == ConstArraySpecialUndef) {6114 switch (const_val->data.x_array.special) {
6108 const_val->data.x_array.special = ConstArraySpecialNone;6115 case ConstArraySpecialNone:
6109 size_t elem_count = const_val->type->data.array.len;6116 return;
6110 const_val->data.x_array.s_none.elements = create_const_vals(elem_count);6117 case ConstArraySpecialUndef: {
6111 for (size_t i = 0; i < elem_count; i += 1) {6118 const_val->data.x_array.special = ConstArraySpecialNone;
6112 ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i];6119 size_t elem_count = const_val->type->data.array.len;
6113 element_val->type = const_val->type->data.array.child_type;6120 const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
6114 init_const_undefined(g, element_val);6121 for (size_t i = 0; i < elem_count; i += 1) {
6115 ConstParent *parent = get_const_val_parent(g, element_val);6122 ConstExprValue *element_val = &const_val->data.x_array.data.s_none.elements[i];
6116 if (parent != nullptr) {6123 element_val->type = const_val->type->data.array.child_type;
6117 parent->id = ConstParentIdArray;6124 init_const_undefined(g, element_val);
6118 parent->data.p_array.array_val = const_val;6125 ConstParent *parent = get_const_val_parent(g, element_val);
6119 parent->data.p_array.elem_index = i;6126 if (parent != nullptr) {
6127 parent->id = ConstParentIdArray;
6128 parent->data.p_array.array_val = const_val;
6129 parent->data.p_array.elem_index = i;
6130 }
6120 }6131 }
6132 return;
6133 }
6134 case ConstArraySpecialBuf: {
6135 Buf *buf = const_val->data.x_array.data.s_buf;
6136 // If we're doing this it means that we are potentially modifying the data,
6137 // so we can't have it be in the string literals table
6138 g->string_literals_table.maybe_remove(buf);
6139
6140 const_val->data.x_array.special = ConstArraySpecialNone;
6141 size_t elem_count = const_val->type->data.array.len;
6142 assert(elem_count == buf_len(buf));
6143 const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
6144 for (size_t i = 0; i < elem_count; i += 1) {
6145 ConstExprValue *this_char = &const_val->data.x_array.data.s_none.elements[i];
6146 this_char->special = ConstValSpecialStatic;
6147 this_char->type = g->builtin_types.entry_u8;
6148 bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(buf)[i]);
6149 }
6150 return;
6121 }6151 }
6122 }6152 }
6153 zig_unreachable();
6123}6154}
61246155
6125ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {6156ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
...@@ -6127,7 +6158,7 @@ ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {...@@ -6127,7 +6158,7 @@ ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
6127 ZigType *type_entry = value->type;6158 ZigType *type_entry = value->type;
6128 if (type_entry->id == ZigTypeIdArray) {6159 if (type_entry->id == ZigTypeIdArray) {
6129 expand_undef_array(g, value);6160 expand_undef_array(g, value);
6130 return &value->data.x_array.s_none.parent;6161 return &value->data.x_array.data.s_none.parent;
6131 } else if (type_entry->id == ZigTypeIdStruct) {6162 } else if (type_entry->id == ZigTypeIdStruct) {
6132 return &value->data.x_struct.parent;6163 return &value->data.x_struct.parent;
6133 } else if (type_entry->id == ZigTypeIdUnion) {6164 } else if (type_entry->id == ZigTypeIdUnion) {
src/analyze.hpp+15-15
...@@ -84,8 +84,8 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source...@@ -84,8 +84,8 @@ void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source
84ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name,84ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name,
85 bool is_const, ConstExprValue *init_value, Tld *src_tld);85 bool is_const, ConstExprValue *init_value, Tld *src_tld);
86ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node);86ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node);
87ZigFn *create_fn(AstNode *proto_node);87ZigFn *create_fn(CodeGen *g, AstNode *proto_node);
88ZigFn *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage);88ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value);
89void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);89void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc);
90AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);90AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index);
91bool type_requires_comptime(ZigType *type_entry);91bool type_requires_comptime(ZigType *type_entry);
...@@ -93,25 +93,25 @@ Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry);...@@ -93,25 +93,25 @@ Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry);
93Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status);93Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status);
94void complete_enum(CodeGen *g, ZigType *enum_type);94void complete_enum(CodeGen *g, ZigType *enum_type);
95bool ir_get_var_is_comptime(ZigVar *var);95bool ir_get_var_is_comptime(ZigVar *var);
96bool const_values_equal(ConstExprValue *a, ConstExprValue *b);96bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b);
97void eval_min_max_value(CodeGen *g, ZigType *type_entry, ConstExprValue *const_val, bool is_max);97void eval_min_max_value(CodeGen *g, ZigType *type_entry, ConstExprValue *const_val, bool is_max);
98void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool is_max);98void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool is_max);
9999
100void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val);100void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val);
101void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_type_node);101void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_type_node);
102102
103ScopeBlock *create_block_scope(AstNode *node, Scope *parent);103ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent);
104ScopeDefer *create_defer_scope(AstNode *node, Scope *parent);104ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent);
105ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent);105ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
106Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var);106Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var);
107ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent);107ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent);
108ScopeLoop *create_loop_scope(AstNode *node, Scope *parent);108ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
109ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent);109ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
110ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry);110ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
111ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import);111ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import);
112Scope *create_comptime_scope(AstNode *node, Scope *parent);112Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
113Scope *create_coro_prelude_scope(AstNode *node, Scope *parent);113Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent);
114Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime);114Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime);
115115
116void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str);116void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str);
117ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str);117ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str);
src/codegen.cpp+27-21
...@@ -5336,7 +5336,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent...@@ -5336,7 +5336,7 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent
53365336
5337static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {5337static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {
5338 expand_undef_array(g, array_const_val);5338 expand_undef_array(g, array_const_val);
5339 ConstParent *parent = &array_const_val->data.x_array.s_none.parent;5339 ConstParent *parent = &array_const_val->data.x_array.data.s_none.parent;
5340 LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);5340 LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);
53415341
5342 LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr)));5342 LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr)));
...@@ -5716,23 +5716,29 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -5716,23 +5716,29 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
5716 case ZigTypeIdArray:5716 case ZigTypeIdArray:
5717 {5717 {
5718 uint64_t len = type_entry->data.array.len;5718 uint64_t len = type_entry->data.array.len;
5719 if (const_val->data.x_array.special == ConstArraySpecialUndef) {5719 switch (const_val->data.x_array.special) {
5720 return LLVMGetUndef(type_entry->type_ref);5720 case ConstArraySpecialUndef:
5721 }5721 return LLVMGetUndef(type_entry->type_ref);
57225722 case ConstArraySpecialNone: {
5723 LLVMValueRef *values = allocate<LLVMValueRef>(len);5723 LLVMValueRef *values = allocate<LLVMValueRef>(len);
5724 LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;5724 LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref;
5725 bool make_unnamed_struct = false;5725 bool make_unnamed_struct = false;
5726 for (uint64_t i = 0; i < len; i += 1) {5726 for (uint64_t i = 0; i < len; i += 1) {
5727 ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i];5727 ConstExprValue *elem_value = &const_val->data.x_array.data.s_none.elements[i];
5728 LLVMValueRef val = gen_const_val(g, elem_value, "");5728 LLVMValueRef val = gen_const_val(g, elem_value, "");
5729 values[i] = val;5729 values[i] = val;
5730 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);5730 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val);
5731 }5731 }
5732 if (make_unnamed_struct) {5732 if (make_unnamed_struct) {
5733 return LLVMConstStruct(values, len, true);5733 return LLVMConstStruct(values, len, true);
5734 } else {5734 } else {
5735 return LLVMConstArray(element_type_ref, values, (unsigned)len);5735 return LLVMConstArray(element_type_ref, values, (unsigned)len);
5736 }
5737 }
5738 case ConstArraySpecialBuf: {
5739 Buf *buf = const_val->data.x_array.data.s_buf;
5740 return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true);
5741 }
5736 }5742 }
5737 }5743 }
5738 case ZigTypeIdUnion:5744 case ZigTypeIdUnion:
...@@ -7278,7 +7284,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) {...@@ -7278,7 +7284,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) {
7278 import->source_code = nullptr;7284 import->source_code = nullptr;
7279 import->path = full_path;7285 import->path = full_path;
7280 g->root_import = import;7286 g->root_import = import;
7281 import->decls_scope = create_decls_scope(nullptr, nullptr, nullptr, import);7287 import->decls_scope = create_decls_scope(g, nullptr, nullptr, nullptr, import);
72827288
7283 init(g);7289 init(g);
72847290
...@@ -7352,12 +7358,12 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {...@@ -7352,12 +7358,12 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
7352 ConstExprValue *test_fn_array = create_const_vals(1);7358 ConstExprValue *test_fn_array = create_const_vals(1);
7353 test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length);7359 test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length);
7354 test_fn_array->special = ConstValSpecialStatic;7360 test_fn_array->special = ConstValSpecialStatic;
7355 test_fn_array->data.x_array.s_none.elements = create_const_vals(g->test_fns.length);7361 test_fn_array->data.x_array.data.s_none.elements = create_const_vals(g->test_fns.length);
73567362
7357 for (size_t i = 0; i < g->test_fns.length; i += 1) {7363 for (size_t i = 0; i < g->test_fns.length; i += 1) {
7358 ZigFn *test_fn_entry = g->test_fns.at(i);7364 ZigFn *test_fn_entry = g->test_fns.at(i);
73597365
7360 ConstExprValue *this_val = &test_fn_array->data.x_array.s_none.elements[i];7366 ConstExprValue *this_val = &test_fn_array->data.x_array.data.s_none.elements[i];
7361 this_val->special = ConstValSpecialStatic;7367 this_val->special = ConstValSpecialStatic;
7362 this_val->type = struct_type;7368 this_val->type = struct_type;
7363 this_val->data.x_struct.parent.id = ConstParentIdArray;7369 this_val->data.x_struct.parent.id = ConstParentIdArray;
src/ir.cpp+71-64
...@@ -166,7 +166,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c...@@ -166,7 +166,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
166 break;166 break;
167 case ConstPtrSpecialBaseArray:167 case ConstPtrSpecialBaseArray:
168 expand_undef_array(g, const_val->data.x_ptr.data.base_array.array_val);168 expand_undef_array(g, const_val->data.x_ptr.data.base_array.array_val);
169 result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.s_none.elements[169 result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.data.s_none.elements[
170 const_val->data.x_ptr.data.base_array.elem_index];170 const_val->data.x_ptr.data.base_array.elem_index];
171 break;171 break;
172 case ConstPtrSpecialBaseStruct:172 case ConstPtrSpecialBaseStruct:
...@@ -3360,7 +3360,7 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s...@@ -3360,7 +3360,7 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s
3360 variable_entry->src_is_const = src_is_const;3360 variable_entry->src_is_const = src_is_const;
3361 variable_entry->gen_is_const = gen_is_const;3361 variable_entry->gen_is_const = gen_is_const;
3362 variable_entry->decl_node = node;3362 variable_entry->decl_node = node;
3363 variable_entry->child_scope = create_var_scope(node, parent_scope, variable_entry);3363 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry);
33643364
3365 return variable_entry;3365 return variable_entry;
3366}3366}
...@@ -3388,7 +3388,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode...@@ -3388,7 +3388,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
3388 ZigList<IrInstruction *> incoming_values = {0};3388 ZigList<IrInstruction *> incoming_values = {0};
3389 ZigList<IrBasicBlock *> incoming_blocks = {0};3389 ZigList<IrBasicBlock *> incoming_blocks = {0};
33903390
3391 ScopeBlock *scope_block = create_block_scope(block_node, parent_scope);3391 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope);
33923392
3393 Scope *outer_block_scope = &scope_block->base;3393 Scope *outer_block_scope = &scope_block->base;
3394 Scope *child_scope = outer_block_scope;3394 Scope *child_scope = outer_block_scope;
...@@ -5026,7 +5026,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode...@@ -5026,7 +5026,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
50265026
5027 ir_set_cursor_at_end_and_append_block(irb, then_block);5027 ir_set_cursor_at_end_and_append_block(irb, then_block);
50285028
5029 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);5029 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
5030 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope);5030 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope);
5031 if (then_expr_result == irb->codegen->invalid_instruction)5031 if (then_expr_result == irb->codegen->invalid_instruction)
5032 return then_expr_result;5032 return then_expr_result;
...@@ -5318,7 +5318,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5318,7 +5318,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5318 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline);5318 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline);
5319 ir_build_br(irb, scope, node, cond_block, is_comptime);5319 ir_build_br(irb, scope, node, cond_block, is_comptime);
53205320
5321 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);5321 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
5322 Buf *var_symbol = node->data.while_expr.var_symbol;5322 Buf *var_symbol = node->data.while_expr.var_symbol;
5323 Buf *err_symbol = node->data.while_expr.err_symbol;5323 Buf *err_symbol = node->data.while_expr.err_symbol;
5324 if (err_symbol != nullptr) {5324 if (err_symbol != nullptr) {
...@@ -5359,7 +5359,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5359,7 +5359,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5359 ZigList<IrInstruction *> incoming_values = {0};5359 ZigList<IrInstruction *> incoming_values = {0};
5360 ZigList<IrBasicBlock *> incoming_blocks = {0};5360 ZigList<IrBasicBlock *> incoming_blocks = {0};
53615361
5362 ScopeLoop *loop_scope = create_loop_scope(node, payload_scope);5362 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope);
5363 loop_scope->break_block = end_block;5363 loop_scope->break_block = end_block;
5364 loop_scope->continue_block = continue_block;5364 loop_scope->continue_block = continue_block;
5365 loop_scope->is_comptime = is_comptime;5365 loop_scope->is_comptime = is_comptime;
...@@ -5415,7 +5415,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5415,7 +5415,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5415 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);5415 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
5416 } else if (var_symbol != nullptr) {5416 } else if (var_symbol != nullptr) {
5417 ir_set_cursor_at_end_and_append_block(irb, cond_block);5417 ir_set_cursor_at_end_and_append_block(irb, cond_block);
5418 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);5418 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
5419 // TODO make it an error to write to payload variable5419 // TODO make it an error to write to payload variable
5420 AstNode *symbol_node = node; // TODO make more accurate5420 AstNode *symbol_node = node; // TODO make more accurate
54215421
...@@ -5443,7 +5443,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5443,7 +5443,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5443 ZigList<IrInstruction *> incoming_values = {0};5443 ZigList<IrInstruction *> incoming_values = {0};
5444 ZigList<IrBasicBlock *> incoming_blocks = {0};5444 ZigList<IrBasicBlock *> incoming_blocks = {0};
54455445
5446 ScopeLoop *loop_scope = create_loop_scope(node, child_scope);5446 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
5447 loop_scope->break_block = end_block;5447 loop_scope->break_block = end_block;
5448 loop_scope->continue_block = continue_block;5448 loop_scope->continue_block = continue_block;
5449 loop_scope->is_comptime = is_comptime;5449 loop_scope->is_comptime = is_comptime;
...@@ -5506,9 +5506,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n...@@ -5506,9 +5506,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
5506 ZigList<IrInstruction *> incoming_values = {0};5506 ZigList<IrInstruction *> incoming_values = {0};
5507 ZigList<IrBasicBlock *> incoming_blocks = {0};5507 ZigList<IrBasicBlock *> incoming_blocks = {0};
55085508
5509 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);5509 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
55105510
5511 ScopeLoop *loop_scope = create_loop_scope(node, subexpr_scope);5511 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope);
5512 loop_scope->break_block = end_block;5512 loop_scope->break_block = end_block;
5513 loop_scope->continue_block = continue_block;5513 loop_scope->continue_block = continue_block;
5514 loop_scope->is_comptime = is_comptime;5514 loop_scope->is_comptime = is_comptime;
...@@ -5645,7 +5645,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -5645,7 +5645,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
56455645
5646 ZigList<IrInstruction *> incoming_values = {0};5646 ZigList<IrInstruction *> incoming_values = {0};
5647 ZigList<IrBasicBlock *> incoming_blocks = {0};5647 ZigList<IrBasicBlock *> incoming_blocks = {0};
5648 ScopeLoop *loop_scope = create_loop_scope(node, child_scope);5648 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope);
5649 loop_scope->break_block = end_block;5649 loop_scope->break_block = end_block;
5650 loop_scope->continue_block = continue_block;5650 loop_scope->continue_block = continue_block;
5651 loop_scope->is_comptime = is_comptime;5651 loop_scope->is_comptime = is_comptime;
...@@ -5855,7 +5855,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no...@@ -5855,7 +5855,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
58555855
5856 ir_set_cursor_at_end_and_append_block(irb, then_block);5856 ir_set_cursor_at_end_and_append_block(irb, then_block);
58575857
5858 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);5858 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
5859 Scope *var_scope;5859 Scope *var_scope;
5860 if (var_symbol) {5860 if (var_symbol) {
5861 IrInstruction *var_type = nullptr;5861 IrInstruction *var_type = nullptr;
...@@ -5930,7 +5930,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -5930,7 +5930,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
59305930
5931 ir_set_cursor_at_end_and_append_block(irb, ok_block);5931 ir_set_cursor_at_end_and_append_block(irb, ok_block);
59325932
5933 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);5933 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
5934 Scope *var_scope;5934 Scope *var_scope;
5935 if (var_symbol) {5935 if (var_symbol) {
5936 IrInstruction *var_type = nullptr;5936 IrInstruction *var_type = nullptr;
...@@ -6066,8 +6066,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6066,8 +6066,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
6066 ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0};6066 ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0};
60676067
6068 // First do the else and the ranges6068 // First do the else and the ranges
6069 Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime);6069 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
6070 Scope *comptime_scope = create_comptime_scope(node, scope);6070 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
6071 AstNode *else_prong = nullptr;6071 AstNode *else_prong = nullptr;
6072 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {6072 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
6073 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);6073 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
...@@ -6231,7 +6231,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6231,7 +6231,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
6231static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {6231static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {
6232 assert(node->type == NodeTypeCompTime);6232 assert(node->type == NodeTypeCompTime);
62336233
6234 Scope *child_scope = create_comptime_scope(node, parent_scope);6234 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope);
6235 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval);6235 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval);
6236}6236}
62376237
...@@ -6394,10 +6394,10 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n...@@ -6394,10 +6394,10 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n
6394static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {6394static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
6395 assert(node->type == NodeTypeDefer);6395 assert(node->type == NodeTypeDefer);
63966396
6397 ScopeDefer *defer_child_scope = create_defer_scope(node, parent_scope);6397 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope);
6398 node->data.defer.child_scope = &defer_child_scope->base;6398 node->data.defer.child_scope = &defer_child_scope->base;
63996399
6400 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(node, parent_scope);6400 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope);
6401 node->data.defer.expr_scope = &defer_expr_scope->base;6401 node->data.defer.expr_scope = &defer_expr_scope->base;
64026402
6403 return ir_build_const_void(irb, parent_scope, node);6403 return ir_build_const_void(irb, parent_scope, node);
...@@ -7154,7 +7154,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod...@@ -7154,7 +7154,7 @@ static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNod
7154 suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false);7154 suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false);
7155 } else {7155 } else {
7156 Scope *child_scope;7156 Scope *child_scope;
7157 ScopeSuspend *suspend_scope = create_suspend_scope(node, parent_scope);7157 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope);
7158 suspend_scope->resume_block = resume_block;7158 suspend_scope->resume_block = resume_block;
7159 child_scope = &suspend_scope->base;7159 child_scope = &suspend_scope->base;
7160 IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle);7160 IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle);
...@@ -7370,7 +7370,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -7370,7 +7370,7 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
7370 ZigVar *coro_size_var;7370 ZigVar *coro_size_var;
7371 if (is_async) {7371 if (is_async) {
7372 // create the coro promise7372 // create the coro promise
7373 Scope *coro_scope = create_coro_prelude_scope(node, scope);7373 Scope *coro_scope = create_coro_prelude_scope(irb->codegen, node, scope);
7374 const_bool_false = ir_build_const_bool(irb, coro_scope, node, false);7374 const_bool_false = ir_build_const_bool(irb, coro_scope, node, false);
7375 ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);7375 ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
73767376
...@@ -10569,9 +10569,9 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou...@@ -10569,9 +10569,9 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou
10569 array_val->special = ConstValSpecialStatic;10569 array_val->special = ConstValSpecialStatic;
10570 array_val->type = array_type;10570 array_val->type = array_type;
10571 array_val->data.x_array.special = ConstArraySpecialNone;10571 array_val->data.x_array.special = ConstArraySpecialNone;
10572 array_val->data.x_array.s_none.elements = pointee;10572 array_val->data.x_array.data.s_none.elements = pointee;
10573 array_val->data.x_array.s_none.parent.id = ConstParentIdScalar;10573 array_val->data.x_array.data.s_none.parent.id = ConstParentIdScalar;
10574 array_val->data.x_array.s_none.parent.data.p_scalar.scalar_val = pointee;10574 array_val->data.x_array.data.s_none.parent.data.p_scalar.scalar_val = pointee;
1057510575
10576 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,10576 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
10577 source_instr->scope, source_instr->source_node);10577 source_instr->scope, source_instr->source_node);
...@@ -11391,13 +11391,16 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {...@@ -11391,13 +11391,16 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
1139111391
11392 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);11392 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
11393 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;11393 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
11394 if (array_val->data.x_array.special == ConstArraySpecialBuf) {
11395 return array_val->data.x_array.data.s_buf;
11396 }
11394 expand_undef_array(ira->codegen, array_val);11397 expand_undef_array(ira->codegen, array_val);
11395 size_t len = bigint_as_unsigned(&len_field->data.x_bigint);11398 size_t len = bigint_as_unsigned(&len_field->data.x_bigint);
11396 Buf *result = buf_alloc();11399 Buf *result = buf_alloc();
11397 buf_resize(result, len);11400 buf_resize(result, len);
11398 for (size_t i = 0; i < len; i += 1) {11401 for (size_t i = 0; i < len; i += 1) {
11399 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;11402 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i;
11400 ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index];11403 ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index];
11401 if (char_val->special == ConstValSpecialUndef) {11404 if (char_val->special == ConstValSpecialUndef) {
11402 ir_add_error(ira, casted_value, buf_sprintf("use of undefined value"));11405 ir_add_error(ira, casted_value, buf_sprintf("use of undefined value"));
11403 return nullptr;11406 return nullptr;
...@@ -11750,7 +11753,7 @@ static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op...@@ -11750,7 +11753,7 @@ static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op
11750 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);11753 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);
11751 answer = resolve_cmp_op_id(op_id, cmp_result);11754 answer = resolve_cmp_op_id(op_id, cmp_result);
11752 } else {11755 } else {
11753 bool are_equal = one_possible_value || const_values_equal(op1_val, op2_val);11756 bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val);
11754 if (op_id == IrBinOpCmpEq) {11757 if (op_id == IrBinOpCmpEq) {
11755 answer = are_equal;11758 answer = are_equal;
11756 } else if (op_id == IrBinOpCmpNotEq) {11759 } else if (op_id == IrBinOpCmpNotEq) {
...@@ -12463,19 +12466,20 @@ static ZigType *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruc...@@ -12463,19 +12466,20 @@ static ZigType *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruc
12463 return result_type;12466 return result_type;
12464 }12467 }
1246512468
12466 out_array_val->data.x_array.s_none.elements = create_const_vals(new_len);12469 out_array_val->data.x_array.data.s_none.elements = create_const_vals(new_len);
12470 // TODO handle the buf case here for an optimization
12467 expand_undef_array(ira->codegen, op1_array_val);12471 expand_undef_array(ira->codegen, op1_array_val);
12468 expand_undef_array(ira->codegen, op2_array_val);12472 expand_undef_array(ira->codegen, op2_array_val);
1246912473
12470 size_t next_index = 0;12474 size_t next_index = 0;
12471 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {12475 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) {
12472 out_array_val->data.x_array.s_none.elements[next_index] = op1_array_val->data.x_array.s_none.elements[i];12476 out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i];
12473 }12477 }
12474 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {12478 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) {
12475 out_array_val->data.x_array.s_none.elements[next_index] = op2_array_val->data.x_array.s_none.elements[i];12479 out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i];
12476 }12480 }
12477 if (next_index < new_len) {12481 if (next_index < new_len) {
12478 ConstExprValue *null_byte = &out_array_val->data.x_array.s_none.elements[next_index];12482 ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index];
12479 init_const_unsigned_negative(null_byte, child_type, 0, false);12483 init_const_unsigned_negative(null_byte, child_type, 0, false);
12480 next_index += 1;12484 next_index += 1;
12481 }12485 }
...@@ -12524,12 +12528,14 @@ static ZigType *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instru...@@ -12524,12 +12528,14 @@ static ZigType *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instru
12524 return get_array_type(ira->codegen, child_type, new_array_len);12528 return get_array_type(ira->codegen, child_type, new_array_len);
12525 }12529 }
1252612530
12527 out_val->data.x_array.s_none.elements = create_const_vals(new_array_len);12531 // TODO optimize the buf case
12532 expand_undef_array(ira->codegen, array_val);
12533 out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len);
1252812534
12529 uint64_t i = 0;12535 uint64_t i = 0;
12530 for (uint64_t x = 0; x < mult_amt; x += 1) {12536 for (uint64_t x = 0; x < mult_amt; x += 1) {
12531 for (uint64_t y = 0; y < old_array_len; y += 1) {12537 for (uint64_t y = 0; y < old_array_len; y += 1) {
12532 out_val->data.x_array.s_none.elements[i] = array_val->data.x_array.s_none.elements[y];12538 out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y];
12533 i += 1;12539 i += 1;
12534 }12540 }
12535 }12541 }
...@@ -13502,10 +13508,10 @@ static ZigType *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instr...@@ -13502,10 +13508,10 @@ static ZigType *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instr
1350213508
13503 // Fork a scope of the function with known values for the parameters.13509 // Fork a scope of the function with known values for the parameters.
13504 Scope *parent_scope = fn_entry->fndef_scope->base.parent;13510 Scope *parent_scope = fn_entry->fndef_scope->base.parent;
13505 ZigFn *impl_fn = create_fn(fn_proto_node);13511 ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node);
13506 impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count);13512 impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count);
13507 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);13513 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
13508 impl_fn->fndef_scope = create_fndef_scope(impl_fn->body_node, parent_scope, impl_fn);13514 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn);
13509 impl_fn->child_scope = &impl_fn->fndef_scope->base;13515 impl_fn->child_scope = &impl_fn->fndef_scope->base;
13510 FnTypeId inst_fn_type_id = {0};13516 FnTypeId inst_fn_type_id = {0};
13511 init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count);13517 init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count);
...@@ -16073,7 +16079,7 @@ static ZigType *ir_analyze_instruction_switch_br(IrAnalyze *ira,...@@ -16073,7 +16079,7 @@ static ZigType *ir_analyze_instruction_switch_br(IrAnalyze *ira,
16073 if (!case_val)16079 if (!case_val)
16074 return ir_unreach_error(ira);16080 return ir_unreach_error(ira);
1607516081
16076 if (const_values_equal(target_val, case_val)) {16082 if (const_values_equal(ira->codegen, target_val, case_val)) {
16077 old_dest_block = old_case->block;16083 old_dest_block = old_case->block;
16078 break;16084 break;
16079 }16085 }
...@@ -16652,7 +16658,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -16652,7 +16658,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
16652 ConstExprValue const_val = {};16658 ConstExprValue const_val = {};
16653 const_val.special = ConstValSpecialStatic;16659 const_val.special = ConstValSpecialStatic;
16654 const_val.type = fixed_size_array_type;16660 const_val.type = fixed_size_array_type;
16655 const_val.data.x_array.s_none.elements = create_const_vals(elem_count);16661 const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count);
1665616662
16657 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);16663 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
1665816664
...@@ -16677,7 +16683,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -16677,7 +16683,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
16677 if (!elem_val)16683 if (!elem_val)
16678 return ira->codegen->builtin_types.entry_invalid;16684 return ira->codegen->builtin_types.entry_invalid;
1667916685
16680 copy_const_val(&const_val.data.x_array.s_none.elements[i], elem_val, true);16686 copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true);
16681 } else {16687 } else {
16682 first_non_const_instruction = casted_arg;16688 first_non_const_instruction = casted_arg;
16683 const_val.special = ConstValSpecialRuntime;16689 const_val.special = ConstValSpecialRuntime;
...@@ -16689,7 +16695,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -16689,7 +16695,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
16689 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);16695 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
16690 *out_val = const_val;16696 *out_val = const_val;
16691 for (size_t i = 0; i < elem_count; i += 1) {16697 for (size_t i = 0; i < elem_count; i += 1) {
16692 ConstExprValue *elem_val = &out_val->data.x_array.s_none.elements[i];16698 ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i];
16693 ConstParent *parent = get_const_val_parent(ira->codegen, elem_val);16699 ConstParent *parent = get_const_val_parent(ira->codegen, elem_val);
16694 if (parent != nullptr) {16700 if (parent != nullptr) {
16695 parent->id = ConstParentIdArray;16701 parent->id = ConstParentIdArray;
...@@ -17146,8 +17152,8 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco...@@ -17146,8 +17152,8 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
17146 definition_array->special = ConstValSpecialStatic;17152 definition_array->special = ConstValSpecialStatic;
17147 definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count);17153 definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count);
17148 definition_array->data.x_array.special = ConstArraySpecialNone;17154 definition_array->data.x_array.special = ConstArraySpecialNone;
17149 definition_array->data.x_array.s_none.parent.id = ConstParentIdNone;17155 definition_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
17150 definition_array->data.x_array.s_none.elements = create_const_vals(definition_count);17156 definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count);
17151 init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false);17157 init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false);
1715217158
17153 // Loop through the definitions and generate info.17159 // Loop through the definitions and generate info.
...@@ -17164,7 +17170,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco...@@ -17164,7 +17170,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
17164 continue;17170 continue;
17165 }17171 }
1716617172
17167 ConstExprValue *definition_val = &definition_array->data.x_array.s_none.elements[definition_index];17173 ConstExprValue *definition_val = &definition_array->data.x_array.data.s_none.elements[definition_index];
1716817174
17169 definition_val->special = ConstValSpecialStatic;17175 definition_val->special = ConstValSpecialStatic;
17170 definition_val->type = type_info_definition_type;17176 definition_val->type = type_info_definition_type;
...@@ -17293,15 +17299,15 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco...@@ -17293,15 +17299,15 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
17293 fn_arg_name_array->type = get_array_type(ira->codegen,17299 fn_arg_name_array->type = get_array_type(ira->codegen,
17294 get_slice_type(ira->codegen, u8_ptr), fn_arg_count);17300 get_slice_type(ira->codegen, u8_ptr), fn_arg_count);
17295 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;17301 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
17296 fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone;17302 fn_arg_name_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
17297 fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count);17303 fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
1729817304
17299 init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false);17305 init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false);
1730017306
17301 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++)17307 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++)
17302 {17308 {
17303 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);17309 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);
17304 ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.s_none.elements[fn_arg_index];17310 ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index];
17305 ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name);17311 ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name);
17306 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true);17312 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true);
17307 fn_arg_name_val->data.x_struct.parent.id = ConstParentIdArray;17313 fn_arg_name_val->data.x_struct.parent.id = ConstParentIdArray;
...@@ -17593,15 +17599,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE...@@ -17593,15 +17599,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
17593 enum_field_array->special = ConstValSpecialStatic;17599 enum_field_array->special = ConstValSpecialStatic;
17594 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count);17600 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count);
17595 enum_field_array->data.x_array.special = ConstArraySpecialNone;17601 enum_field_array->data.x_array.special = ConstArraySpecialNone;
17596 enum_field_array->data.x_array.s_none.parent.id = ConstParentIdNone;17602 enum_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
17597 enum_field_array->data.x_array.s_none.elements = create_const_vals(enum_field_count);17603 enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count);
1759817604
17599 init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false);17605 init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false);
1760017606
17601 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++)17607 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++)
17602 {17608 {
17603 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index];17609 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index];
17604 ConstExprValue *enum_field_val = &enum_field_array->data.x_array.s_none.elements[enum_field_index];17610 ConstExprValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index];
17605 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type);17611 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type);
17606 enum_field_val->data.x_struct.parent.id = ConstParentIdArray;17612 enum_field_val->data.x_struct.parent.id = ConstParentIdArray;
17607 enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array;17613 enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array;
...@@ -17632,13 +17638,13 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE...@@ -17632,13 +17638,13 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
17632 error_array->special = ConstValSpecialStatic;17638 error_array->special = ConstValSpecialStatic;
17633 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count);17639 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count);
17634 error_array->data.x_array.special = ConstArraySpecialNone;17640 error_array->data.x_array.special = ConstArraySpecialNone;
17635 error_array->data.x_array.s_none.parent.id = ConstParentIdNone;17641 error_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
17636 error_array->data.x_array.s_none.elements = create_const_vals(error_count);17642 error_array->data.x_array.data.s_none.elements = create_const_vals(error_count);
1763717643
17638 init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false);17644 init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false);
17639 for (uint32_t error_index = 0; error_index < error_count; error_index++) {17645 for (uint32_t error_index = 0; error_index < error_count; error_index++) {
17640 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index];17646 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index];
17641 ConstExprValue *error_val = &error_array->data.x_array.s_none.elements[error_index];17647 ConstExprValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index];
1764217648
17643 error_val->special = ConstValSpecialStatic;17649 error_val->special = ConstValSpecialStatic;
17644 error_val->type = type_info_error_type;17650 error_val->type = type_info_error_type;
...@@ -17727,8 +17733,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE...@@ -17727,8 +17733,8 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
17727 union_field_array->special = ConstValSpecialStatic;17733 union_field_array->special = ConstValSpecialStatic;
17728 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count);17734 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count);
17729 union_field_array->data.x_array.special = ConstArraySpecialNone;17735 union_field_array->data.x_array.special = ConstArraySpecialNone;
17730 union_field_array->data.x_array.s_none.parent.id = ConstParentIdNone;17736 union_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
17731 union_field_array->data.x_array.s_none.elements = create_const_vals(union_field_count);17737 union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count);
1773217738
17733 init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false);17739 init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false);
1773417740
...@@ -17736,7 +17742,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE...@@ -17736,7 +17742,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
1773617742
17737 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) {17743 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) {
17738 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index];17744 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index];
17739 ConstExprValue *union_field_val = &union_field_array->data.x_array.s_none.elements[union_field_index];17745 ConstExprValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index];
1774017746
17741 union_field_val->special = ConstValSpecialStatic;17747 union_field_val->special = ConstValSpecialStatic;
17742 union_field_val->type = type_info_union_field_type;17748 union_field_val->type = type_info_union_field_type;
...@@ -17800,14 +17806,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE...@@ -17800,14 +17806,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
17800 struct_field_array->special = ConstValSpecialStatic;17806 struct_field_array->special = ConstValSpecialStatic;
17801 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count);17807 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count);
17802 struct_field_array->data.x_array.special = ConstArraySpecialNone;17808 struct_field_array->data.x_array.special = ConstArraySpecialNone;
17803 struct_field_array->data.x_array.s_none.parent.id = ConstParentIdNone;17809 struct_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
17804 struct_field_array->data.x_array.s_none.elements = create_const_vals(struct_field_count);17810 struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count);
1780517811
17806 init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false);17812 init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false);
1780717813
17808 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) {17814 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) {
17809 TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index];17815 TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index];
17810 ConstExprValue *struct_field_val = &struct_field_array->data.x_array.s_none.elements[struct_field_index];17816 ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index];
1781117817
17812 struct_field_val->special = ConstValSpecialStatic;17818 struct_field_val->special = ConstValSpecialStatic;
17813 struct_field_val->type = type_info_struct_field_type;17819 struct_field_val->type = type_info_struct_field_type;
...@@ -17906,15 +17912,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE...@@ -17906,15 +17912,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
17906 fn_arg_array->special = ConstValSpecialStatic;17912 fn_arg_array->special = ConstValSpecialStatic;
17907 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count);17913 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count);
17908 fn_arg_array->data.x_array.special = ConstArraySpecialNone;17914 fn_arg_array->data.x_array.special = ConstArraySpecialNone;
17909 fn_arg_array->data.x_array.s_none.parent.id = ConstParentIdNone;17915 fn_arg_array->data.x_array.data.s_none.parent.id = ConstParentIdNone;
17910 fn_arg_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count);17916 fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
1791117917
17912 init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false);17918 init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false);
1791317919
17914 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++)17920 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++)
17915 {17921 {
17916 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index];17922 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index];
17917 ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.s_none.elements[fn_arg_index];17923 ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index];
1791817924
17919 fn_arg_val->special = ConstValSpecialStatic;17925 fn_arg_val->special = ConstValSpecialStatic;
17920 fn_arg_val->type = type_info_fn_arg_type;17926 fn_arg_val->type = type_info_fn_arg_type;
...@@ -18059,7 +18065,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm...@@ -18059,7 +18065,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm
18059 assert(node->type == NodeTypeFnCallExpr);18065 assert(node->type == NodeTypeFnCallExpr);
18060 AstNode *block_node = node->data.fn_call_expr.params.at(0);18066 AstNode *block_node = node->data.fn_call_expr.params.at(0);
1806118067
18062 ScopeCImport *cimport_scope = create_cimport_scope(node, instruction->base.scope);18068 ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope);
1806318069
18064 // Execute the C import block like an inline function18070 // Execute the C import block like an inline function
18065 ZigType *void_type = ira->codegen->builtin_types.entry_void;18071 ZigType *void_type = ira->codegen->builtin_types.entry_void;
...@@ -18072,7 +18078,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm...@@ -18072,7 +18078,7 @@ static ZigType *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCIm
18072 find_libc_include_path(ira->codegen);18078 find_libc_include_path(ira->codegen);
1807318079
18074 ImportTableEntry *child_import = allocate<ImportTableEntry>(1);18080 ImportTableEntry *child_import = allocate<ImportTableEntry>(1);
18075 child_import->decls_scope = create_decls_scope(node, nullptr, nullptr, child_import);18081 child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import);
18076 child_import->c_import_node = node;18082 child_import->c_import_node = node;
18077 child_import->package = new_anonymous_package();18083 child_import->package = new_anonymous_package();
18078 child_import->package->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package);18084 child_import->package->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package);
...@@ -18826,7 +18832,7 @@ static ZigType *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemse...@@ -18826,7 +18832,7 @@ static ZigType *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemse
18826 {18832 {
18827 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;18833 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
18828 expand_undef_array(ira->codegen, array_val);18834 expand_undef_array(ira->codegen, array_val);
18829 dest_elements = array_val->data.x_array.s_none.elements;18835 dest_elements = array_val->data.x_array.data.s_none.elements;
18830 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;18836 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;
18831 bound_end = array_val->type->data.array.len;18837 bound_end = array_val->type->data.array.len;
18832 break;18838 break;
...@@ -18940,7 +18946,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp...@@ -18940,7 +18946,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp
18940 {18946 {
18941 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;18947 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val;
18942 expand_undef_array(ira->codegen, array_val);18948 expand_undef_array(ira->codegen, array_val);
18943 dest_elements = array_val->data.x_array.s_none.elements;18949 dest_elements = array_val->data.x_array.data.s_none.elements;
18944 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;18950 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index;
18945 dest_end = array_val->type->data.array.len;18951 dest_end = array_val->type->data.array.len;
18946 break;18952 break;
...@@ -18976,7 +18982,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp...@@ -18976,7 +18982,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp
18976 {18982 {
18977 ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val;18983 ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val;
18978 expand_undef_array(ira->codegen, array_val);18984 expand_undef_array(ira->codegen, array_val);
18979 src_elements = array_val->data.x_array.s_none.elements;18985 src_elements = array_val->data.x_array.data.s_none.elements;
18980 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index;18986 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index;
18981 src_end = array_val->type->data.array.len;18987 src_end = array_val->type->data.array.len;
18982 break;18988 break;
...@@ -20282,9 +20288,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -20282,9 +20288,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
20282 case ZigTypeIdArray:20288 case ZigTypeIdArray:
20283 {20289 {
20284 size_t buf_i = 0;20290 size_t buf_i = 0;
20291 // TODO optimize the buf case
20285 expand_undef_array(codegen, val);20292 expand_undef_array(codegen, val);
20286 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) {20293 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) {
20287 ConstExprValue *elem = &val->data.x_array.s_none.elements[elem_i];20294 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i];
20288 buf_write_value_bytes(codegen, &buf[buf_i], elem);20295 buf_write_value_bytes(codegen, &buf[buf_i], elem);
20289 buf_i += type_size(codegen, elem->type);20296 buf_i += type_size(codegen, elem->type);
20290 }20297 }
test/behavior.zig+1
...@@ -8,6 +8,7 @@ comptime {...@@ -8,6 +8,7 @@ comptime {
8 _ = @import("cases/atomics.zig");8 _ = @import("cases/atomics.zig");
9 _ = @import("cases/bitcast.zig");9 _ = @import("cases/bitcast.zig");
10 _ = @import("cases/bool.zig");10 _ = @import("cases/bool.zig");
11 _ = @import("cases/bugs/1076.zig");
11 _ = @import("cases/bugs/1111.zig");12 _ = @import("cases/bugs/1111.zig");
12 _ = @import("cases/bugs/1277.zig");13 _ = @import("cases/bugs/1277.zig");
13 _ = @import("cases/bugs/1322.zig");14 _ = @import("cases/bugs/1322.zig");
test/cases/bugs/1076.zig created+16
...@@ -0,0 +1,16 @@
1const std = @import("std");
2const mem = std.mem;
3const assert = std.debug.assert;
4
5test "comptime code should not modify constant data" {
6 testCastPtrOfArrayToSliceAndPtr();
7 comptime testCastPtrOfArrayToSliceAndPtr();
8}
9
10fn testCastPtrOfArrayToSliceAndPtr() void {
11 var array = "aoeu";
12 const x: [*]u8 = &array;
13 x[0] += 1;
14 assert(mem.eql(u8, array[0..], "boeu"));
15}
16
test/cases/cast.zig+1-1
...@@ -400,7 +400,7 @@ test "single-item pointer of array to slice and to unknown length pointer" {...@@ -400,7 +400,7 @@ test "single-item pointer of array to slice and to unknown length pointer" {
400}400}
401401
402fn testCastPtrOfArrayToSliceAndPtr() void {402fn testCastPtrOfArrayToSliceAndPtr() void {
403 var array = "ao" ++ "eu"; // TODO https://github.com/ziglang/zig/issues/1076403 var array = "aoeu";
404 const x: [*]u8 = &array;404 const x: [*]u8 = &array;
405 x[0] += 1;405 x[0] += 1;
406 assert(mem.eql(u8, array[0..], "boeu"));406 assert(mem.eql(u8, array[0..], "boeu"));