Commit b47e2fa060
Changed files (4)
src/all_types.hpp
@@ -1452,6 +1452,7 @@ enum IrInstructionId {
IrInstructionIdSliceType,
IrInstructionIdAsm,
IrInstructionIdCompileVar,
+ IrInstructionIdSizeOf,
};
struct IrInstruction {
@@ -1742,6 +1743,12 @@ struct IrInstructionCompileVar {
IrInstruction *name;
};
+struct IrInstructionSizeOf {
+ IrInstruction base;
+
+ IrInstruction *type_value;
+};
+
enum LValPurpose {
LValPurposeNone,
LValPurposeAssign,
src/codegen.cpp
@@ -1444,6 +1444,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdArrayType:
case IrInstructionIdSliceType:
case IrInstructionIdCompileVar:
+ case IrInstructionIdSizeOf:
zig_unreachable();
case IrInstructionIdReturn:
return ir_render_return(g, executable, (IrInstructionReturn *)instruction);
src/ir.cpp
@@ -222,6 +222,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileVar *) {
return IrInstructionIdCompileVar;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionSizeOf *) {
+ return IrInstructionIdSizeOf;
+}
+
template<typename T>
static T *ir_create_instruction(IrExecutable *exec, AstNode *source_node) {
T *special_instruction = allocate<T>(1);
@@ -865,6 +869,15 @@ static IrInstruction *ir_build_compile_var(IrBuilder *irb, AstNode *source_node,
return &instruction->base;
}
+static IrInstruction *ir_build_size_of(IrBuilder *irb, AstNode *source_node, IrInstruction *type_value) {
+ IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, source_node);
+ instruction->type_value = type_value;
+
+ ir_ref_instruction(type_value);
+
+ return &instruction->base;
+}
+
static void ir_gen_defers_for_block(IrBuilder *irb, BlockContext *inner_block, BlockContext *outer_block,
bool gen_error_defers, bool gen_maybe_defers)
{
@@ -1356,9 +1369,17 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, AstNode *node) {
return ir_build_compile_var(irb, node, arg0_value);
}
+ case BuiltinFnIdSizeof:
+ {
+ AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
+ IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, node->block_context);
+ if (arg0_value == irb->codegen->invalid_instruction)
+ return arg0_value;
+
+ return ir_build_size_of(irb, node, arg0_value);
+ }
case BuiltinFnIdMemcpy:
case BuiltinFnIdMemset:
- case BuiltinFnIdSizeof:
case BuiltinFnIdAlignof:
case BuiltinFnIdMaxValue:
case BuiltinFnIdMinValue:
@@ -4417,6 +4438,56 @@ static TypeTableEntry *ir_analyze_instruction_compile_var(IrAnalyze *ira,
zig_unreachable();
}
+static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
+ IrInstructionSizeOf *size_of_instruction)
+{
+ IrInstruction *type_value = size_of_instruction->type_value->other;
+ TypeTableEntry *type_entry = ir_resolve_type(ira, type_value);
+ TypeTableEntry *canon_type_entry = get_underlying_type(type_entry);
+ switch (canon_type_entry->id) {
+ case TypeTableEntryIdInvalid:
+ return ira->codegen->builtin_types.entry_invalid;
+ case TypeTableEntryIdTypeDecl:
+ zig_unreachable();
+ case TypeTableEntryIdVar:
+ case TypeTableEntryIdUnreachable:
+ case TypeTableEntryIdUndefLit:
+ case TypeTableEntryIdNullLit:
+ case TypeTableEntryIdBlock:
+ case TypeTableEntryIdNumLitFloat:
+ case TypeTableEntryIdNumLitInt:
+ case TypeTableEntryIdGenericFn:
+ case TypeTableEntryIdMetaType:
+ case TypeTableEntryIdFn:
+ case TypeTableEntryIdNamespace:
+ add_node_error(ira->codegen, size_of_instruction->base.source_node,
+ buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));
+ // TODO if this is a typedecl, add error note showing the declaration of the type decl
+ return ira->codegen->builtin_types.entry_invalid;
+ case TypeTableEntryIdVoid:
+ case TypeTableEntryIdBool:
+ case TypeTableEntryIdInt:
+ case TypeTableEntryIdFloat:
+ case TypeTableEntryIdPointer:
+ case TypeTableEntryIdArray:
+ case TypeTableEntryIdStruct:
+ case TypeTableEntryIdMaybe:
+ case TypeTableEntryIdErrorUnion:
+ case TypeTableEntryIdPureError:
+ case TypeTableEntryIdEnum:
+ case TypeTableEntryIdUnion:
+ {
+ uint64_t size_in_bytes = type_size(ira->codegen, type_entry);
+ bool depends_on_compile_var = false; // TODO types should be able to depend on compile var
+ ConstExprValue *out_val = ir_build_const_from(ira, &size_of_instruction->base,
+ depends_on_compile_var);
+ bignum_init_unsigned(&out_val->data.x_bignum, size_in_bytes);
+ return ira->codegen->builtin_types.entry_num_lit_int;
+ }
+ }
+ zig_unreachable();
+}
+
static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
switch (instruction->id) {
case IrInstructionIdInvalid:
@@ -4471,6 +4542,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction);
case IrInstructionIdCompileVar:
return ir_analyze_instruction_compile_var(ira, (IrInstructionCompileVar *)instruction);
+ case IrInstructionIdSizeOf:
+ return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction);
case IrInstructionIdSwitchBr:
case IrInstructionIdCast:
case IrInstructionIdContainerInitList:
@@ -4580,6 +4653,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdArrayType:
case IrInstructionIdSliceType:
case IrInstructionIdCompileVar:
+ case IrInstructionIdSizeOf:
return false;
case IrInstructionIdAsm:
{
@@ -5248,24 +5322,6 @@ IrInstruction *ir_exec_const_result(IrExecutable *exec) {
//
// return builtin_fn->return_type;
// }
-// case BuiltinFnIdSizeof:
-// {
-// AstNode *type_node = node->data.fn_call_expr.params.at(0);
-// TypeTableEntry *type_entry = analyze_type_expr(g, import, context, type_node);
-// if (type_entry->id == TypeTableEntryIdInvalid) {
-// return g->builtin_types.entry_invalid;
-// } else if (type_entry->id == TypeTableEntryIdUnreachable) {
-// add_node_error(g, first_executing_node(type_node),
-// buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));
-// return g->builtin_types.entry_invalid;
-// } else {
-// uint64_t size_in_bytes = type_size(g, type_entry);
-// bool depends_on_compile_var = (type_entry == g->builtin_types.entry_usize ||
-// type_entry == g->builtin_types.entry_isize);
-// return resolve_expr_const_val_as_unsigned_num_lit(g, node, expected_type,
-// size_in_bytes, depends_on_compile_var);
-// }
-// }
// case BuiltinFnIdAlignof:
// {
// 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
// LLVMBuildCall(g->builder, builtin_fn->fn_val, params, 5, "");
// return nullptr;
// }
-// case BuiltinFnIdSizeof:
// case BuiltinFnIdAlignof:
// case BuiltinFnIdMinValue:
// case BuiltinFnIdMaxValue:
src/ir_print.cpp
@@ -36,7 +36,8 @@ static void ir_print_const_value(IrPrint *irp, TypeTableEntry *type_entry, Const
}
switch (type_entry->id) {
case TypeTableEntryIdInvalid:
- zig_unreachable();
+ fprintf(irp->f, "(invalid)");
+ break;
case TypeTableEntryIdVoid:
fprintf(irp->f, "{}");
break;
@@ -490,6 +491,12 @@ static void ir_print_compile_var(IrPrint *irp, IrInstructionCompileVar *instruct
fprintf(irp->f, ")");
}
+static void ir_print_size_of(IrPrint *irp, IrInstructionSizeOf *instruction) {
+ fprintf(irp->f, "@sizeOf(");
+ ir_print_other_instruction(irp, instruction->type_value);
+ fprintf(irp->f, ")");
+}
+
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
ir_print_prefix(irp, instruction);
switch (instruction->id) {
@@ -582,6 +589,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdCompileVar:
ir_print_compile_var(irp, (IrInstructionCompileVar *)instruction);
break;
+ case IrInstructionIdSizeOf:
+ ir_print_size_of(irp, (IrInstructionSizeOf *)instruction);
+ break;
case IrInstructionIdSwitchBr:
zig_panic("TODO print more IR instructions");
}