| author | |
| committer | |
| log | f8fe517d126d582e37ab4537fe9fd42f0531f44b |
| tree | 040baa17d21eb30b1dc7d2a4ef470fe7aea08e85 |
| parent | 492821781dc34659f694577aacbc853c8839406f |
| signature |
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 #10768 files changed, 278 insertions(+), 210 deletions(-)
src/all_types.hpp+12-5| ... | ... | @@ -130,14 +130,18 @@ struct ConstUnionValue { |
| 130 | 130 | enum ConstArraySpecial { |
| 131 | 131 | ConstArraySpecialNone, |
| 132 | 132 | ConstArraySpecialUndef, |
| 133 | ConstArraySpecialBuf, | |
| 133 | 134 | }; |
| 134 | 135 | |
| 135 | 136 | struct ConstArrayValue { |
| 136 | 137 | ConstArraySpecial special; |
| 137 | struct { | |
| 138 | ConstExprValue *elements; | |
| 139 | ConstParent parent; | |
| 140 | } s_none; | |
| 138 | union { | |
| 139 | struct { | |
| 140 | ConstExprValue *elements; | |
| 141 | ConstParent parent; | |
| 142 | } s_none; | |
| 143 | Buf *s_buf; | |
| 144 | } data; | |
| 141 | 145 | }; |
| 142 | 146 | |
| 143 | 147 | enum ConstPtrSpecial { |
| ... | ... | @@ -983,6 +987,7 @@ struct FnTypeParamInfo { |
| 983 | 987 | }; |
| 984 | 988 | |
| 985 | 989 | struct GenericFnTypeId { |
| 990 | CodeGen *codegen; | |
| 986 | 991 | ZigFn *fn_entry; |
| 987 | 992 | ConstExprValue *params; |
| 988 | 993 | size_t param_count; |
| ... | ... | @@ -1291,6 +1296,7 @@ struct FnExport { |
| 1291 | 1296 | }; |
| 1292 | 1297 | |
| 1293 | 1298 | struct ZigFn { |
| 1299 | CodeGen *codegen; | |
| 1294 | 1300 | LLVMValueRef llvm_value; |
| 1295 | 1301 | const char *llvm_name; |
| 1296 | 1302 | AstNode *proto_node; |
| ... | ... | @@ -1848,13 +1854,14 @@ enum ScopeId { |
| 1848 | 1854 | }; |
| 1849 | 1855 | |
| 1850 | 1856 | struct Scope { |
| 1851 | ScopeId id; | |
| 1857 | CodeGen *codegen; | |
| 1852 | 1858 | AstNode *source_node; |
| 1853 | 1859 | |
| 1854 | 1860 | // if the scope has a parent, this is it |
| 1855 | 1861 | Scope *parent; |
| 1856 | 1862 | |
| 1857 | 1863 | ZigLLVMDIScope *di_scope; |
| 1864 | ScopeId id; | |
| 1858 | 1865 | }; |
| 1859 | 1866 | |
| 1860 | 1867 | // 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 | 92 | return *get_container_scope_ptr(type_entry); |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) { | |
| 95 | void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) { | |
| 96 | dest->codegen = g; | |
| 96 | 97 | dest->id = id; |
| 97 | 98 | dest->source_node = source_node; |
| 98 | 99 | dest->parent = parent; |
| 99 | 100 | } |
| 100 | 101 | |
| 101 | ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) { | |
| 102 | ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import) { | |
| 102 | 103 | assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr); |
| 103 | 104 | ScopeDecls *scope = allocate<ScopeDecls>(1); |
| 104 | init_scope(&scope->base, ScopeIdDecls, node, parent); | |
| 105 | init_scope(g, &scope->base, ScopeIdDecls, node, parent); | |
| 105 | 106 | scope->decl_table.init(4); |
| 106 | 107 | scope->container_type = container_type; |
| 107 | 108 | scope->import = import; |
| 108 | 109 | return scope; |
| 109 | 110 | } |
| 110 | 111 | |
| 111 | ScopeBlock *create_block_scope(AstNode *node, Scope *parent) { | |
| 112 | ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent) { | |
| 112 | 113 | assert(node->type == NodeTypeBlock); |
| 113 | 114 | ScopeBlock *scope = allocate<ScopeBlock>(1); |
| 114 | init_scope(&scope->base, ScopeIdBlock, node, parent); | |
| 115 | init_scope(g, &scope->base, ScopeIdBlock, node, parent); | |
| 115 | 116 | scope->name = node->data.block.name; |
| 116 | 117 | return scope; |
| 117 | 118 | } |
| 118 | 119 | |
| 119 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) { | |
| 120 | ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent) { | |
| 120 | 121 | assert(node->type == NodeTypeDefer); |
| 121 | 122 | ScopeDefer *scope = allocate<ScopeDefer>(1); |
| 122 | init_scope(&scope->base, ScopeIdDefer, node, parent); | |
| 123 | init_scope(g, &scope->base, ScopeIdDefer, node, parent); | |
| 123 | 124 | return scope; |
| 124 | 125 | } |
| 125 | 126 | |
| 126 | ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent) { | |
| 127 | ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent) { | |
| 127 | 128 | assert(node->type == NodeTypeDefer); |
| 128 | 129 | ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1); |
| 129 | init_scope(&scope->base, ScopeIdDeferExpr, node, parent); | |
| 130 | init_scope(g, &scope->base, ScopeIdDeferExpr, node, parent); | |
| 130 | 131 | return scope; |
| 131 | 132 | } |
| 132 | 133 | |
| 133 | Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var) { | |
| 134 | Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var) { | |
| 134 | 135 | ScopeVarDecl *scope = allocate<ScopeVarDecl>(1); |
| 135 | init_scope(&scope->base, ScopeIdVarDecl, node, parent); | |
| 136 | init_scope(g, &scope->base, ScopeIdVarDecl, node, parent); | |
| 136 | 137 | scope->var = var; |
| 137 | 138 | return &scope->base; |
| 138 | 139 | } |
| 139 | 140 | |
| 140 | ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) { | |
| 141 | ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent) { | |
| 141 | 142 | assert(node->type == NodeTypeFnCallExpr); |
| 142 | 143 | ScopeCImport *scope = allocate<ScopeCImport>(1); |
| 143 | init_scope(&scope->base, ScopeIdCImport, node, parent); | |
| 144 | init_scope(g, &scope->base, ScopeIdCImport, node, parent); | |
| 144 | 145 | buf_resize(&scope->buf, 0); |
| 145 | 146 | return scope; |
| 146 | 147 | } |
| 147 | 148 | |
| 148 | ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) { | |
| 149 | ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent) { | |
| 149 | 150 | ScopeLoop *scope = allocate<ScopeLoop>(1); |
| 150 | init_scope(&scope->base, ScopeIdLoop, node, parent); | |
| 151 | init_scope(g, &scope->base, ScopeIdLoop, node, parent); | |
| 151 | 152 | if (node->type == NodeTypeWhileExpr) { |
| 152 | 153 | scope->name = node->data.while_expr.name; |
| 153 | 154 | } else if (node->type == NodeTypeForExpr) { |
| ... | ... | @@ -158,37 +159,37 @@ ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) { |
| 158 | 159 | return scope; |
| 159 | 160 | } |
| 160 | 161 | |
| 161 | Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime) { | |
| 162 | Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime) { | |
| 162 | 163 | ScopeRuntime *scope = allocate<ScopeRuntime>(1); |
| 163 | 164 | scope->is_comptime = is_comptime; |
| 164 | init_scope(&scope->base, ScopeIdRuntime, node, parent); | |
| 165 | init_scope(g, &scope->base, ScopeIdRuntime, node, parent); | |
| 165 | 166 | return &scope->base; |
| 166 | 167 | } |
| 167 | 168 | |
| 168 | ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent) { | |
| 169 | ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent) { | |
| 169 | 170 | assert(node->type == NodeTypeSuspend); |
| 170 | 171 | ScopeSuspend *scope = allocate<ScopeSuspend>(1); |
| 171 | init_scope(&scope->base, ScopeIdSuspend, node, parent); | |
| 172 | init_scope(g, &scope->base, ScopeIdSuspend, node, parent); | |
| 172 | 173 | return scope; |
| 173 | 174 | } |
| 174 | 175 | |
| 175 | ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry) { | |
| 176 | ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry) { | |
| 176 | 177 | ScopeFnDef *scope = allocate<ScopeFnDef>(1); |
| 177 | init_scope(&scope->base, ScopeIdFnDef, node, parent); | |
| 178 | init_scope(g, &scope->base, ScopeIdFnDef, node, parent); | |
| 178 | 179 | scope->fn_entry = fn_entry; |
| 179 | 180 | return scope; |
| 180 | 181 | } |
| 181 | 182 | |
| 182 | Scope *create_comptime_scope(AstNode *node, Scope *parent) { | |
| 183 | Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) { | |
| 183 | 184 | assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr); |
| 184 | 185 | ScopeCompTime *scope = allocate<ScopeCompTime>(1); |
| 185 | init_scope(&scope->base, ScopeIdCompTime, node, parent); | |
| 186 | init_scope(g, &scope->base, ScopeIdCompTime, node, parent); | |
| 186 | 187 | return &scope->base; |
| 187 | 188 | } |
| 188 | 189 | |
| 189 | Scope *create_coro_prelude_scope(AstNode *node, Scope *parent) { | |
| 190 | Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent) { | |
| 190 | 191 | ScopeCoroPrelude *scope = allocate<ScopeCoroPrelude>(1); |
| 191 | init_scope(&scope->base, ScopeIdCoroPrelude, node, parent); | |
| 192 | init_scope(g, &scope->base, ScopeIdCoroPrelude, node, parent); | |
| 192 | 193 | return &scope->base; |
| 193 | 194 | } |
| 194 | 195 | |
| ... | ... | @@ -204,9 +205,9 @@ ImportTableEntry *get_scope_import(Scope *scope) { |
| 204 | 205 | zig_unreachable(); |
| 205 | 206 | } |
| 206 | 207 | |
| 207 | static ZigType *new_container_type_entry(ZigTypeId id, AstNode *source_node, Scope *parent_scope) { | |
| 208 | static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *source_node, Scope *parent_scope) { | |
| 208 | 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 | 211 | return entry; |
| 211 | 212 | } |
| 212 | 213 | |
| ... | ... | @@ -1245,7 +1246,7 @@ ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind |
| 1245 | 1246 | AstNode *decl_node, const char *name, ContainerLayout layout) |
| 1246 | 1247 | { |
| 1247 | 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); | |
| 1249 | 1250 | |
| 1250 | 1251 | switch (kind) { |
| 1251 | 1252 | case ContainerKindStruct: |
| ... | ... | @@ -1372,13 +1373,17 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf ** |
| 1372 | 1373 | |
| 1373 | 1374 | assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 1374 | 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 | 1380 | expand_undef_array(g, array_val); |
| 1376 | 1381 | size_t len = bigint_as_unsigned(&len_field->data.x_bigint); |
| 1377 | 1382 | Buf *result = buf_alloc(); |
| 1378 | 1383 | buf_resize(result, len); |
| 1379 | 1384 | for (size_t i = 0; i < len; i += 1) { |
| 1380 | 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 | 1387 | if (char_val->special == ConstValSpecialUndef) { |
| 1383 | 1388 | add_node_error(g, node, buf_sprintf("use of undefined value")); |
| 1384 | 1389 | return false; |
| ... | ... | @@ -3093,9 +3098,10 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { |
| 3093 | 3098 | buf_append_buf(buf, tld->name); |
| 3094 | 3099 | } |
| 3095 | 3100 | |
| 3096 | ZigFn *create_fn_raw(FnInline inline_value) { | |
| 3101 | ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) { | |
| 3097 | 3102 | ZigFn *fn_entry = allocate<ZigFn>(1); |
| 3098 | 3103 | |
| 3104 | fn_entry->codegen = g; | |
| 3099 | 3105 | fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; |
| 3100 | 3106 | fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota; |
| 3101 | 3107 | fn_entry->analyzed_executable.fn_entry = fn_entry; |
| ... | ... | @@ -3105,12 +3111,12 @@ ZigFn *create_fn_raw(FnInline inline_value) { |
| 3105 | 3111 | return fn_entry; |
| 3106 | 3112 | } |
| 3107 | 3113 | |
| 3108 | ZigFn *create_fn(AstNode *proto_node) { | |
| 3114 | ZigFn *create_fn(CodeGen *g, AstNode *proto_node) { | |
| 3109 | 3115 | assert(proto_node->type == NodeTypeFnProto); |
| 3110 | 3116 | AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; |
| 3111 | 3117 | |
| 3112 | 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); | |
| 3114 | 3120 | |
| 3115 | 3121 | fn_entry->proto_node = proto_node; |
| 3116 | 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 | 3215 | |
| 3210 | 3216 | AstNode *fn_def_node = fn_proto->fn_def_node; |
| 3211 | 3217 | |
| 3212 | ZigFn *fn_table_entry = create_fn(source_node); | |
| 3218 | ZigFn *fn_table_entry = create_fn(g, source_node); | |
| 3213 | 3219 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); |
| 3214 | 3220 | |
| 3215 | 3221 | if (fn_proto->is_export) { |
| ... | ... | @@ -3220,7 +3226,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 3220 | 3226 | tld_fn->fn_entry = fn_table_entry; |
| 3221 | 3227 | |
| 3222 | 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 | 3230 | fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry); |
| 3225 | 3231 | |
| 3226 | 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 | 3276 | } |
| 3271 | 3277 | } |
| 3272 | 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); | |
| 3274 | 3280 | |
| 3275 | 3281 | get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); |
| 3276 | 3282 | |
| 3277 | 3283 | tld_fn->fn_entry = fn_table_entry; |
| 3278 | 3284 | |
| 3279 | 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 | 3287 | fn_table_entry->type_entry = get_test_fn_type(g); |
| 3282 | 3288 | fn_table_entry->body_node = source_node->data.test_decl.body; |
| 3283 | 3289 | fn_table_entry->is_test = true; |
| ... | ... | @@ -3606,7 +3612,7 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf |
| 3606 | 3612 | |
| 3607 | 3613 | Scope *child_scope; |
| 3608 | 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 | 3616 | } else { |
| 3611 | 3617 | // it's already in the decls table |
| 3612 | 3618 | child_scope = parent_scope; |
| ... | ... | @@ -4329,7 +4335,7 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *r |
| 4329 | 4335 | g->import_table.put(resolved_path, import_entry); |
| 4330 | 4336 | g->import_queue.append(import_entry); |
| 4331 | 4337 | |
| 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); | |
| 4333 | 4339 | |
| 4334 | 4340 | |
| 4335 | 4341 | assert(import_entry->root->type == NodeTypeRoot); |
| ... | ... | @@ -4880,7 +4886,7 @@ bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { |
| 4880 | 4886 | if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) { |
| 4881 | 4887 | assert(a_val->special == ConstValSpecialStatic); |
| 4882 | 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 | 4890 | return false; |
| 4885 | 4891 | } |
| 4886 | 4892 | } else { |
| ... | ... | @@ -4920,14 +4926,18 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) { |
| 4920 | 4926 | case ZigTypeIdArray: |
| 4921 | 4927 | if (value->type->data.array.len == 0) |
| 4922 | 4928 | return false; |
| 4923 | if (value->data.x_array.special == ConstArraySpecialUndef) | |
| 4924 | return false; | |
| 4925 | for (uint32_t i = 0; i < value->type->data.array.len; i += 1) { | |
| 4926 | if (can_mutate_comptime_var_state(&value->data.x_array.s_none.elements[i])) | |
| 4927 | return true; | |
| 4929 | switch (value->data.x_array.special) { | |
| 4930 | case ConstArraySpecialUndef: | |
| 4931 | case ConstArraySpecialBuf: | |
| 4932 | return false; | |
| 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; | |
| 4930 | ||
| 4940 | zig_unreachable(); | |
| 4931 | 4941 | case ZigTypeIdStruct: |
| 4932 | 4942 | for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) { |
| 4933 | 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 | 5049 | } |
| 5040 | 5050 | |
| 5041 | 5051 | bool fn_eval_eql(Scope *a, Scope *b) { |
| 5052 | assert(a->codegen != nullptr); | |
| 5053 | assert(b->codegen != nullptr); | |
| 5042 | 5054 | while (a && b) { |
| 5043 | 5055 | if (a->id != b->id) |
| 5044 | 5056 | return false; |
| ... | ... | @@ -5048,7 +5060,7 @@ bool fn_eval_eql(Scope *a, Scope *b) { |
| 5048 | 5060 | ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b; |
| 5049 | 5061 | if (a_var_scope->var->value->type != b_var_scope->var->value->type) |
| 5050 | 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 | 5064 | return false; |
| 5053 | 5065 | } else if (a->id == ScopeIdFnDef) { |
| 5054 | 5066 | ScopeFnDef *a_fn_scope = (ScopeFnDef *)a; |
| ... | ... | @@ -5130,14 +5142,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { |
| 5130 | 5142 | |
| 5131 | 5143 | const_val->special = ConstValSpecialStatic; |
| 5132 | 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)); | |
| 5134 | ||
| 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 | } | |
| 5145 | const_val->data.x_array.special = ConstArraySpecialBuf; | |
| 5146 | const_val->data.x_array.data.s_buf = str; | |
| 5141 | 5147 | |
| 5142 | 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 | 5160 | ConstExprValue *array_val = create_const_vals(1); |
| 5155 | 5161 | array_val->special = ConstValSpecialStatic; |
| 5156 | 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 | 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 | 5167 | this_char->special = ConstValSpecialStatic; |
| 5161 | 5168 | this_char->type = g->builtin_types.entry_u8; |
| 5162 | 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 | 5172 | null_char->special = ConstValSpecialStatic; |
| 5166 | 5173 | null_char->type = g->builtin_types.entry_u8; |
| 5167 | 5174 | bigint_init_unsigned(&null_char->data.x_bigint, 0); |
| ... | ... | @@ -5535,7 +5542,7 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) { |
| 5535 | 5542 | zig_unreachable(); |
| 5536 | 5543 | } |
| 5537 | 5544 | |
| 5538 | bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { | |
| 5545 | bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) { | |
| 5539 | 5546 | assert(a->type->id == b->type->id); |
| 5540 | 5547 | assert(a->special == ConstValSpecialStatic); |
| 5541 | 5548 | assert(b->special == ConstValSpecialStatic); |
| ... | ... | @@ -5593,13 +5600,20 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { |
| 5593 | 5600 | assert(a->type->data.array.len == b->type->data.array.len); |
| 5594 | 5601 | assert(a->data.x_array.special != ConstArraySpecialUndef); |
| 5595 | 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); | |
| 5596 | 5610 | |
| 5597 | 5611 | size_t len = a->type->data.array.len; |
| 5598 | ConstExprValue *a_elems = a->data.x_array.s_none.elements; | |
| 5599 | ConstExprValue *b_elems = b->data.x_array.s_none.elements; | |
| 5612 | ConstExprValue *a_elems = a->data.x_array.data.s_none.elements; | |
| 5613 | ConstExprValue *b_elems = b->data.x_array.data.s_none.elements; | |
| 5600 | 5614 | |
| 5601 | 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 | 5617 | return false; |
| 5604 | 5618 | } |
| 5605 | 5619 | |
| ... | ... | @@ -5609,7 +5623,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { |
| 5609 | 5623 | for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) { |
| 5610 | 5624 | ConstExprValue *field_a = &a->data.x_struct.fields[i]; |
| 5611 | 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 | 5627 | return false; |
| 5614 | 5628 | } |
| 5615 | 5629 | return true; |
| ... | ... | @@ -5623,7 +5637,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { |
| 5623 | 5637 | if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) { |
| 5624 | 5638 | return (a->data.x_optional == nullptr && b->data.x_optional == nullptr); |
| 5625 | 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 | 5642 | case ZigTypeIdErrorUnion: |
| 5629 | 5643 | zig_panic("TODO"); |
| ... | ... | @@ -5808,26 +5822,15 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { |
| 5808 | 5822 | case ZigTypeIdPointer: |
| 5809 | 5823 | return render_const_val_ptr(g, buf, const_val, type_entry); |
| 5810 | 5824 | case ZigTypeIdArray: |
| 5811 | { | |
| 5812 | ZigType *child_type = type_entry->data.array.child_type; | |
| 5813 | uint64_t len = type_entry->data.array.len; | |
| 5814 | ||
| 5815 | if (const_val->data.x_array.special == ConstArraySpecialUndef) { | |
| 5825 | switch (const_val->data.x_array.special) { | |
| 5826 | case ConstArraySpecialUndef: | |
| 5816 | 5827 | buf_append_str(buf, "undefined"); |
| 5817 | 5828 | return; |
| 5818 | } | |
| 5819 | ||
| 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 | { | |
| 5829 | case ConstArraySpecialBuf: { | |
| 5830 | Buf *array_buf = const_val->data.x_array.data.s_buf; | |
| 5825 | 5831 | buf_append_char(buf, '"'); |
| 5826 | for (uint64_t i = 0; i < len; i += 1) { | |
| 5827 | ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[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; | |
| 5832 | for (size_t i = 0; i < buf_len(array_buf); i += 1) { | |
| 5833 | uint8_t c = buf_ptr(array_buf)[i]; | |
| 5831 | 5834 | if (c == '"') { |
| 5832 | 5835 | buf_append_str(buf, "\\\""); |
| 5833 | 5836 | } else { |
| ... | ... | @@ -5837,17 +5840,20 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { |
| 5837 | 5840 | buf_append_char(buf, '"'); |
| 5838 | 5841 | return; |
| 5839 | 5842 | } |
| 5840 | ||
| 5841 | buf_appendf(buf, "%s{", buf_ptr(&type_entry->name)); | |
| 5842 | for (uint64_t i = 0; i < len; i += 1) { | |
| 5843 | if (i != 0) | |
| 5844 | buf_appendf(buf, ","); | |
| 5845 | ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i]; | |
| 5846 | render_const_value(g, buf, child_value); | |
| 5843 | case ConstArraySpecialNone: { | |
| 5844 | buf_appendf(buf, "%s{", buf_ptr(&type_entry->name)); | |
| 5845 | uint64_t len = type_entry->data.array.len; | |
| 5846 | for (uint64_t i = 0; i < len; i += 1) { | |
| 5847 | if (i != 0) | |
| 5848 | buf_appendf(buf, ","); | |
| 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 | 5857 | case ZigTypeIdNull: |
| 5852 | 5858 | { |
| 5853 | 5859 | buf_appendf(buf, "null"); |
| ... | ... | @@ -6102,24 +6108,49 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { |
| 6102 | 6108 | zig_unreachable(); |
| 6103 | 6109 | } |
| 6104 | 6110 | |
| 6111 | // Canonicalize the array value as ConstArraySpecialNone | |
| 6105 | 6112 | void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { |
| 6106 | 6113 | assert(const_val->type->id == ZigTypeIdArray); |
| 6107 | if (const_val->data.x_array.special == ConstArraySpecialUndef) { | |
| 6108 | const_val->data.x_array.special = ConstArraySpecialNone; | |
| 6109 | size_t elem_count = const_val->type->data.array.len; | |
| 6110 | const_val->data.x_array.s_none.elements = create_const_vals(elem_count); | |
| 6111 | for (size_t i = 0; i < elem_count; i += 1) { | |
| 6112 | ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i]; | |
| 6113 | element_val->type = const_val->type->data.array.child_type; | |
| 6114 | init_const_undefined(g, element_val); | |
| 6115 | ConstParent *parent = get_const_val_parent(g, element_val); | |
| 6116 | if (parent != nullptr) { | |
| 6117 | parent->id = ConstParentIdArray; | |
| 6118 | parent->data.p_array.array_val = const_val; | |
| 6119 | parent->data.p_array.elem_index = i; | |
| 6114 | switch (const_val->data.x_array.special) { | |
| 6115 | case ConstArraySpecialNone: | |
| 6116 | return; | |
| 6117 | case ConstArraySpecialUndef: { | |
| 6118 | const_val->data.x_array.special = ConstArraySpecialNone; | |
| 6119 | size_t elem_count = const_val->type->data.array.len; | |
| 6120 | const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count); | |
| 6121 | for (size_t i = 0; i < elem_count; i += 1) { | |
| 6122 | ConstExprValue *element_val = &const_val->data.x_array.data.s_none.elements[i]; | |
| 6123 | element_val->type = const_val->type->data.array.child_type; | |
| 6124 | init_const_undefined(g, element_val); | |
| 6125 | ConstParent *parent = get_const_val_parent(g, element_val); | |
| 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 | } |
| 6124 | 6155 | |
| 6125 | 6156 | ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) { |
| ... | ... | @@ -6127,7 +6158,7 @@ ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) { |
| 6127 | 6158 | ZigType *type_entry = value->type; |
| 6128 | 6159 | if (type_entry->id == ZigTypeIdArray) { |
| 6129 | 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 | 6162 | } else if (type_entry->id == ZigTypeIdStruct) { |
| 6132 | 6163 | return &value->data.x_struct.parent; |
| 6133 | 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 | 84 | ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, |
| 85 | 85 | bool is_const, ConstExprValue *init_value, Tld *src_tld); |
| 86 | 86 | ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); |
| 87 | ZigFn *create_fn(AstNode *proto_node); | |
| 88 | ZigFn *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage); | |
| 87 | ZigFn *create_fn(CodeGen *g, AstNode *proto_node); | |
| 88 | ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value); | |
| 89 | 89 | void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc); |
| 90 | 90 | AstNode *get_param_decl_node(ZigFn *fn_entry, size_t index); |
| 91 | 91 | bool type_requires_comptime(ZigType *type_entry); |
| ... | ... | @@ -93,25 +93,25 @@ Error ATTRIBUTE_MUST_USE ensure_complete_type(CodeGen *g, ZigType *type_entry); |
| 93 | 93 | Error ATTRIBUTE_MUST_USE type_resolve(CodeGen *g, ZigType *type_entry, ResolveStatus status); |
| 94 | 94 | void complete_enum(CodeGen *g, ZigType *enum_type); |
| 95 | 95 | bool ir_get_var_is_comptime(ZigVar *var); |
| 96 | bool const_values_equal(ConstExprValue *a, ConstExprValue *b); | |
| 96 | bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b); | |
| 97 | 97 | void eval_min_max_value(CodeGen *g, ZigType *type_entry, ConstExprValue *const_val, bool is_max); |
| 98 | 98 | void eval_min_max_value_int(CodeGen *g, ZigType *int_type, BigInt *bigint, bool is_max); |
| 99 | 99 | |
| 100 | 100 | void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val); |
| 101 | 101 | void analyze_fn_ir(CodeGen *g, ZigFn *fn_table_entry, AstNode *return_type_node); |
| 102 | 102 | |
| 103 | ScopeBlock *create_block_scope(AstNode *node, Scope *parent); | |
| 104 | ScopeDefer *create_defer_scope(AstNode *node, Scope *parent); | |
| 105 | ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent); | |
| 106 | Scope *create_var_scope(AstNode *node, Scope *parent, ZigVar *var); | |
| 107 | ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent); | |
| 108 | ScopeLoop *create_loop_scope(AstNode *node, Scope *parent); | |
| 109 | ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent); | |
| 110 | ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, ZigFn *fn_entry); | |
| 111 | ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import); | |
| 112 | Scope *create_comptime_scope(AstNode *node, Scope *parent); | |
| 113 | Scope *create_coro_prelude_scope(AstNode *node, Scope *parent); | |
| 114 | Scope *create_runtime_scope(AstNode *node, Scope *parent, IrInstruction *is_comptime); | |
| 103 | ScopeBlock *create_block_scope(CodeGen *g, AstNode *node, Scope *parent); | |
| 104 | ScopeDefer *create_defer_scope(CodeGen *g, AstNode *node, Scope *parent); | |
| 105 | ScopeDeferExpr *create_defer_expr_scope(CodeGen *g, AstNode *node, Scope *parent); | |
| 106 | Scope *create_var_scope(CodeGen *g, AstNode *node, Scope *parent, ZigVar *var); | |
| 107 | ScopeCImport *create_cimport_scope(CodeGen *g, AstNode *node, Scope *parent); | |
| 108 | ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent); | |
| 109 | ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent); | |
| 110 | ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry); | |
| 111 | ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type, ImportTableEntry *import); | |
| 112 | Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent); | |
| 113 | Scope *create_coro_prelude_scope(CodeGen *g, AstNode *node, Scope *parent); | |
| 114 | Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstruction *is_comptime); | |
| 115 | 115 | |
| 116 | 116 | void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str); |
| 117 | 117 | ConstExprValue *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 | 5336 | |
| 5337 | 5337 | static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) { |
| 5338 | 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 | 5340 | LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); |
| 5341 | 5341 | |
| 5342 | 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 | 5716 | case ZigTypeIdArray: |
| 5717 | 5717 | { |
| 5718 | 5718 | uint64_t len = type_entry->data.array.len; |
| 5719 | if (const_val->data.x_array.special == ConstArraySpecialUndef) { | |
| 5720 | return LLVMGetUndef(type_entry->type_ref); | |
| 5721 | } | |
| 5722 | ||
| 5723 | LLVMValueRef *values = allocate<LLVMValueRef>(len); | |
| 5724 | LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref; | |
| 5725 | bool make_unnamed_struct = false; | |
| 5726 | for (uint64_t i = 0; i < len; i += 1) { | |
| 5727 | ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i]; | |
| 5728 | LLVMValueRef val = gen_const_val(g, elem_value, ""); | |
| 5729 | values[i] = val; | |
| 5730 | make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val); | |
| 5731 | } | |
| 5732 | if (make_unnamed_struct) { | |
| 5733 | return LLVMConstStruct(values, len, true); | |
| 5734 | } else { | |
| 5735 | return LLVMConstArray(element_type_ref, values, (unsigned)len); | |
| 5719 | switch (const_val->data.x_array.special) { | |
| 5720 | case ConstArraySpecialUndef: | |
| 5721 | return LLVMGetUndef(type_entry->type_ref); | |
| 5722 | case ConstArraySpecialNone: { | |
| 5723 | LLVMValueRef *values = allocate<LLVMValueRef>(len); | |
| 5724 | LLVMTypeRef element_type_ref = type_entry->data.array.child_type->type_ref; | |
| 5725 | bool make_unnamed_struct = false; | |
| 5726 | for (uint64_t i = 0; i < len; i += 1) { | |
| 5727 | ConstExprValue *elem_value = &const_val->data.x_array.data.s_none.elements[i]; | |
| 5728 | LLVMValueRef val = gen_const_val(g, elem_value, ""); | |
| 5729 | values[i] = val; | |
| 5730 | make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(elem_value->type, val); | |
| 5731 | } | |
| 5732 | if (make_unnamed_struct) { | |
| 5733 | return LLVMConstStruct(values, len, true); | |
| 5734 | } else { | |
| 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 | 5744 | case ZigTypeIdUnion: |
| ... | ... | @@ -7278,7 +7284,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) { |
| 7278 | 7284 | import->source_code = nullptr; |
| 7279 | 7285 | import->path = full_path; |
| 7280 | 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); | |
| 7282 | 7288 | |
| 7283 | 7289 | init(g); |
| 7284 | 7290 | |
| ... | ... | @@ -7352,12 +7358,12 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) { |
| 7352 | 7358 | ConstExprValue *test_fn_array = create_const_vals(1); |
| 7353 | 7359 | test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length); |
| 7354 | 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); | |
| 7356 | 7362 | |
| 7357 | 7363 | for (size_t i = 0; i < g->test_fns.length; i += 1) { |
| 7358 | 7364 | ZigFn *test_fn_entry = g->test_fns.at(i); |
| 7359 | 7365 | |
| 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 | 7367 | this_val->special = ConstValSpecialStatic; |
| 7362 | 7368 | this_val->type = struct_type; |
| 7363 | 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 | 166 | break; |
| 167 | 167 | case ConstPtrSpecialBaseArray: |
| 168 | 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 | 170 | const_val->data.x_ptr.data.base_array.elem_index]; |
| 171 | 171 | break; |
| 172 | 172 | case ConstPtrSpecialBaseStruct: |
| ... | ... | @@ -3360,7 +3360,7 @@ static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_s |
| 3360 | 3360 | variable_entry->src_is_const = src_is_const; |
| 3361 | 3361 | variable_entry->gen_is_const = gen_is_const; |
| 3362 | 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); | |
| 3364 | 3364 | |
| 3365 | 3365 | return variable_entry; |
| 3366 | 3366 | } |
| ... | ... | @@ -3388,7 +3388,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3388 | 3388 | ZigList<IrInstruction *> incoming_values = {0}; |
| 3389 | 3389 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| 3390 | 3390 | |
| 3391 | ScopeBlock *scope_block = create_block_scope(block_node, parent_scope); | |
| 3391 | ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); | |
| 3392 | 3392 | |
| 3393 | 3393 | Scope *outer_block_scope = &scope_block->base; |
| 3394 | 3394 | Scope *child_scope = outer_block_scope; |
| ... | ... | @@ -5026,7 +5026,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode |
| 5026 | 5026 | |
| 5027 | 5027 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 5028 | 5028 | |
| 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 | 5030 | IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope); |
| 5031 | 5031 | if (then_expr_result == irb->codegen->invalid_instruction) |
| 5032 | 5032 | return then_expr_result; |
| ... | ... | @@ -5318,7 +5318,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5318 | 5318 | ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); |
| 5319 | 5319 | ir_build_br(irb, scope, node, cond_block, is_comptime); |
| 5320 | 5320 | |
| 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 | 5322 | Buf *var_symbol = node->data.while_expr.var_symbol; |
| 5323 | 5323 | Buf *err_symbol = node->data.while_expr.err_symbol; |
| 5324 | 5324 | if (err_symbol != nullptr) { |
| ... | ... | @@ -5359,7 +5359,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5359 | 5359 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5360 | 5360 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| 5361 | 5361 | |
| 5362 | ScopeLoop *loop_scope = create_loop_scope(node, payload_scope); | |
| 5362 | ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); | |
| 5363 | 5363 | loop_scope->break_block = end_block; |
| 5364 | 5364 | loop_scope->continue_block = continue_block; |
| 5365 | 5365 | loop_scope->is_comptime = is_comptime; |
| ... | ... | @@ -5415,7 +5415,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5415 | 5415 | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 5416 | 5416 | } else if (var_symbol != nullptr) { |
| 5417 | 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 | 5419 | // TODO make it an error to write to payload variable |
| 5420 | 5420 | AstNode *symbol_node = node; // TODO make more accurate |
| 5421 | 5421 | |
| ... | ... | @@ -5443,7 +5443,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5443 | 5443 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5444 | 5444 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| 5445 | 5445 | |
| 5446 | ScopeLoop *loop_scope = create_loop_scope(node, child_scope); | |
| 5446 | ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); | |
| 5447 | 5447 | loop_scope->break_block = end_block; |
| 5448 | 5448 | loop_scope->continue_block = continue_block; |
| 5449 | 5449 | loop_scope->is_comptime = is_comptime; |
| ... | ... | @@ -5506,9 +5506,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 5506 | 5506 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5507 | 5507 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| 5508 | 5508 | |
| 5509 | Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); | |
| 5509 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | |
| 5510 | 5510 | |
| 5511 | ScopeLoop *loop_scope = create_loop_scope(node, subexpr_scope); | |
| 5511 | ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope); | |
| 5512 | 5512 | loop_scope->break_block = end_block; |
| 5513 | 5513 | loop_scope->continue_block = continue_block; |
| 5514 | 5514 | loop_scope->is_comptime = is_comptime; |
| ... | ... | @@ -5645,7 +5645,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5645 | 5645 | |
| 5646 | 5646 | ZigList<IrInstruction *> incoming_values = {0}; |
| 5647 | 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 | 5649 | loop_scope->break_block = end_block; |
| 5650 | 5650 | loop_scope->continue_block = continue_block; |
| 5651 | 5651 | loop_scope->is_comptime = is_comptime; |
| ... | ... | @@ -5855,7 +5855,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no |
| 5855 | 5855 | |
| 5856 | 5856 | ir_set_cursor_at_end_and_append_block(irb, then_block); |
| 5857 | 5857 | |
| 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 | 5859 | Scope *var_scope; |
| 5860 | 5860 | if (var_symbol) { |
| 5861 | 5861 | IrInstruction *var_type = nullptr; |
| ... | ... | @@ -5930,7 +5930,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 5930 | 5930 | |
| 5931 | 5931 | ir_set_cursor_at_end_and_append_block(irb, ok_block); |
| 5932 | 5932 | |
| 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 | 5934 | Scope *var_scope; |
| 5935 | 5935 | if (var_symbol) { |
| 5936 | 5936 | IrInstruction *var_type = nullptr; |
| ... | ... | @@ -6066,8 +6066,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * |
| 6066 | 6066 | ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; |
| 6067 | 6067 | |
| 6068 | 6068 | // First do the else and the ranges |
| 6069 | Scope *subexpr_scope = create_runtime_scope(node, scope, is_comptime); | |
| 6070 | Scope *comptime_scope = create_comptime_scope(node, scope); | |
| 6069 | Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); | |
| 6070 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); | |
| 6071 | 6071 | AstNode *else_prong = nullptr; |
| 6072 | 6072 | for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { |
| 6073 | 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 | 6231 | static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { |
| 6232 | 6232 | assert(node->type == NodeTypeCompTime); |
| 6233 | 6233 | |
| 6234 | Scope *child_scope = create_comptime_scope(node, parent_scope); | |
| 6234 | Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); | |
| 6235 | 6235 | return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval); |
| 6236 | 6236 | } |
| 6237 | 6237 | |
| ... | ... | @@ -6394,10 +6394,10 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 6394 | 6394 | static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 6395 | 6395 | assert(node->type == NodeTypeDefer); |
| 6396 | 6396 | |
| 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 | 6398 | node->data.defer.child_scope = &defer_child_scope->base; |
| 6399 | 6399 | |
| 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 | 6401 | node->data.defer.expr_scope = &defer_expr_scope->base; |
| 6402 | 6402 | |
| 6403 | 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 | 7154 | suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false); |
| 7155 | 7155 | } else { |
| 7156 | 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 | 7158 | suspend_scope->resume_block = resume_block; |
| 7159 | 7159 | child_scope = &suspend_scope->base; |
| 7160 | 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 | 7370 | ZigVar *coro_size_var; |
| 7371 | 7371 | if (is_async) { |
| 7372 | 7372 | // 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 | 7374 | const_bool_false = ir_build_const_bool(irb, coro_scope, node, false); |
| 7375 | 7375 | ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); |
| 7376 | 7376 | |
| ... | ... | @@ -10569,9 +10569,9 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou |
| 10569 | 10569 | array_val->special = ConstValSpecialStatic; |
| 10570 | 10570 | array_val->type = array_type; |
| 10571 | 10571 | array_val->data.x_array.special = ConstArraySpecialNone; |
| 10572 | array_val->data.x_array.s_none.elements = pointee; | |
| 10573 | array_val->data.x_array.s_none.parent.id = ConstParentIdScalar; | |
| 10574 | array_val->data.x_array.s_none.parent.data.p_scalar.scalar_val = pointee; | |
| 10572 | array_val->data.x_array.data.s_none.elements = pointee; | |
| 10573 | array_val->data.x_array.data.s_none.parent.id = ConstParentIdScalar; | |
| 10574 | array_val->data.x_array.data.s_none.parent.data.p_scalar.scalar_val = pointee; | |
| 10575 | 10575 | |
| 10576 | 10576 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 10577 | 10577 | source_instr->scope, source_instr->source_node); |
| ... | ... | @@ -11391,13 +11391,16 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { |
| 11391 | 11391 | |
| 11392 | 11392 | assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 11393 | 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 | 11397 | expand_undef_array(ira->codegen, array_val); |
| 11395 | 11398 | size_t len = bigint_as_unsigned(&len_field->data.x_bigint); |
| 11396 | 11399 | Buf *result = buf_alloc(); |
| 11397 | 11400 | buf_resize(result, len); |
| 11398 | 11401 | for (size_t i = 0; i < len; i += 1) { |
| 11399 | 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 | 11404 | if (char_val->special == ConstValSpecialUndef) { |
| 11402 | 11405 | ir_add_error(ira, casted_value, buf_sprintf("use of undefined value")); |
| 11403 | 11406 | return nullptr; |
| ... | ... | @@ -11750,7 +11753,7 @@ static ZigType *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op |
| 11750 | 11753 | Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 11751 | 11754 | answer = resolve_cmp_op_id(op_id, cmp_result); |
| 11752 | 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 | 11757 | if (op_id == IrBinOpCmpEq) { |
| 11755 | 11758 | answer = are_equal; |
| 11756 | 11759 | } else if (op_id == IrBinOpCmpNotEq) { |
| ... | ... | @@ -12463,19 +12466,20 @@ static ZigType *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruc |
| 12463 | 12466 | return result_type; |
| 12464 | 12467 | } |
| 12465 | 12468 | |
| 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 | 12471 | expand_undef_array(ira->codegen, op1_array_val); |
| 12468 | 12472 | expand_undef_array(ira->codegen, op2_array_val); |
| 12469 | 12473 | |
| 12470 | 12474 | size_t next_index = 0; |
| 12471 | 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 | 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 | 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 | 12483 | init_const_unsigned_negative(null_byte, child_type, 0, false); |
| 12480 | 12484 | next_index += 1; |
| 12481 | 12485 | } |
| ... | ... | @@ -12524,12 +12528,14 @@ static ZigType *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instru |
| 12524 | 12528 | return get_array_type(ira->codegen, child_type, new_array_len); |
| 12525 | 12529 | } |
| 12526 | 12530 | |
| 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); | |
| 12528 | 12534 | |
| 12529 | 12535 | uint64_t i = 0; |
| 12530 | 12536 | for (uint64_t x = 0; x < mult_amt; x += 1) { |
| 12531 | 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 | 12539 | i += 1; |
| 12534 | 12540 | } |
| 12535 | 12541 | } |
| ... | ... | @@ -13502,10 +13508,10 @@ static ZigType *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instr |
| 13502 | 13508 | |
| 13503 | 13509 | // Fork a scope of the function with known values for the parameters. |
| 13504 | 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 | 13512 | impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count); |
| 13507 | 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 | 13515 | impl_fn->child_scope = &impl_fn->fndef_scope->base; |
| 13510 | 13516 | FnTypeId inst_fn_type_id = {0}; |
| 13511 | 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 | 16079 | if (!case_val) |
| 16074 | 16080 | return ir_unreach_error(ira); |
| 16075 | 16081 | |
| 16076 | if (const_values_equal(target_val, case_val)) { | |
| 16082 | if (const_values_equal(ira->codegen, target_val, case_val)) { | |
| 16077 | 16083 | old_dest_block = old_case->block; |
| 16078 | 16084 | break; |
| 16079 | 16085 | } |
| ... | ... | @@ -16652,7 +16658,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 16652 | 16658 | ConstExprValue const_val = {}; |
| 16653 | 16659 | const_val.special = ConstValSpecialStatic; |
| 16654 | 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); | |
| 16656 | 16662 | |
| 16657 | 16663 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); |
| 16658 | 16664 | |
| ... | ... | @@ -16677,7 +16683,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 16677 | 16683 | if (!elem_val) |
| 16678 | 16684 | return ira->codegen->builtin_types.entry_invalid; |
| 16679 | 16685 | |
| 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 | 16687 | } else { |
| 16682 | 16688 | first_non_const_instruction = casted_arg; |
| 16683 | 16689 | const_val.special = ConstValSpecialRuntime; |
| ... | ... | @@ -16689,7 +16695,7 @@ static ZigType *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 16689 | 16695 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 16690 | 16696 | *out_val = const_val; |
| 16691 | 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 | 16699 | ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); |
| 16694 | 16700 | if (parent != nullptr) { |
| 16695 | 16701 | parent->id = ConstParentIdArray; |
| ... | ... | @@ -17146,8 +17152,8 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco |
| 17146 | 17152 | definition_array->special = ConstValSpecialStatic; |
| 17147 | 17153 | definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count); |
| 17148 | 17154 | definition_array->data.x_array.special = ConstArraySpecialNone; |
| 17149 | definition_array->data.x_array.s_none.parent.id = ConstParentIdNone; | |
| 17150 | definition_array->data.x_array.s_none.elements = create_const_vals(definition_count); | |
| 17155 | definition_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; | |
| 17156 | definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count); | |
| 17151 | 17157 | init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false); |
| 17152 | 17158 | |
| 17153 | 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 | 17170 | continue; |
| 17165 | 17171 | } |
| 17166 | 17172 | |
| 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]; | |
| 17168 | 17174 | |
| 17169 | 17175 | definition_val->special = ConstValSpecialStatic; |
| 17170 | 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 | 17299 | fn_arg_name_array->type = get_array_type(ira->codegen, |
| 17294 | 17300 | get_slice_type(ira->codegen, u8_ptr), fn_arg_count); |
| 17295 | 17301 | fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; |
| 17296 | fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone; | |
| 17297 | fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); | |
| 17302 | fn_arg_name_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; | |
| 17303 | fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); | |
| 17298 | 17304 | |
| 17299 | 17305 | init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false); |
| 17300 | 17306 | |
| 17301 | 17307 | for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) |
| 17302 | 17308 | { |
| 17303 | 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 | 17311 | ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name); |
| 17306 | 17312 | init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true); |
| 17307 | 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 | 17599 | enum_field_array->special = ConstValSpecialStatic; |
| 17594 | 17600 | enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count); |
| 17595 | 17601 | enum_field_array->data.x_array.special = ConstArraySpecialNone; |
| 17596 | enum_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; | |
| 17597 | enum_field_array->data.x_array.s_none.elements = create_const_vals(enum_field_count); | |
| 17602 | enum_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; | |
| 17603 | enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count); | |
| 17598 | 17604 | |
| 17599 | 17605 | init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false); |
| 17600 | 17606 | |
| 17601 | 17607 | for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) |
| 17602 | 17608 | { |
| 17603 | 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 | 17611 | make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); |
| 17606 | 17612 | enum_field_val->data.x_struct.parent.id = ConstParentIdArray; |
| 17607 | 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 | 17638 | error_array->special = ConstValSpecialStatic; |
| 17633 | 17639 | error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count); |
| 17634 | 17640 | error_array->data.x_array.special = ConstArraySpecialNone; |
| 17635 | error_array->data.x_array.s_none.parent.id = ConstParentIdNone; | |
| 17636 | error_array->data.x_array.s_none.elements = create_const_vals(error_count); | |
| 17641 | error_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; | |
| 17642 | error_array->data.x_array.data.s_none.elements = create_const_vals(error_count); | |
| 17637 | 17643 | |
| 17638 | 17644 | init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false); |
| 17639 | 17645 | for (uint32_t error_index = 0; error_index < error_count; error_index++) { |
| 17640 | 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]; | |
| 17642 | 17648 | |
| 17643 | 17649 | error_val->special = ConstValSpecialStatic; |
| 17644 | 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 | 17733 | union_field_array->special = ConstValSpecialStatic; |
| 17728 | 17734 | union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count); |
| 17729 | 17735 | union_field_array->data.x_array.special = ConstArraySpecialNone; |
| 17730 | union_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; | |
| 17731 | union_field_array->data.x_array.s_none.elements = create_const_vals(union_field_count); | |
| 17736 | union_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; | |
| 17737 | union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count); | |
| 17732 | 17738 | |
| 17733 | 17739 | init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); |
| 17734 | 17740 | |
| ... | ... | @@ -17736,7 +17742,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE |
| 17736 | 17742 | |
| 17737 | 17743 | for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { |
| 17738 | 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]; | |
| 17740 | 17746 | |
| 17741 | 17747 | union_field_val->special = ConstValSpecialStatic; |
| 17742 | 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 | 17806 | struct_field_array->special = ConstValSpecialStatic; |
| 17801 | 17807 | struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count); |
| 17802 | 17808 | struct_field_array->data.x_array.special = ConstArraySpecialNone; |
| 17803 | struct_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; | |
| 17804 | struct_field_array->data.x_array.s_none.elements = create_const_vals(struct_field_count); | |
| 17809 | struct_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; | |
| 17810 | struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count); | |
| 17805 | 17811 | |
| 17806 | 17812 | init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false); |
| 17807 | 17813 | |
| 17808 | 17814 | for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { |
| 17809 | 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]; | |
| 17811 | 17817 | |
| 17812 | 17818 | struct_field_val->special = ConstValSpecialStatic; |
| 17813 | 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 | 17912 | fn_arg_array->special = ConstValSpecialStatic; |
| 17907 | 17913 | fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count); |
| 17908 | 17914 | fn_arg_array->data.x_array.special = ConstArraySpecialNone; |
| 17909 | fn_arg_array->data.x_array.s_none.parent.id = ConstParentIdNone; | |
| 17910 | fn_arg_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); | |
| 17915 | fn_arg_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; | |
| 17916 | fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); | |
| 17911 | 17917 | |
| 17912 | 17918 | init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false); |
| 17913 | 17919 | |
| 17914 | 17920 | for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) |
| 17915 | 17921 | { |
| 17916 | 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]; | |
| 17918 | 17924 | |
| 17919 | 17925 | fn_arg_val->special = ConstValSpecialStatic; |
| 17920 | 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 | 18065 | assert(node->type == NodeTypeFnCallExpr); |
| 18060 | 18066 | AstNode *block_node = node->data.fn_call_expr.params.at(0); |
| 18061 | 18067 | |
| 18062 | ScopeCImport *cimport_scope = create_cimport_scope(node, instruction->base.scope); | |
| 18068 | ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope); | |
| 18063 | 18069 | |
| 18064 | 18070 | // Execute the C import block like an inline function |
| 18065 | 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 | 18078 | find_libc_include_path(ira->codegen); |
| 18073 | 18079 | |
| 18074 | 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 | 18082 | child_import->c_import_node = node; |
| 18077 | 18083 | child_import->package = new_anonymous_package(); |
| 18078 | 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 | 18832 | { |
| 18827 | 18833 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; |
| 18828 | 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 | 18836 | start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; |
| 18831 | 18837 | bound_end = array_val->type->data.array.len; |
| 18832 | 18838 | break; |
| ... | ... | @@ -18940,7 +18946,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp |
| 18940 | 18946 | { |
| 18941 | 18947 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; |
| 18942 | 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 | 18950 | dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; |
| 18945 | 18951 | dest_end = array_val->type->data.array.len; |
| 18946 | 18952 | break; |
| ... | ... | @@ -18976,7 +18982,7 @@ static ZigType *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcp |
| 18976 | 18982 | { |
| 18977 | 18983 | ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; |
| 18978 | 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 | 18986 | src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; |
| 18981 | 18987 | src_end = array_val->type->data.array.len; |
| 18982 | 18988 | break; |
| ... | ... | @@ -20282,9 +20288,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 20282 | 20288 | case ZigTypeIdArray: |
| 20283 | 20289 | { |
| 20284 | 20290 | size_t buf_i = 0; |
| 20291 | // TODO optimize the buf case | |
| 20285 | 20292 | expand_undef_array(codegen, val); |
| 20286 | 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 | 20295 | buf_write_value_bytes(codegen, &buf[buf_i], elem); |
| 20289 | 20296 | buf_i += type_size(codegen, elem->type); |
| 20290 | 20297 | } |
test/behavior.zig+1| ... | ... | @@ -8,6 +8,7 @@ comptime { |
| 8 | 8 | _ = @import("cases/atomics.zig"); |
| 9 | 9 | _ = @import("cases/bitcast.zig"); |
| 10 | 10 | _ = @import("cases/bool.zig"); |
| 11 | _ = @import("cases/bugs/1076.zig"); | |
| 11 | 12 | _ = @import("cases/bugs/1111.zig"); |
| 12 | 13 | _ = @import("cases/bugs/1277.zig"); |
| 13 | 14 | _ = @import("cases/bugs/1322.zig"); |
test/cases/bugs/1076.zig created+16| ... | ... | @@ -0,0 +1,16 @@ |
| 1 | const std = @import("std"); | |
| 2 | const mem = std.mem; | |
| 3 | const assert = std.debug.assert; | |
| 4 | ||
| 5 | test "comptime code should not modify constant data" { | |
| 6 | testCastPtrOfArrayToSliceAndPtr(); | |
| 7 | comptime testCastPtrOfArrayToSliceAndPtr(); | |
| 8 | } | |
| 9 | ||
| 10 | fn 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 | 400 | } |
| 401 | 401 | |
| 402 | 402 | fn testCastPtrOfArrayToSliceAndPtr() void { |
| 403 | var array = "ao" ++ "eu"; // TODO https://github.com/ziglang/zig/issues/1076 | |
| 403 | var array = "aoeu"; | |
| 404 | 404 | const x: [*]u8 = &array; |
| 405 | 405 | x[0] += 1; |
| 406 | 406 | assert(mem.eql(u8, array[0..], "boeu")); |