| ... | @@ -222,6 +222,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileVar *) { | ... | @@ -222,6 +222,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileVar *) { |
| 222 | return IrInstructionIdCompileVar; | 222 | return IrInstructionIdCompileVar; |
| 223 | } | 223 | } |
| 224 | | 224 | |
| | 225 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSizeOf *) { |
| | 226 | return IrInstructionIdSizeOf; |
| | 227 | } |
| | 228 | |
| 225 | template<typename T> | 229 | template<typename T> |
| 226 | static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { | 230 | static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) { |
| 227 | T *special_instruction = allocate<T>(1); | 231 | T *special_instruction = allocate<T>(1); |
| ... | @@ -865,6 +869,15 @@ static IrInstruction *ir_build_compile_var(IrBuilder *irb, AstNode *source_node, | ... | @@ -865,6 +869,15 @@ static IrInstruction *ir_build_compile_var(IrBuilder *irb, AstNode *source_node, |
| 865 | return &instruction->base; | 869 | return &instruction->base; |
| 866 | } | 870 | } |
| 867 | | 871 | |
| | 872 | static IrInstruction *ir_build_size_of(IrBuilder *irb, AstNode *source_node, IrInstruction *type_value) { |
| | 873 | IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, source_node); |
| | 874 | instruction->type_value = type_value; |
| | 875 | |
| | 876 | ir_ref_instruction(type_value); |
| | 877 | |
| | 878 | return &instruction->base; |
| | 879 | } |
| | 880 | |
| 868 | static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, | 881 | static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block, |
| 869 | bool gen_error_defers, bool gen_maybe_defers) | 882 | bool gen_error_defers, bool gen_maybe_defers) |
| 870 | { | 883 | { |
| ... | @@ -1356,9 +1369,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { | ... | @@ -1356,9 +1369,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) { |
| 1356 | | 1369 | |
| 1357 | return ir_build_compile_var(irb, node, arg0_value); | 1370 | return ir_build_compile_var(irb, node, arg0_value); |
| 1358 | } | 1371 | } |
| | 1372 | case BuiltinFnIdSizeof: |
| | 1373 | { |
| | 1374 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| | 1375 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context); |
| | 1376 | if (arg0_value == irb->codegen->invalid_instruction) |
| | 1377 | return arg0_value; |
| | 1378 | |
| | 1379 | return ir_build_size_of(irb, node, arg0_value); |
| | 1380 | } |
| 1359 | case BuiltinFnIdMemcpy: | 1381 | case BuiltinFnIdMemcpy: |
| 1360 | case BuiltinFnIdMemset: | 1382 | case BuiltinFnIdMemset: |
| 1361 | case BuiltinFnIdSizeof: | | |
| 1362 | case BuiltinFnIdAlignof: | 1383 | case BuiltinFnIdAlignof: |
| 1363 | case BuiltinFnIdMaxValue: | 1384 | case BuiltinFnIdMaxValue: |
| 1364 | case BuiltinFnIdMinValue: | 1385 | case BuiltinFnIdMinValue: |
| ... | @@ -4417,6 +4438,56 @@ static TypeTableEntry *ir_analyze_instruction_compile_var(IrAnalyze *ira, | ... | @@ -4417,6 +4438,56 @@ static TypeTableEntry *ir_analyze_instruction_compile_var(IrAnalyze *ira, |
| 4417 | zig_unreachable(); | 4438 | zig_unreachable(); |
| 4418 | } | 4439 | } |
| 4419 | | 4440 | |
| | 4441 | static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira, |
| | 4442 | IrInstructionSizeOf *size_of_instruction) |
| | 4443 | { |
| | 4444 | IrInstruction *type_value = size_of_instruction->type_value->other; |
| | 4445 | TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); |
| | 4446 | TypeTableEntry *canon_type_entry = get_underlying_type(type_entry); |
| | 4447 | switch (canon_type_entry->id) { |
| | 4448 | case TypeTableEntryIdInvalid: |
| | 4449 | return ira->codegen->builtin_types.entry_invalid; |
| | 4450 | case TypeTableEntryIdTypeDecl: |
| | 4451 | zig_unreachable(); |
| | 4452 | case TypeTableEntryIdVar: |
| | 4453 | case TypeTableEntryIdUnreachable: |
| | 4454 | case TypeTableEntryIdUndefLit: |
| | 4455 | case TypeTableEntryIdNullLit: |
| | 4456 | case TypeTableEntryIdBlock: |
| | 4457 | case TypeTableEntryIdNumLitFloat: |
| | 4458 | case TypeTableEntryIdNumLitInt: |
| | 4459 | case TypeTableEntryIdGenericFn: |
| | 4460 | case TypeTableEntryIdMetaType: |
| | 4461 | case TypeTableEntryIdFn: |
| | 4462 | case TypeTableEntryIdNamespace: |
| | 4463 | add_node_error(ira->codegen, size_of_instruction->base.source_node, |
| | 4464 | buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name))); |
| | 4465 | // TODO if this is a typedecl, add error note showing the declaration of the type decl |
| | 4466 | return ira->codegen->builtin_types.entry_invalid; |
| | 4467 | case TypeTableEntryIdVoid: |
| | 4468 | case TypeTableEntryIdBool: |
| | 4469 | case TypeTableEntryIdInt: |
| | 4470 | case TypeTableEntryIdFloat: |
| | 4471 | case TypeTableEntryIdPointer: |
| | 4472 | case TypeTableEntryIdArray: |
| | 4473 | case TypeTableEntryIdStruct: |
| | 4474 | case TypeTableEntryIdMaybe: |
| | 4475 | case TypeTableEntryIdErrorUnion: |
| | 4476 | case TypeTableEntryIdPureError: |
| | 4477 | case TypeTableEntryIdEnum: |
| | 4478 | case TypeTableEntryIdUnion: |
| | 4479 | { |
| | 4480 | uint64_t size_in_bytes = type_size(ira->codegen, type_entry); |
| | 4481 | bool depends_on_compile_var = false; // TODO types should be able to depend on compile var |
| | 4482 | ConstExprValue *out_val = ir_build_const_from(ira, &size_of_instruction->base, |
| | 4483 | depends_on_compile_var); |
| | 4484 | bignum_init_unsigned(&out_val->data.x_bignum, size_in_bytes); |
| | 4485 | return ira->codegen->builtin_types.entry_num_lit_int; |
| | 4486 | } |
| | 4487 | } |
| | 4488 | zig_unreachable(); |
| | 4489 | } |
| | 4490 | |
| 4420 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { | 4491 | static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { |
| 4421 | switch (instruction->id) { | 4492 | switch (instruction->id) { |
| 4422 | case IrInstructionIdInvalid: | 4493 | case IrInstructionIdInvalid: |
| ... | @@ -4471,6 +4542,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi | ... | @@ -4471,6 +4542,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 4471 | return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); | 4542 | return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); |
| 4472 | case IrInstructionIdCompileVar: | 4543 | case IrInstructionIdCompileVar: |
| 4473 | return ir_analyze_instruction_compile_var(ira, (IrInstructionCompileVar *)instruction); | 4544 | return ir_analyze_instruction_compile_var(ira, (IrInstructionCompileVar *)instruction); |
| | 4545 | case IrInstructionIdSizeOf: |
| | 4546 | return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction); |
| 4474 | case IrInstructionIdSwitchBr: | 4547 | case IrInstructionIdSwitchBr: |
| 4475 | case IrInstructionIdCast: | 4548 | case IrInstructionIdCast: |
| 4476 | case IrInstructionIdContainerInitList: | 4549 | case IrInstructionIdContainerInitList: |
| ... | @@ -4580,6 +4653,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -4580,6 +4653,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 4580 | case IrInstructionIdArrayType: | 4653 | case IrInstructionIdArrayType: |
| 4581 | case IrInstructionIdSliceType: | 4654 | case IrInstructionIdSliceType: |
| 4582 | case IrInstructionIdCompileVar: | 4655 | case IrInstructionIdCompileVar: |
| | 4656 | case IrInstructionIdSizeOf: |
| 4583 | return false; | 4657 | return false; |
| 4584 | case IrInstructionIdAsm: | 4658 | case IrInstructionIdAsm: |
| 4585 | { | 4659 | { |
| ... | @@ -5248,24 +5322,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { | ... | @@ -5248,24 +5322,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) { |
| 5248 | // | 5322 | // |
| 5249 | // return builtin_fn->return_type; | 5323 | // return builtin_fn->return_type; |
| 5250 | // } | 5324 | // } |
| 5251 | // case BuiltinFnIdSizeof: | | |
| 5252 | // { | | |
| 5253 | // AstNode *type_node = node->data.fn_call_expr.params.at(0); | | |
| 5254 | // TypeTableEntry *type_entry = analyze_type_expr(g, import, context, type_node); | | |
| 5255 | // if (type_entry->id == TypeTableEntryIdInvalid) { | | |
| 5256 | // return g->builtin_types.entry_invalid; | | |
| 5257 | // } else if (type_entry->id == TypeTableEntryIdUnreachable) { | | |
| 5258 | // add_node_error(g, first_executing_node(type_node), | | |
| 5259 | // buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name))); | | |
| 5260 | // return g->builtin_types.entry_invalid; | | |
| 5261 | // } else { | | |
| 5262 | // uint64_t size_in_bytes = type_size(g, type_entry); | | |
| 5263 | // bool depends_on_compile_var = (type_entry == g->builtin_types.entry_usize || | | |
| 5264 | // type_entry == g->builtin_types.entry_isize); | | |
| 5265 | // return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type, | | |
| 5266 | // size_in_bytes, depends_on_compile_var); | | |
| 5267 | // } | | |
| 5268 | // } | | |
| 5269 | // case BuiltinFnIdAlignof: | 5325 | // case BuiltinFnIdAlignof: |
| 5270 | // { | 5326 | // { |
| 5271 | // AstNode *type_node = node->data.fn_call_expr.params.at(0); | 5327 | // AstNode *type_node = node->data.fn_call_expr.params.at(0); |
| ... | @@ -8044,7 +8100,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no | ... | @@ -8044,7 +8100,6 @@ static void analyze_goto_pass2(CodeGen *g, ImportTableEntry *import, AstNode *no |
| 8044 | // LLVMBuildCall(g->builder, builtin_fn->fn_val, params, 5, ""); | 8100 | // LLVMBuildCall(g->builder, builtin_fn->fn_val, params, 5, ""); |
| 8045 | // return nullptr; | 8101 | // return nullptr; |
| 8046 | // } | 8102 | // } |
| 8047 | // case BuiltinFnIdSizeof: | | |
| 8048 | // case BuiltinFnIdAlignof: | 8103 | // case BuiltinFnIdAlignof: |
| 8049 | // case BuiltinFnIdMinValue: | 8104 | // case BuiltinFnIdMinValue: |
| 8050 | // case BuiltinFnIdMaxValue: | 8105 | // case BuiltinFnIdMaxValue: |