authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-08 22:25:38-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-08 22:25:38-05:00
log6caf32195af7aab084f3f2fee37239de0eb67adb
treee9d8fb542726bbf503b01627c1841181f93610c4
parent76d0e49e612d661b57b795cd81f5ba06dc26ceca

pass unnecessary if statement test


9 files changed, 181 insertions(+), 54 deletions(-)

doc/langref.md+16-3
...@@ -540,9 +540,9 @@ variables:...@@ -540,9 +540,9 @@ variables:
540 * "is_big_endian" `bool` - either `true` for big endian or `false` for little endian.540 * "is_big_endian" `bool` - either `true` for big endian or `false` for little endian.
541 * "is_release" `bool`- either `true` for release mode builds or `false` for debug mode builds.541 * "is_release" `bool`- either `true` for release mode builds or `false` for debug mode builds.
542 * "is_test" `bool`- either `true` for test builds or `false` otherwise.542 * "is_test" `bool`- either `true` for test builds or `false` otherwise.
543 * "os" `@OS` - use `zig targets` to see what enum values are possible here.543 * "os" `Os` - use `zig targets` to see what enum values are possible here.
544 * "arch" `@Arch` - use `zig targets` to see what enum values are possible here.544 * "arch" `Arch` - use `zig targets` to see what enum values are possible here.
545 * "environ" `@Environ` - use `zig targets` to see what enum values are possible here.545 * "environ" `Environ` - use `zig targets` to see what enum values are possible here.
546546
547Build scripts can set additional compile variables of any name and type.547Build scripts can set additional compile variables of any name and type.
548548
...@@ -556,6 +556,18 @@ expression is not known at compile time....@@ -556,6 +556,18 @@ expression is not known at compile time.
556556
557The result of the function is the result of the expression.557The result of the function is the result of the expression.
558558
559### @generatedCode(expression) -> @typeOf(expression)
560
561This function wraps an expression and returns the result of the expression
562unmodified.
563
564Inside the expression, code is considered generated, which means that the
565following compile errors are disabled:
566
567 * unnecessary if statement error
568
569The result of the expression is marked as depending on a compile variable.
570
559### @ctz(x: T) -> T571### @ctz(x: T) -> T
560572
561This function counts the number of trailing zeroes in x which is an integer573This function counts the number of trailing zeroes in x which is an integer
...@@ -638,3 +650,4 @@ This function returns an integer type with the given signness and bit count....@@ -638,3 +650,4 @@ This function returns an integer type with the given signness and bit count.
638### @setFnTest(func)650### @setFnTest(func)
639651
640Makes the target function a test function.652Makes the target function a test function.
653
src/all_types.hpp+9
...@@ -942,6 +942,7 @@ struct TypeTableEntry {...@@ -942,6 +942,7 @@ struct TypeTableEntry {
942 ZigLLVMDIType *di_type;942 ZigLLVMDIType *di_type;
943943
944 bool zero_bits;944 bool zero_bits;
945 bool size_depends_on_compile_var;
945946
946 union {947 union {
947 TypeTableEntryPointer pointer;948 TypeTableEntryPointer pointer;
...@@ -1053,6 +1054,7 @@ enum BuiltinFnId {...@@ -1053,6 +1054,7 @@ enum BuiltinFnId {
1053 BuiltinFnIdCompileVar,1054 BuiltinFnIdCompileVar,
1054 BuiltinFnIdCompileErr,1055 BuiltinFnIdCompileErr,
1055 BuiltinFnIdStaticEval,1056 BuiltinFnIdStaticEval,
1057 BuiltinFnIdGeneratedCode,
1056 BuiltinFnIdCtz,1058 BuiltinFnIdCtz,
1057 BuiltinFnIdClz,1059 BuiltinFnIdClz,
1058 BuiltinFnIdImport,1060 BuiltinFnIdImport,
...@@ -1440,6 +1442,7 @@ enum IrInstructionId {...@@ -1440,6 +1442,7 @@ enum IrInstructionId {
1440 IrInstructionIdClz,1442 IrInstructionIdClz,
1441 IrInstructionIdCtz,1443 IrInstructionIdCtz,
1442 IrInstructionIdStaticEval,1444 IrInstructionIdStaticEval,
1445 IrInstructionIdGeneratedCode,
1443 IrInstructionIdImport,1446 IrInstructionIdImport,
1444 IrInstructionIdCImport,1447 IrInstructionIdCImport,
1445 IrInstructionIdCInclude,1448 IrInstructionIdCInclude,
...@@ -1856,6 +1859,12 @@ struct IrInstructionStaticEval {...@@ -1856,6 +1859,12 @@ struct IrInstructionStaticEval {
1856 IrInstruction *value;1859 IrInstruction *value;
1857};1860};
18581861
1862struct IrInstructionGeneratedCode {
1863 IrInstruction base;
1864
1865 IrInstruction *value;
1866};
1867
1859struct IrInstructionImport {1868struct IrInstructionImport {
1860 IrInstruction base;1869 IrInstruction base;
18611870
src/analyze.cpp+6
...@@ -1148,6 +1148,9 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1148,6 +1148,9 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1148 continue;1148 continue;
1149 }1149 }
11501150
1151 enum_type->size_depends_on_compile_var = enum_type->size_depends_on_compile_var ||
1152 field_type->size_depends_on_compile_var;
1153
1151 if (!type_has_bits(field_type))1154 if (!type_has_bits(field_type))
1152 continue;1155 continue;
11531156
...@@ -1316,6 +1319,9 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {...@@ -1316,6 +1319,9 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
1316 continue;1319 continue;
1317 }1320 }
13181321
1322 struct_type->size_depends_on_compile_var = struct_type->size_depends_on_compile_var ||
1323 field_type->size_depends_on_compile_var;
1324
1319 if (!type_has_bits(field_type))1325 if (!type_has_bits(field_type))
1320 continue;1326 continue;
13211327
src/codegen.cpp+5
...@@ -2273,6 +2273,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -2273,6 +2273,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
2273 case IrInstructionIdAlignOf:2273 case IrInstructionIdAlignOf:
2274 case IrInstructionIdFnProto:2274 case IrInstructionIdFnProto:
2275 case IrInstructionIdTestComptime:2275 case IrInstructionIdTestComptime:
2276 case IrInstructionIdGeneratedCode:
2276 zig_unreachable();2277 zig_unreachable();
2277 case IrInstructionIdReturn:2278 case IrInstructionIdReturn:
2278 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);2279 return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
...@@ -3201,6 +3202,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3201,6 +3202,7 @@ static void define_builtin_types(CodeGen *g) {
3201 bool is_signed = info->is_signed;3202 bool is_signed = info->is_signed;
32023203
3203 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3204 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3205 entry->size_depends_on_compile_var = true;
3204 entry->type_ref = LLVMIntType(size_in_bits);3206 entry->type_ref = LLVMIntType(size_in_bits);
32053207
3206 buf_init_from_str(&entry->name, info->name);3208 buf_init_from_str(&entry->name, info->name);
...@@ -3237,6 +3239,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3237,6 +3239,7 @@ static void define_builtin_types(CodeGen *g) {
32373239
3238 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);3240 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt);
3239 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);3241 entry->type_ref = LLVMIntType(g->pointer_size_bytes * 8);
3242 entry->size_depends_on_compile_var = true;
32403243
3241 const char u_or_i = is_signed ? 'i' : 'u';3244 const char u_or_i = is_signed ? 'i' : 'u';
3242 buf_resize(&entry->name, 0);3245 buf_resize(&entry->name, 0);
...@@ -3292,6 +3295,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -3292,6 +3295,7 @@ static void define_builtin_types(CodeGen *g) {
3292 {3295 {
3293 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);3296 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
3294 entry->type_ref = LLVMX86FP80Type();3297 entry->type_ref = LLVMX86FP80Type();
3298 entry->size_depends_on_compile_var = true;
3295 buf_init_from_str(&entry->name, "c_long_double");3299 buf_init_from_str(&entry->name, "c_long_double");
3296 entry->data.floating.bit_count = 80;3300 entry->data.floating.bit_count = 80;
32973301
...@@ -3613,6 +3617,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -3613,6 +3617,7 @@ static void define_builtin_fns(CodeGen *g) {
3613 create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1);3617 create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1);
3614 create_builtin_fn(g, BuiltinFnIdCompileVar, "compileVar", 1);3618 create_builtin_fn(g, BuiltinFnIdCompileVar, "compileVar", 1);
3615 create_builtin_fn(g, BuiltinFnIdStaticEval, "staticEval", 1);3619 create_builtin_fn(g, BuiltinFnIdStaticEval, "staticEval", 1);
3620 create_builtin_fn(g, BuiltinFnIdGeneratedCode, "generatedCode", 1);
3616 create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1);3621 create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1);
3617 create_builtin_fn(g, BuiltinFnIdClz, "clz", 1);3622 create_builtin_fn(g, BuiltinFnIdClz, "clz", 1);
3618 create_builtin_fn(g, BuiltinFnIdImport, "import", 1);3623 create_builtin_fn(g, BuiltinFnIdImport, "import", 1);
src/ir.cpp+110-31
...@@ -307,6 +307,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStaticEval *) {...@@ -307,6 +307,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionStaticEval *) {
307 return IrInstructionIdStaticEval;307 return IrInstructionIdStaticEval;
308}308}
309309
310static constexpr IrInstructionId ir_instruction_id(IrInstructionGeneratedCode *) {
311 return IrInstructionIdGeneratedCode;
312}
313
310static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) {314static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) {
311 return IrInstructionIdImport;315 return IrInstructionIdImport;
312}316}
...@@ -616,19 +620,20 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode...@@ -616,19 +620,20 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode
616}620}
617621
618static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,622static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
619 TypeTableEntry *type_entry)623 TypeTableEntry *type_entry, bool depends_on_compile_var)
620{624{
621 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node);625 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node);
622 const_instruction->base.value.type = irb->codegen->builtin_types.entry_type;626 const_instruction->base.value.type = irb->codegen->builtin_types.entry_type;
623 const_instruction->base.value.special = ConstValSpecialStatic;627 const_instruction->base.value.special = ConstValSpecialStatic;
628 const_instruction->base.value.depends_on_compile_var = depends_on_compile_var;
624 const_instruction->base.value.data.x_type = type_entry;629 const_instruction->base.value.data.x_type = type_entry;
625 return &const_instruction->base;630 return &const_instruction->base;
626}631}
627632
628static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,633static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
629 TypeTableEntry *type_entry)634 TypeTableEntry *type_entry, bool depends_on_compile_var)
630{635{
631 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry);636 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry, depends_on_compile_var);
632 ir_instruction_append(irb->current_basic_block, instruction);637 ir_instruction_append(irb->current_basic_block, instruction);
633 return instruction;638 return instruction;
634}639}
...@@ -1392,6 +1397,17 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, Scope *scope, AstNode...@@ -1392,6 +1397,17 @@ static IrInstruction *ir_build_static_eval(IrBuilder *irb, Scope *scope, AstNode
1392 return &instruction->base;1397 return &instruction->base;
1393}1398}
13941399
1400static IrInstruction *ir_build_generated_code(IrBuilder *irb, Scope *scope, AstNode *source_node,
1401 IrInstruction *value)
1402{
1403 IrInstructionGeneratedCode *instruction = ir_build_instruction<IrInstructionGeneratedCode>(irb, scope, source_node);
1404 instruction->value = value;
1405
1406 ir_ref_instruction(value, irb->current_basic_block);
1407
1408 return &instruction->base;
1409}
1410
1395static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) {1411static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) {
1396 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node);1412 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node);
1397 instruction->name = name;1413 instruction->name = name;
...@@ -2258,6 +2274,13 @@ static IrInstruction *ir_instruction_staticeval_get_dep(IrInstructionStaticEval...@@ -2258,6 +2274,13 @@ static IrInstruction *ir_instruction_staticeval_get_dep(IrInstructionStaticEval
2258 }2274 }
2259}2275}
22602276
2277static IrInstruction *ir_instruction_generatedcode_get_dep(IrInstructionGeneratedCode *instruction, size_t index) {
2278 switch (index) {
2279 case 0: return instruction->value;
2280 default: return nullptr;
2281 }
2282}
2283
2261static IrInstruction *ir_instruction_import_get_dep(IrInstructionImport *instruction, size_t index) {2284static IrInstruction *ir_instruction_import_get_dep(IrInstructionImport *instruction, size_t index) {
2262 switch (index) {2285 switch (index) {
2263 case 0: return instruction->name;2286 case 0: return instruction->name;
...@@ -2645,6 +2668,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t...@@ -2645,6 +2668,8 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t
2645 return ir_instruction_ctz_get_dep((IrInstructionCtz *) instruction, index);2668 return ir_instruction_ctz_get_dep((IrInstructionCtz *) instruction, index);
2646 case IrInstructionIdStaticEval:2669 case IrInstructionIdStaticEval:
2647 return ir_instruction_staticeval_get_dep((IrInstructionStaticEval *) instruction, index);2670 return ir_instruction_staticeval_get_dep((IrInstructionStaticEval *) instruction, index);
2671 case IrInstructionIdGeneratedCode:
2672 return ir_instruction_generatedcode_get_dep((IrInstructionGeneratedCode *) instruction, index);
2648 case IrInstructionIdImport:2673 case IrInstructionIdImport:
2649 return ir_instruction_import_get_dep((IrInstructionImport *) instruction, index);2674 return ir_instruction_import_get_dep((IrInstructionImport *) instruction, index);
2650 case IrInstructionIdCImport:2675 case IrInstructionIdCImport:
...@@ -2846,7 +2871,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -2846,7 +2871,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
2846 is_comptime = ir_build_test_comptime(irb, scope, node, is_err);2871 is_comptime = ir_build_test_comptime(irb, scope, node, is_err);
2847 }2872 }
28482873
2849 ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime);2874 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime));
28502875
2851 ir_set_cursor_at_end(irb, err_block);2876 ir_set_cursor_at_end(irb, err_block);
2852 ir_gen_defers_for_block(irb, scope, outer_scope, true, false);2877 ir_gen_defers_for_block(irb, scope, outer_scope, true, false);
...@@ -2868,7 +2893,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -2868,7 +2893,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
2868 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null);2893 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null);
2869 }2894 }
28702895
2871 ir_build_cond_br(irb, scope, node, is_non_null, ok_block, null_block, is_comptime);2896 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_non_null, ok_block, null_block, is_comptime));
28722897
2873 ir_set_cursor_at_end(irb, null_block);2898 ir_set_cursor_at_end(irb, null_block);
2874 ir_gen_defers_for_block(irb, scope, outer_scope, false, true);2899 ir_gen_defers_for_block(irb, scope, outer_scope, false, true);
...@@ -2895,7 +2920,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -2895,7 +2920,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
2895 IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "ErrRetReturn");2920 IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "ErrRetReturn");
2896 IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "ErrRetContinue");2921 IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "ErrRetContinue");
2897 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb));2922 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb));
2898 ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime);2923 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime));
28992924
2900 ir_set_cursor_at_end(irb, return_block);2925 ir_set_cursor_at_end(irb, return_block);
2901 ir_gen_defers_for_block(irb, scope, outer_scope, true, false);2926 ir_gen_defers_for_block(irb, scope, outer_scope, true, false);
...@@ -2921,7 +2946,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -2921,7 +2946,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
2921 IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "MaybeRetReturn");2946 IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "MaybeRetReturn");
2922 IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "MaybeRetContinue");2947 IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "MaybeRetContinue");
2923 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb));2948 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb));
2924 ir_build_cond_br(irb, scope, node, is_non_null, continue_block, return_block, is_comptime);2949 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_non_null, continue_block, return_block, is_comptime));
29252950
2926 ir_set_cursor_at_end(irb, return_block);2951 ir_set_cursor_at_end(irb, return_block);
2927 ir_gen_defers_for_block(irb, scope, outer_scope, false, true);2952 ir_gen_defers_for_block(irb, scope, outer_scope, false, true);
...@@ -3388,7 +3413,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode...@@ -3388,7 +3413,7 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode
3388static IrInstruction *ir_gen_var_literal(IrBuilder *irb, Scope *scope, AstNode *node) {3413static IrInstruction *ir_gen_var_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
3389 assert(node->type == NodeTypeVarLiteral);3414 assert(node->type == NodeTypeVarLiteral);
33903415
3391 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var);3416 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var, false);
3392}3417}
33933418
3394static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld *tld,3419static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld *tld,
...@@ -3426,7 +3451,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld...@@ -3426,7 +3451,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld
3426 {3451 {
3427 TldTypeDef *tld_typedef = (TldTypeDef *)tld;3452 TldTypeDef *tld_typedef = (TldTypeDef *)tld;
3428 TypeTableEntry *typedef_type = tld_typedef->type_entry;3453 TypeTableEntry *typedef_type = tld_typedef->type_entry;
3429 IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, typedef_type);3454 IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, typedef_type, false);
3430 if (lval != LValPurposeNone)3455 if (lval != LValPurposeNone)
3431 return ir_build_ref(irb, scope, source_node, ref_instruction, true);3456 return ir_build_ref(irb, scope, source_node, ref_instruction, true);
3432 else3457 else
...@@ -3443,7 +3468,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3443,7 +3468,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
34433468
3444 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);3469 auto primitive_table_entry = irb->codegen->primitive_type_table.maybe_get(variable_name);
3445 if (primitive_table_entry) {3470 if (primitive_table_entry) {
3446 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value);3471 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value, false);
3447 if (lval != LValPurposeNone) {3472 if (lval != LValPurposeNone) {
3448 return ir_build_ref(irb, scope, node, value, lval == LValPurposeAddressOfConst);3473 return ir_build_ref(irb, scope, node, value, lval == LValPurposeAddressOfConst);
3449 } else {3474 } else {
...@@ -3664,6 +3689,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -3664,6 +3689,15 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
36643689
3665 return ir_build_static_eval(irb, scope, node, arg0_value);3690 return ir_build_static_eval(irb, scope, node, arg0_value);
3666 }3691 }
3692 case BuiltinFnIdGeneratedCode:
3693 {
3694 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
3695 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
3696 if (arg0_value == irb->codegen->invalid_instruction)
3697 return arg0_value;
3698
3699 return ir_build_generated_code(irb, scope, node, arg0_value);
3700 }
3667 case BuiltinFnIdImport:3701 case BuiltinFnIdImport:
3668 {3702 {
3669 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);3703 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -4327,7 +4361,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -4327,7 +4361,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
4327 }4361 }
4328 child_scope = index_var->child_scope;4362 child_scope = index_var->child_scope;
43294363
4330 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize);4364 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize, false);
4331 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0);4365 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0);
4332 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1);4366 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1);
4333 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, zero);4367 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, zero);
...@@ -4345,7 +4379,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -4345,7 +4379,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
4345 ir_set_cursor_at_end(irb, cond_block);4379 ir_set_cursor_at_end(irb, cond_block);
4346 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr);4380 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr);
4347 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);4381 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
4348 ir_build_cond_br(irb, child_scope, node, cond, body_block, end_block, is_comptime);4382 ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, end_block, is_comptime));
43494383
4350 ir_set_cursor_at_end(irb, body_block);4384 ir_set_cursor_at_end(irb, body_block);
4351 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false);4385 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false);
...@@ -4391,7 +4425,7 @@ static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode...@@ -4391,7 +4425,7 @@ static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode
4391 ScopeDecls *decls_scope = (ScopeDecls *)scope;4425 ScopeDecls *decls_scope = (ScopeDecls *)scope;
4392 TypeTableEntry *container_type = decls_scope->container_type;4426 TypeTableEntry *container_type = decls_scope->container_type;
4393 assert(container_type);4427 assert(container_type);
4394 return ir_build_const_type(irb, scope, node, container_type);4428 return ir_build_const_type(irb, scope, node, container_type, false);
4395 }4429 }
43964430
4397 if (scope->id == ScopeIdBlock)4431 if (scope->id == ScopeIdBlock)
...@@ -4719,7 +4753,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -4719,7 +4753,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
47194753
4720 assert(ok_bit);4754 assert(ok_bit);
4721 assert(last_item_node);4755 assert(last_item_node);
4722 ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, range_block_no, is_comptime);4756 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes,
4757 range_block_no, is_comptime));
47234758
4724 ir_set_cursor_at_end(irb, range_block_yes);4759 ir_set_cursor_at_end(irb, range_block_yes);
4725 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,4760 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
...@@ -4843,12 +4878,12 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -4843,12 +4878,12 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod
48434878
4844static IrInstruction *ir_gen_type_literal(IrBuilder *irb, Scope *scope, AstNode *node) {4879static IrInstruction *ir_gen_type_literal(IrBuilder *irb, Scope *scope, AstNode *node) {
4845 assert(node->type == NodeTypeTypeLiteral);4880 assert(node->type == NodeTypeTypeLiteral);
4846 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_type);4881 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_type, false);
4847}4882}
48484883
4849static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) {4884static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) {
4850 assert(node->type == NodeTypeErrorType);4885 assert(node->type == NodeTypeErrorType);
4851 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_pure_error);4886 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_pure_error, false);
4852}4887}
48534888
4854static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {4889static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
...@@ -4922,7 +4957,7 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN...@@ -4922,7 +4957,7 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
4922 if (var_node) {4957 if (var_node) {
4923 assert(var_node->type == NodeTypeSymbol);4958 assert(var_node->type == NodeTypeSymbol);
4924 IrInstruction *var_type = ir_build_const_type(irb, parent_scope, node,4959 IrInstruction *var_type = ir_build_const_type(irb, parent_scope, node,
4925 irb->codegen->builtin_types.entry_pure_error);4960 irb->codegen->builtin_types.entry_pure_error, false);
4926 Buf *var_name = var_node->data.symbol_expr.symbol;4961 Buf *var_name = var_node->data.symbol_expr.symbol;
4927 bool is_const = true;4962 bool is_const = true;
4928 bool is_shadowable = false;4963 bool is_shadowable = false;
...@@ -5008,7 +5043,7 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,...@@ -5008,7 +5043,7 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope,
5008 }5043 }
5009 irb->codegen->resolve_queue.append(&tld_container->base);5044 irb->codegen->resolve_queue.append(&tld_container->base);
50105045
5011 return ir_build_const_type(irb, parent_scope, node, container_type);5046 return ir_build_const_type(irb, parent_scope, node, container_type, false);
5012}5047}
50135048
5014static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) {5049static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) {
...@@ -6530,8 +6565,10 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc...@@ -6530,8 +6565,10 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
6530 ConstExprValue *pointee = const_ptr_pointee(&ptr->value);6565 ConstExprValue *pointee = const_ptr_pointee(&ptr->value);
6531 if (pointee->special != ConstValSpecialRuntime) {6566 if (pointee->special != ConstValSpecialRuntime) {
6532 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,6567 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope,
6533 source_instruction->source_node, child_type, pointee->depends_on_compile_var);6568 source_instruction->source_node, child_type, false);
6534 result->value = *pointee;6569 result->value = *pointee;
6570 result->value.depends_on_compile_var = pointee->depends_on_compile_var ||
6571 ptr->value.depends_on_compile_var;
6535 return result;6572 return result;
6536 }6573 }
6537 }6574 }
...@@ -6547,7 +6584,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc...@@ -6547,7 +6584,8 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
6547 TypeTableEntry *ptr_type = ptr_val->data.x_type;6584 TypeTableEntry *ptr_type = ptr_val->data.x_type;
6548 if (ptr_type->id == TypeTableEntryIdPointer) {6585 if (ptr_type->id == TypeTableEntryIdPointer) {
6549 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;6586 TypeTableEntry *child_type = ptr_type->data.pointer.child_type;
6550 return ir_create_const_type(&ira->new_irb, source_instruction->scope, source_instruction->source_node, child_type);6587 return ir_create_const_type(&ira->new_irb, source_instruction->scope,
6588 source_instruction->source_node, child_type, ptr_val->depends_on_compile_var);
6551 } else {6589 } else {
6552 ir_add_error(ira, source_instruction,6590 ir_add_error(ira, source_instruction,
6553 buf_sprintf("attempt to dereference non pointer type '%s'", buf_ptr(&ptr_type->name)));6591 buf_sprintf("attempt to dereference non pointer type '%s'", buf_ptr(&ptr_type->name)));
...@@ -6572,7 +6610,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst...@@ -6572,7 +6610,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst
6572 if (!val)6610 if (!val)
6573 return ira->codegen->builtin_types.entry_invalid;6611 return ira->codegen->builtin_types.entry_invalid;
6574 return ir_analyze_const_ptr(ira, source_instruction, val, value->value.type,6612 return ir_analyze_const_ptr(ira, source_instruction, val, value->value.type,
6575 false, ConstPtrSpecialNone, is_const);6613 value->value.depends_on_compile_var, ConstPtrSpecialNone, is_const);
6576 }6614 }
65776615
6578 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, value->value.type, true);6616 TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, value->value.type, true);
...@@ -7367,6 +7405,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node...@@ -7367,6 +7405,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
7367 Buf *param_name = param_decl_node->data.param_decl.name;7405 Buf *param_name = param_decl_node->data.param_decl.name;
7368 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,7406 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,
7369 *exec_scope, param_name, true, arg_val);7407 *exec_scope, param_name, true, arg_val);
7408 var->value.depends_on_compile_var = true;
7370 *exec_scope = var->child_scope;7409 *exec_scope = var->child_scope;
7371 *next_proto_i += 1;7410 *next_proto_i += 1;
73727411
...@@ -7408,6 +7447,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -7408,6 +7447,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
7408 Buf *param_name = param_decl_node->data.param_decl.name;7447 Buf *param_name = param_decl_node->data.param_decl.name;
7409 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,7448 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,
7410 *child_scope, param_name, true, arg_val);7449 *child_scope, param_name, true, arg_val);
7450 var->value.depends_on_compile_var = true;
7411 *child_scope = var->child_scope;7451 *child_scope = var->child_scope;
74127452
7413 if (inline_arg || is_var_type) {7453 if (inline_arg || is_var_type) {
...@@ -7986,6 +8026,14 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct...@@ -7986,6 +8026,14 @@ static TypeTableEntry *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstruct
7986 if (!ir_resolve_bool(ira, condition, &cond_is_true))8026 if (!ir_resolve_bool(ira, condition, &cond_is_true))
7987 return ir_unreach_error(ira);8027 return ir_unreach_error(ira);
79888028
8029 if (!cond_br_instruction->base.is_gen && !condition->value.depends_on_compile_var &&
8030 !ir_should_inline(&ira->new_irb))
8031 {
8032 const char *true_or_false = cond_is_true ? "true" : "false";
8033 ir_add_error(ira, &cond_br_instruction->base,
8034 buf_sprintf("condition is always %s; unnecessary if statement", true_or_false));
8035 }
8036
7989 IrBasicBlock *old_dest_block = cond_is_true ?8037 IrBasicBlock *old_dest_block = cond_is_true ?
7990 cond_br_instruction->then_block : cond_br_instruction->else_block;8038 cond_br_instruction->then_block : cond_br_instruction->else_block;
79918039
...@@ -8028,9 +8076,9 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -8028,9 +8076,9 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
8028 return ira->codegen->builtin_types.entry_invalid;8076 return ira->codegen->builtin_types.entry_invalid;
80298077
8030 if (value->value.special != ConstValSpecialRuntime) {8078 if (value->value.special != ConstValSpecialRuntime) {
8031 ConstExprValue *out_val = ir_build_const_from(ira, &phi_instruction->base,8079 ConstExprValue *out_val = ir_build_const_from(ira, &phi_instruction->base, true);
8032 value->value.depends_on_compile_var);
8033 *out_val = value->value;8080 *out_val = value->value;
8081 out_val->depends_on_compile_var = true;
8034 } else {8082 } else {
8035 phi_instruction->base.other = value;8083 phi_instruction->base.other = value;
8036 }8084 }
...@@ -8064,7 +8112,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -8064,7 +8112,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
8064 }8112 }
80658113
8066 if (new_incoming_blocks.length == 0) {8114 if (new_incoming_blocks.length == 0) {
8067 ir_build_const_from(ira, &phi_instruction->base, false);8115 ir_build_const_from(ira, &phi_instruction->base, true);
8068 return ira->codegen->builtin_types.entry_void;8116 return ira->codegen->builtin_types.entry_void;
8069 }8117 }
80708118
...@@ -8080,7 +8128,9 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -8080,7 +8128,9 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
8080 return resolved_type;8128 return resolved_type;
80818129
8082 if (resolved_type->id == TypeTableEntryIdNumLitFloat ||8130 if (resolved_type->id == TypeTableEntryIdNumLitFloat ||
8083 resolved_type->id == TypeTableEntryIdNumLitInt)8131 resolved_type->id == TypeTableEntryIdNumLitInt ||
8132 resolved_type->id == TypeTableEntryIdNullLit ||
8133 resolved_type->id == TypeTableEntryIdUndefLit)
8084 {8134 {
8085 ir_add_error_node(ira, phi_instruction->base.source_node,8135 ir_add_error_node(ira, phi_instruction->base.source_node,
8086 buf_sprintf("unable to infer expression type"));8136 buf_sprintf("unable to infer expression type"));
...@@ -8109,7 +8159,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -8109,7 +8159,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
8109}8159}
81108160
8111static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction,8161static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
8112 VariableTableEntry *var, bool is_const_ptr)8162 VariableTableEntry *var, bool is_const_ptr, bool depends_on_compile_var)
8113{8163{
8114 assert(var->value.type);8164 assert(var->value.type);
8115 if (var->value.type->id == TypeTableEntryIdInvalid)8165 if (var->value.type->id == TypeTableEntryIdInvalid)
...@@ -8131,7 +8181,8 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc...@@ -8131,7 +8181,8 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
8131 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {8181 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {
8132 ConstPtrSpecial ptr_special = is_comptime ? ConstPtrSpecialInline : ConstPtrSpecialNone;8182 ConstPtrSpecial ptr_special = is_comptime ? ConstPtrSpecialInline : ConstPtrSpecialNone;
8133 bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;8183 bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;
8134 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type, false, ptr_special, is_const);8184 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type,
8185 mem_slot->depends_on_compile_var || depends_on_compile_var, ptr_special, is_const);
8135 } else {8186 } else {
8136 ir_build_var_ptr_from(&ira->new_irb, instruction, var, false);8187 ir_build_var_ptr_from(&ira->new_irb, instruction, var, false);
8137 type_ensure_zero_bits_known(ira->codegen, var->value.type);8188 type_ensure_zero_bits_known(ira->codegen, var->value.type);
...@@ -8141,7 +8192,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc...@@ -8141,7 +8192,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
81418192
8142static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {8193static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {
8143 VariableTableEntry *var = var_ptr_instruction->var;8194 VariableTableEntry *var = var_ptr_instruction->var;
8144 return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var, var_ptr_instruction->is_const);8195 return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var, var_ptr_instruction->is_const, false);
8145}8196}
81468197
8147static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {8198static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) {
...@@ -8295,6 +8346,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -8295,6 +8346,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
8295 ensure_complete_type(ira->codegen, bare_type);8346 ensure_complete_type(ira->codegen, bare_type);
82968347
8297 if (bare_type->id == TypeTableEntryIdStruct) {8348 if (bare_type->id == TypeTableEntryIdStruct) {
8349 if (bare_type->data.structure.is_invalid)
8350 return ira->codegen->builtin_types.entry_invalid;
8351
8298 TypeStructField *field = find_struct_type_field(bare_type, field_name);8352 TypeStructField *field = find_struct_type_field(bare_type, field_name);
8299 if (field) {8353 if (field) {
8300 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);8354 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
...@@ -8304,6 +8358,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -8304,6 +8358,9 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
8304 field_ptr_instruction, container_ptr, container_type);8358 field_ptr_instruction, container_ptr, container_type);
8305 }8359 }
8306 } else if (bare_type->id == TypeTableEntryIdEnum) {8360 } else if (bare_type->id == TypeTableEntryIdEnum) {
8361 if (bare_type->data.enumeration.is_invalid)
8362 return ira->codegen->builtin_types.entry_invalid;
8363
8307 TypeEnumField *field = find_enum_type_field(bare_type, field_name);8364 TypeEnumField *field = find_enum_type_field(bare_type, field_name);
8308 if (field) {8365 if (field) {
8309 ir_build_enum_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);8366 ir_build_enum_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
...@@ -8334,7 +8391,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source...@@ -8334,7 +8391,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
8334 {8391 {
8335 TldVar *tld_var = (TldVar *)tld;8392 TldVar *tld_var = (TldVar *)tld;
8336 VariableTableEntry *var = tld_var->var;8393 VariableTableEntry *var = tld_var->var;
8337 return ir_analyze_var_ptr(ira, source_instruction, var, false);8394 return ir_analyze_var_ptr(ira, source_instruction, var, false, depends_on_compile_var);
8338 }8395 }
8339 case TldIdFn:8396 case TldIdFn:
8340 {8397 {
...@@ -9065,9 +9122,8 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,...@@ -9065,9 +9122,8 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
9065 case TypeTableEntryIdEnumTag:9122 case TypeTableEntryIdEnumTag:
9066 {9123 {
9067 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);9124 uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
9068 bool depends_on_compile_var = false; // TODO types should be able to depend on compile var
9069 ConstExprValue *out_val = ir_build_const_from(ira, &size_of_instruction->base,9125 ConstExprValue *out_val = ir_build_const_from(ira, &size_of_instruction->base,
9070 depends_on_compile_var);9126 type_entry->size_depends_on_compile_var);
9071 bignum_init_unsigned(&out_val->data.x_bignum, size_in_bytes);9127 bignum_init_unsigned(&out_val->data.x_bignum, size_in_bytes);
9072 return ira->codegen->builtin_types.entry_num_lit_int;9128 return ira->codegen->builtin_types.entry_num_lit_int;
9073 }9129 }
...@@ -9463,6 +9519,26 @@ static TypeTableEntry *ir_analyze_instruction_static_eval(IrAnalyze *ira,...@@ -9463,6 +9519,26 @@ static TypeTableEntry *ir_analyze_instruction_static_eval(IrAnalyze *ira,
9463 return value->value.type;9519 return value->value.type;
9464}9520}
94659521
9522static TypeTableEntry *ir_analyze_instruction_generated_code(IrAnalyze *ira, IrInstructionGeneratedCode *instruction) {
9523 IrInstruction *value = instruction->value->other;
9524 if (value->value.type->id == TypeTableEntryIdInvalid)
9525 return ira->codegen->builtin_types.entry_invalid;
9526
9527 if (instr_is_comptime(value)) {
9528 ConstExprValue *val = ir_resolve_const(ira, value, UndefOk);
9529 if (!val)
9530 return ira->codegen->builtin_types.entry_invalid;
9531
9532 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, false);
9533 *out_val = *val;
9534 out_val->depends_on_compile_var = true;
9535 return value->value.type;
9536 }
9537
9538 instruction->base.other = value;
9539 return value->value.type;
9540}
9541
9466static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) {9542static TypeTableEntry *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) {
9467 IrInstruction *name_value = import_instruction->name->other;9543 IrInstruction *name_value = import_instruction->name->other;
9468 Buf *import_target_str = ir_resolve_str(ira, name_value);9544 Buf *import_target_str = ir_resolve_str(ira, name_value);
...@@ -11078,6 +11154,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -11078,6 +11154,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
11078 return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction);11154 return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction);
11079 case IrInstructionIdStaticEval:11155 case IrInstructionIdStaticEval:
11080 return ir_analyze_instruction_static_eval(ira, (IrInstructionStaticEval *)instruction);11156 return ir_analyze_instruction_static_eval(ira, (IrInstructionStaticEval *)instruction);
11157 case IrInstructionIdGeneratedCode:
11158 return ir_analyze_instruction_generated_code(ira, (IrInstructionGeneratedCode *)instruction);
11081 case IrInstructionIdImport:11159 case IrInstructionIdImport:
11082 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction);11160 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction);
11083 case IrInstructionIdArrayLen:11161 case IrInstructionIdArrayLen:
...@@ -11284,6 +11362,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -11284,6 +11362,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
11284 case IrInstructionIdSwitchTarget:11362 case IrInstructionIdSwitchTarget:
11285 case IrInstructionIdEnumTag:11363 case IrInstructionIdEnumTag:
11286 case IrInstructionIdStaticEval:11364 case IrInstructionIdStaticEval:
11365 case IrInstructionIdGeneratedCode:
11287 case IrInstructionIdRef:11366 case IrInstructionIdRef:
11288 case IrInstructionIdMinValue:11367 case IrInstructionIdMinValue:
11289 case IrInstructionIdMaxValue:11368 case IrInstructionIdMaxValue:
src/ir_print.cpp+9
...@@ -492,6 +492,12 @@ static void ir_print_static_eval(IrPrint *irp, IrInstructionStaticEval *instruct...@@ -492,6 +492,12 @@ static void ir_print_static_eval(IrPrint *irp, IrInstructionStaticEval *instruct
492 fprintf(irp->f, ")");492 fprintf(irp->f, ")");
493}493}
494494
495static void ir_print_generated_code(IrPrint *irp, IrInstructionGeneratedCode *instruction) {
496 fprintf(irp->f, "@generatedCode(");
497 ir_print_other_instruction(irp, instruction->value);
498 fprintf(irp->f, ")");
499}
500
495static void ir_print_import(IrPrint *irp, IrInstructionImport *instruction) {501static void ir_print_import(IrPrint *irp, IrInstructionImport *instruction) {
496 fprintf(irp->f, "@import(");502 fprintf(irp->f, "@import(");
497 ir_print_other_instruction(irp, instruction->name);503 ir_print_other_instruction(irp, instruction->name);
...@@ -921,6 +927,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -921,6 +927,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
921 case IrInstructionIdStaticEval:927 case IrInstructionIdStaticEval:
922 ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction);928 ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction);
923 break;929 break;
930 case IrInstructionIdGeneratedCode:
931 ir_print_generated_code(irp, (IrInstructionGeneratedCode *)instruction);
932 break;
924 case IrInstructionIdImport:933 case IrInstructionIdImport:
925 ir_print_import(irp, (IrInstructionImport *)instruction);934 ir_print_import(irp, (IrInstructionImport *)instruction);
926 break;935 break;
test/cases/math.zig+6-3
...@@ -72,9 +72,11 @@ fn modifyOperators() {...@@ -72,9 +72,11 @@ fn modifyOperators() {
7272
73fn threeExprInARow() {73fn threeExprInARow() {
74 @setFnTest(this);74 @setFnTest(this);
7575 testThreeExprInARow(false, true);
76 assertFalse(false || false || false);76}
77 assertFalse(true && true && false);77fn testThreeExprInARow(f: bool, t: bool) {
78 assertFalse(f || f || f);
79 assertFalse(t && t && f);
78 assertFalse(1 | 2 | 4 != 7);80 assertFalse(1 | 2 | 4 != 7);
79 assertFalse(3 ^ 6 ^ 8 != 13);81 assertFalse(3 ^ 6 ^ 8 != 13);
80 assertFalse(7 & 14 & 28 != 4);82 assertFalse(7 & 14 & 28 != 4);
...@@ -86,6 +88,7 @@ fn threeExprInARow() {...@@ -86,6 +88,7 @@ fn threeExprInARow() {
86 assertFalse(!!false);88 assertFalse(!!false);
87 assertFalse(i32(7) != --(i32(7)));89 assertFalse(i32(7) != --(i32(7)));
88}90}
91
89fn assertFalse(b: bool) {92fn assertFalse(b: bool) {
90 assert(!b);93 assert(!b);
91}94}
test/cases/misc.zig+16-13
...@@ -86,26 +86,29 @@ fn maxValueType() {...@@ -86,26 +86,29 @@ fn maxValueType() {
8686
87fn shortCircuit() {87fn shortCircuit() {
88 @setFnTest(this);88 @setFnTest(this);
89 testShortCircuit(false, true);
90}
8991
90 var hit_1 = false;92fn testShortCircuit(f: bool, t: bool) {
91 var hit_2 = false;93 var hit_1 = f;
92 var hit_3 = false;94 var hit_2 = f;
93 var hit_4 = false;95 var hit_3 = f;
96 var hit_4 = f;
9497
95 if (true || {assert(false); false}) {98 if (t || {assert(f); f}) {
96 hit_1 = true;99 hit_1 = t;
97 }100 }
98 if (false || { hit_2 = true; false }) {101 if (f || { hit_2 = t; f }) {
99 assert(false);102 assert(f);
100 }103 }
101104
102 if (true && { hit_3 = true; false }) {105 if (t && { hit_3 = t; f }) {
103 assert(false);106 assert(f);
104 }107 }
105 if (false && {assert(false); false}) {108 if (f && {assert(f); f}) {
106 assert(false);109 assert(f);
107 } else {110 } else {
108 hit_4 = true;111 hit_4 = t;
109 }112 }
110 assert(hit_1);113 assert(hit_1);
111 assert(hit_2);114 assert(hit_2);
test/cases/null.zig+4-4
...@@ -3,7 +3,7 @@ const assert = @import("std").debug.assert;...@@ -3,7 +3,7 @@ const assert = @import("std").debug.assert;
3fn nullableType() {3fn nullableType() {
4 @setFnTest(this);4 @setFnTest(this);
55
6 const x : ?bool = true;6 const x : ?bool = @generatedCode(true);
77
8 if (const y ?= x) {8 if (const y ?= x) {
9 if (y) {9 if (y) {
...@@ -15,13 +15,13 @@ fn nullableType() {...@@ -15,13 +15,13 @@ fn nullableType() {
15 @unreachable();15 @unreachable();
16 }16 }
1717
18 const next_x : ?i32 = null;18 const next_x : ?i32 = @generatedCode(null);
1919
20 const z = next_x ?? 1234;20 const z = next_x ?? 1234;
2121
22 assert(z == 1234);22 assert(z == 1234);
2323
24 const final_x : ?i32 = 13;24 const final_x : ?i32 = @generatedCode(13);
2525
26 const num = final_x ?? @unreachable();26 const num = final_x ?? @unreachable();
2727
...@@ -43,7 +43,7 @@ fn assignToIfVarPtr() {...@@ -43,7 +43,7 @@ fn assignToIfVarPtr() {
43fn rhsMaybeUnwrapReturn() {43fn rhsMaybeUnwrapReturn() {
44 @setFnTest(this);44 @setFnTest(this);
4545
46 const x: ?bool = true;46 const x: ?bool = @generatedCode(true);
47 const y = x ?? return;47 const y = x ?? return;
48}48}
4949