From 7eab62325b539be4aacb17fd64f5b4445c8409e7 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 24 Apr 2018 01:49:22 +0300 Subject: One step towards @typeInfo --- src/ir.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index cd00fc6230..69897f3b91 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -615,6 +615,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionOffsetOf *) { return IrInstructionIdOffsetOf; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { + return IrInstructionIdTypeInfo; +} + static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { return IrInstructionIdTypeId; } @@ -2440,6 +2444,16 @@ static IrInstruction *ir_build_offset_of(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } +static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *type_value) { + IrInstructionTypeInfo *instruction = ir_build_instruction(irb, scope, source_node); + instruction->type_value = type_value; + + ir_ref_instruction(type_value, irb->current_basic_block); + + return &instruction->base; +} + static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { @@ -4080,6 +4094,16 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo return ir_build_load_ptr(irb, scope, node, ptr_instruction); } + case BuiltinFnIdTypeInfo: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); + return ir_lval_wrap(irb, scope, type_info, lval); + } case BuiltinFnIdBreakpoint: return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval); case BuiltinFnIdReturnAddress: @@ -15669,6 +15693,26 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira, return ira->codegen->builtin_types.entry_num_lit_int; } +static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, + IrInstructionTypeInfo *instruction) +{ + IrInstruction *type_value = instruction->type_value->other; + TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); + if (type_is_invalid(type_entry)) + return ira->codegen->builtin_types.entry_invalid; + + ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeInfo"); + assert(var_value->type->id == TypeTableEntryIdMetaType); + TypeTableEntry *result_type = var_value->data.x_type; + + // TODO: Check if we need to explicitely make a &const TypeInfo here, I think we don't. + ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); + out_val->data.x_struct.fields = create_const_vals(1); + // TODO: Fill the struct + zig_panic("Building TypeInfo..."); + return result_type; +} + static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira, IrInstructionTypeId *instruction) { @@ -18555,6 +18599,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); case IrInstructionIdOffsetOf: return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction); + case IrInstructionIdTypeInfo: + return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); case IrInstructionIdTypeId: return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); case IrInstructionIdSetEvalBranchQuota: @@ -18821,6 +18867,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdTagName: case IrInstructionIdFieldParentPtr: case IrInstructionIdOffsetOf: + case IrInstructionIdTypeInfo: case IrInstructionIdTypeId: case IrInstructionIdAlignCast: case IrInstructionIdOpaqueType: -- cgit v1.2.3 From fb88f5a0d21f68632a8c712e14a9640f9c4f6cb3 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 24 Apr 2018 11:20:33 +0300 Subject: @typeInfo with void payloads now works! --- src/ir.cpp | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 69897f3b91..52136ec9c8 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15705,11 +15705,32 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, assert(var_value->type->id == TypeTableEntryIdMetaType); TypeTableEntry *result_type = var_value->data.x_type; - // TODO: Check if we need to explicitely make a &const TypeInfo here, I think we don't. ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - out_val->data.x_struct.fields = create_const_vals(1); - // TODO: Fill the struct - zig_panic("Building TypeInfo..."); + bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id)); + out_val->data.x_union.parent.id = ConstParentIdNone; + + switch (type_entry->id) { + case TypeTableEntryIdInvalid: + zig_unreachable(); + case TypeTableEntryIdMetaType: + case TypeTableEntryIdVoid: + case TypeTableEntryIdBool: + case TypeTableEntryIdUnreachable: + case TypeTableEntryIdNumLitFloat: + case TypeTableEntryIdNumLitInt: + case TypeTableEntryIdUndefLit: + case TypeTableEntryIdNullLit: + case TypeTableEntryIdNamespace: + case TypeTableEntryIdBlock: + case TypeTableEntryIdArgTuple: + case TypeTableEntryIdOpaque: + // TODO: Check out this is the way to handle voids; + out_val->data.x_union.payload = nullptr; + break; + default: + zig_panic("@typeInfo unsupported for %s", buf_ptr(&type_entry->name)); + } + return result_type; } -- cgit v1.2.3 From ec2a3ed500d4ba269c87b3ad0efe7bcc89eb2057 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 24 Apr 2018 15:03:46 +0300 Subject: Attempt at adding comptime union field access --- src/codegen.cpp | 1 + src/ir.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index ea2d9f463e..60a459f822 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6347,6 +6347,7 @@ static void define_builtin_compile_vars(CodeGen *g) { buf_appendf(contents, "};\n\n"); } { + // TODO: Add method info where methods are supported. buf_appendf(contents, "pub const IntInfo = struct {\n" " is_signed: bool,\n" diff --git a/src/ir.cpp b/src/ir.cpp index 52136ec9c8..2212efb101 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13473,6 +13473,41 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ } else if (bare_type->id == TypeTableEntryIdUnion) { TypeUnionField *field = find_union_type_field(bare_type, field_name); if (field) { + if (instr_is_comptime(container_ptr)) { + ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); + if (!ptr_val) + return ira->codegen->invalid_instruction; + + if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { + ConstExprValue *union_val = const_ptr_pointee(ira->codegen, ptr_val); + if (type_is_invalid(union_val->type)) + return ira->codegen->invalid_instruction; + + TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); + if (actual_field == nullptr) + zig_unreachable(); + + if (field != actual_field) { + ir_add_error_node(ira, source_instr->source_node, + buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), + buf_ptr(actual_field->name))); + return ira->codegen->invalid_instruction; + } + + ConstExprValue *payload_val = union_val->data.x_union.payload; + TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, payload_val->type, is_const, is_volatile, + get_abi_alignment(ira->codegen, payload_val->type), 0, 0); + + IrInstruction *result = ir_get_const(ira, source_instr); + ConstExprValue *const_val = &result->value; + const_val->data.x_ptr.special = ConstPtrSpecialRef; + const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; + const_val->data.x_ptr.data.ref.pointee = payload_val; + const_val->type = ptr_type; + return result; + } + } + IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, get_abi_alignment(ira->codegen, field->type_entry), 0, 0); @@ -15706,8 +15741,12 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, TypeTableEntry *result_type = var_value->data.x_type; ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); + // TODO: Do I need those? probably set in ir_build_const_from + //out_val->special = ConstValSpecialStatic; + //out_val->type = result_type; + bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id)); - out_val->data.x_union.parent.id = ConstParentIdNone; + //out_val->data.x_union.parent.id = ConstParentIdNone; switch (type_entry->id) { case TypeTableEntryIdInvalid: @@ -15724,9 +15763,34 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, case TypeTableEntryIdBlock: case TypeTableEntryIdArgTuple: case TypeTableEntryIdOpaque: - // TODO: Check out this is the way to handle voids; out_val->data.x_union.payload = nullptr; break; + case TypeTableEntryIdInt: + { + // Error from 'ir_resolve_const': "unable to evaluate constant expression" + ConstExprValue *payload = create_const_vals(1); + out_val->data.x_union.payload = payload; + + payload->special = ConstValSpecialStatic; + payload->type = get_builtin_value(ira->codegen, "IntInfo")->type; + + ConstExprValue *fields = create_const_vals(2); + payload->data.x_struct.fields = fields; + + payload->data.x_struct.parent.id = ConstParentIdUnion; + payload->data.x_struct.parent.data.p_union.union_val = out_val; + + // TODO: See what happens if we don't set the field type (set it to nullptr) + fields[0].special = ConstValSpecialStatic; + fields[0].type = ira->codegen->builtin_types.entry_bool; + fields[0].data.x_bool = type_entry->data.integral.is_signed; + + fields[1].special = ConstValSpecialStatic; + fields[1].type = ira->codegen->builtin_types.entry_u8; + bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); + + break; + } default: zig_panic("@typeInfo unsupported for %s", buf_ptr(&type_entry->name)); } -- cgit v1.2.3 From e9309d3b1310863d9571486b071b7a34bea1fb60 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 24 Apr 2018 15:17:34 +0300 Subject: Fixed IntInfo generation. --- src/ir.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 2212efb101..39e48ac33b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15772,7 +15772,10 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, out_val->data.x_union.payload = payload; payload->special = ConstValSpecialStatic; - payload->type = get_builtin_value(ira->codegen, "IntInfo")->type; + + ConstExprValue *int_info_type = get_builtin_value(ira->codegen, "IntInfo"); + assert(int_info_type->type->id == TypeTableEntryIdMetaType); + payload->type = int_info_type->data.x_type; ConstExprValue *fields = create_const_vals(2); payload->data.x_struct.fields = fields; -- cgit v1.2.3 From 0e5fb035e3d12879b4bd7a23578fdb8932deb4d1 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 24 Apr 2018 16:23:22 +0300 Subject: Added (broken) pointer info, float info --- src/ir.cpp | 155 +++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 125 insertions(+), 30 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 39e48ac33b..3ba9bc4772 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15728,27 +15728,13 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira, return ira->codegen->builtin_types.entry_num_lit_int; } -static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, - IrInstructionTypeInfo *instruction) +static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, TypeTableEntry *type_entry) { - IrInstruction *type_value = instruction->type_value->other; - TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); - if (type_is_invalid(type_entry)) - return ira->codegen->builtin_types.entry_invalid; + assert(type_entry != nullptr); + assert(!type_is_invalid(type_entry)); - ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeInfo"); - assert(var_value->type->id == TypeTableEntryIdMetaType); - TypeTableEntry *result_type = var_value->data.x_type; - - ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); - // TODO: Do I need those? probably set in ir_build_const_from - //out_val->special = ConstValSpecialStatic; - //out_val->type = result_type; - - bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id)); - //out_val->data.x_union.parent.id = ConstParentIdNone; - - switch (type_entry->id) { + switch (type_entry->id) + { case TypeTableEntryIdInvalid: zig_unreachable(); case TypeTableEntryIdMetaType: @@ -15763,14 +15749,11 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, case TypeTableEntryIdBlock: case TypeTableEntryIdArgTuple: case TypeTableEntryIdOpaque: - out_val->data.x_union.payload = nullptr; - break; + // TODO: Construct a valid void payload. + return nullptr; case TypeTableEntryIdInt: { - // Error from 'ir_resolve_const': "unable to evaluate constant expression" ConstExprValue *payload = create_const_vals(1); - out_val->data.x_union.payload = payload; - payload->special = ConstValSpecialStatic; ConstExprValue *int_info_type = get_builtin_value(ira->codegen, "IntInfo"); @@ -15780,23 +15763,135 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, ConstExprValue *fields = create_const_vals(2); payload->data.x_struct.fields = fields; - payload->data.x_struct.parent.id = ConstParentIdUnion; - payload->data.x_struct.parent.data.p_union.union_val = out_val; + if (parent->type->id == TypeTableEntryIdStruct) + { + payload->data.x_struct.parent.id = ConstParentIdStruct; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else if (parent->type->id == TypeTableEntryIdUnion) + { + payload->data.x_struct.parent.id = ConstParentIdUnion; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else + { + payload->data.x_struct.parent.id = ConstParentIdNone; + } - // TODO: See what happens if we don't set the field type (set it to nullptr) + // is_signed: bool fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_bool; fields[0].data.x_bool = type_entry->data.integral.is_signed; - + // bits: u8 fields[1].special = ConstValSpecialStatic; fields[1].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); - break; + return payload; + } + case TypeTableEntryIdFloat: + { + ConstExprValue *payload = create_const_vals(1); + payload->special = ConstValSpecialStatic; + + ConstExprValue *float_info_type = get_builtin_value(ira->codegen, "FloatInfo"); + assert(float_info_type->type->id == TypeTableEntryIdMetaType); + payload->type = float_info_type->data.x_type; + + ConstExprValue *fields = create_const_vals(1); + payload->data.x_struct.fields = fields; + + if (parent->type->id == TypeTableEntryIdStruct) + { + payload->data.x_struct.parent.id = ConstParentIdStruct; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else if (parent->type->id == TypeTableEntryIdUnion) + { + payload->data.x_struct.parent.id = ConstParentIdUnion; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else + { + payload->data.x_struct.parent.id = ConstParentIdNone; + } + // bits: u8 + fields[0].special = ConstValSpecialStatic; + fields[0].type = ira->codegen->builtin_types.entry_u8; + bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); + + return payload; + } + case TypeTableEntryIdPointer: + { + ConstExprValue *payload = create_const_vals(1); + payload->special = ConstValSpecialStatic; + + ConstExprValue *pointer_info_type = get_builtin_value(ira->codegen, "PointerInfo"); + assert(pointer_info_type->type->id == TypeTableEntryIdMetaType); + payload->type = pointer_info_type->data.x_type; + + ConstExprValue *fields = create_const_vals(4); + payload->data.x_struct.fields = fields; + + if (parent->type->id == TypeTableEntryIdStruct) + { + payload->data.x_struct.parent.id = ConstParentIdStruct; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else if (parent->type->id == TypeTableEntryIdUnion) + { + payload->data.x_struct.parent.id = ConstParentIdUnion; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else + { + payload->data.x_struct.parent.id = ConstParentIdNone; + } + // is_const: bool + fields[0].special = ConstValSpecialStatic; + fields[0].type = ira->codegen->builtin_types.entry_bool; + fields[0].data.x_bool = type_entry->data.pointer.is_const; + // is_volatile: bool + fields[1].special = ConstValSpecialStatic; + fields[1].type = ira->codegen->builtin_types.entry_bool; + fields[1].data.x_bool = type_entry->data.pointer.is_volatile; + // alignment: u32 + fields[2].special = ConstValSpecialStatic; + fields[2].type = ira->codegen->builtin_types.entry_u32; + bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.pointer.alignment); + // child: &TypeInfo + ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); + assert(type_info_type->type->id == TypeTableEntryIdMetaType); + fields[3].special = ConstValSpecialStatic; + fields[3].type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false); + fields[3].data.x_ptr.special = ConstPtrSpecialRef; + fields[3].data.x_ptr.mut = ConstPtrMutComptimeVar; + fields[3].data.x_ptr.data.ref.pointee = ir_make_type_info_value(ira, &fields[3], type_entry->data.pointer.child_type); + return payload; } default: - zig_panic("@typeInfo unsupported for %s", buf_ptr(&type_entry->name)); + zig_unreachable(); } +} + +static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, + IrInstructionTypeInfo *instruction) +{ + IrInstruction *type_value = instruction->type_value->other; + TypeTableEntry *type_entry = ir_resolve_type(ira, type_value); + if (type_is_invalid(type_entry)) + return ira->codegen->builtin_types.entry_invalid; + + ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeInfo"); + assert(var_value->type->id == TypeTableEntryIdMetaType); + TypeTableEntry *result_type = var_value->data.x_type; + + // TODO: We need to return a const pointer to the typeinfo, not the typeinfo by value. + ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); + out_val->type = result_type; + bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id)); + out_val->data.x_union.payload = ir_make_type_info_value(ira, out_val, type_entry); return result_type; } -- cgit v1.2.3 From 189e8e97bdd8dea8efa9ea30401b164ea619f2e4 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 24 Apr 2018 16:50:36 +0300 Subject: PointerInfo child is a pointer to a TypeInfo union, still not working correctly --- src/ir.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 3ba9bc4772..86c718da81 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15867,7 +15867,11 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p fields[3].type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false); fields[3].data.x_ptr.special = ConstPtrSpecialRef; fields[3].data.x_ptr.mut = ConstPtrMutComptimeVar; - fields[3].data.x_ptr.data.ref.pointee = ir_make_type_info_value(ira, &fields[3], type_entry->data.pointer.child_type); + ConstExprValue *union_val = create_const_vals(1); + union_val->type = type_info_type->data.x_type; + bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.pointer.child_type->id)); + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, type_entry->data.pointer.child_type); + fields[3].data.x_ptr.data.ref.pointee = union_val; return payload; } default: -- cgit v1.2.3 From 2d8553c85333734a1690dfae30d881103dde0727 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 24 Apr 2018 17:01:20 +0300 Subject: Fixed PointerInfo generation --- src/ir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 86c718da81..e1208f03ad 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15859,7 +15859,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p // alignment: u32 fields[2].special = ConstValSpecialStatic; fields[2].type = ira->codegen->builtin_types.entry_u32; - bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.pointer.alignment); + bigint_init_unsigned(&fields[2].data.x_bigint, type_entry->data.pointer.alignment); // child: &TypeInfo ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); assert(type_info_type->type->id == TypeTableEntryIdMetaType); -- cgit v1.2.3 From 09d7033d1db6ac0887aa21f87a2f96dad039f4e3 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 24 Apr 2018 17:08:45 +0300 Subject: PointerInfo child is known at comptime --- src/ir.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index e1208f03ad..be61b0c280 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15868,6 +15868,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p fields[3].data.x_ptr.special = ConstPtrSpecialRef; fields[3].data.x_ptr.mut = ConstPtrMutComptimeVar; ConstExprValue *union_val = create_const_vals(1); + union_val->special = ConstValSpecialStatic; union_val->type = type_info_type->data.x_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.pointer.child_type->id)); union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, type_entry->data.pointer.child_type); -- cgit v1.2.3 From 182a9fad2d55973ab50f4a2170edb88d6708681d Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 24 Apr 2018 17:38:30 +0300 Subject: Added ArrayInfo, NullableInfo, PromiseInfo generation --- src/codegen.cpp | 2 +- src/ir.cpp | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 60a459f822..2e7cc937b4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6366,7 +6366,7 @@ static void define_builtin_compile_vars(CodeGen *g) { "};\n" "\n" "pub const ArrayInfo = struct {\n" - " len: u64,\n" + " len: usize,\n" " child: &TypeInfo,\n" "};\n" "\n" diff --git a/src/ir.cpp b/src/ir.cpp index be61b0c280..a00d98efd1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15875,6 +15875,151 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p fields[3].data.x_ptr.data.ref.pointee = union_val; return payload; } + case TypeTableEntryIdArray: + { + ConstExprValue *payload = create_const_vals(1); + payload->special = ConstValSpecialStatic; + + ConstExprValue *pointer_info_type = get_builtin_value(ira->codegen, "ArrayInfo"); + assert(pointer_info_type->type->id == TypeTableEntryIdMetaType); + payload->type = pointer_info_type->data.x_type; + + ConstExprValue *fields = create_const_vals(2); + payload->data.x_struct.fields = fields; + + if (parent->type->id == TypeTableEntryIdStruct) + { + payload->data.x_struct.parent.id = ConstParentIdStruct; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else if (parent->type->id == TypeTableEntryIdUnion) + { + payload->data.x_struct.parent.id = ConstParentIdUnion; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else + { + payload->data.x_struct.parent.id = ConstParentIdNone; + } + // len: usize + fields[0].special = ConstValSpecialStatic; + fields[0].type = ira->codegen->builtin_types.entry_usize; + bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); + // child: &TypeInfo + ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); + assert(type_info_type->type->id == TypeTableEntryIdMetaType); + fields[1].special = ConstValSpecialStatic; + fields[1].type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false); + fields[1].data.x_ptr.special = ConstPtrSpecialRef; + fields[1].data.x_ptr.mut = ConstPtrMutComptimeVar; + ConstExprValue *union_val = create_const_vals(1); + union_val->special = ConstValSpecialStatic; + union_val->type = type_info_type->data.x_type; + bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.array.child_type->id)); + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, type_entry->data.array.child_type); + fields[1].data.x_ptr.data.ref.pointee = union_val; + return payload; + } + case TypeTableEntryIdMaybe: + { + ConstExprValue *payload = create_const_vals(1); + payload->special = ConstValSpecialStatic; + + ConstExprValue *pointer_info_type = get_builtin_value(ira->codegen, "NullableInfo"); + assert(pointer_info_type->type->id == TypeTableEntryIdMetaType); + payload->type = pointer_info_type->data.x_type; + + ConstExprValue *fields = create_const_vals(1); + payload->data.x_struct.fields = fields; + + if (parent->type->id == TypeTableEntryIdStruct) + { + payload->data.x_struct.parent.id = ConstParentIdStruct; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else if (parent->type->id == TypeTableEntryIdUnion) + { + payload->data.x_struct.parent.id = ConstParentIdUnion; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else + { + payload->data.x_struct.parent.id = ConstParentIdNone; + } + // child: &TypeInfo + ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); + assert(type_info_type->type->id == TypeTableEntryIdMetaType); + fields[0].special = ConstValSpecialStatic; + fields[0].type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false); + fields[0].data.x_ptr.special = ConstPtrSpecialRef; + fields[0].data.x_ptr.mut = ConstPtrMutComptimeVar; + ConstExprValue *union_val = create_const_vals(1); + union_val->special = ConstValSpecialStatic; + union_val->type = type_info_type->data.x_type; + bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.maybe.child_type->id)); + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, type_entry->data.maybe.child_type); + fields[0].data.x_ptr.data.ref.pointee = union_val; + return payload; + } + case TypeTableEntryIdPromise: + { + ConstExprValue *payload = create_const_vals(1); + payload->special = ConstValSpecialStatic; + + ConstExprValue *pointer_info_type = get_builtin_value(ira->codegen, "PromiseInfo"); + assert(pointer_info_type->type->id == TypeTableEntryIdMetaType); + payload->type = pointer_info_type->data.x_type; + + ConstExprValue *fields = create_const_vals(1); + payload->data.x_struct.fields = fields; + + if (parent->type->id == TypeTableEntryIdStruct) + { + payload->data.x_struct.parent.id = ConstParentIdStruct; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else if (parent->type->id == TypeTableEntryIdUnion) + { + payload->data.x_struct.parent.id = ConstParentIdUnion; + payload->data.x_struct.parent.data.p_union.union_val = parent; + } + else + { + payload->data.x_struct.parent.id = ConstParentIdNone; + } + // child: ?&TypeInfo + ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); + assert(type_info_type->type->id == TypeTableEntryIdMetaType); + + TypeTableEntry *type_info_ptr_type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false); + + fields[0].special = ConstValSpecialStatic; + fields[0].type = get_maybe_type(ira->codegen, type_info_ptr_type); + + if (type_entry->data.promise.result_type == nullptr) + { + fields[0].data.x_maybe = nullptr; + } + else + { + ConstExprValue *maybe_value = create_const_vals(1); + maybe_value->special = ConstValSpecialStatic; + maybe_value->type = type_info_ptr_type; + + maybe_value->data.x_ptr.special = ConstPtrSpecialRef; + maybe_value->data.x_ptr.mut = ConstPtrMutComptimeVar; + + ConstExprValue *union_val = create_const_vals(1); + union_val->special = ConstValSpecialStatic; + union_val->type = type_info_type->data.x_type; + bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.promise.result_type->id)); + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, type_entry->data.promise.result_type); + + maybe_value->data.x_ptr.data.ref.pointee = union_val; + fields[0].data.x_maybe = maybe_value; + } + return payload; + } default: zig_unreachable(); } -- cgit v1.2.3 From 778b931bf33c9b19502857af918fc159c0cd8e83 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Wed, 25 Apr 2018 02:50:18 +0300 Subject: Fixed comptime union void field access --- src/ir.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index a00d98efd1..aa456f5030 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13495,8 +13495,18 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ } ConstExprValue *payload_val = union_val->data.x_union.payload; - TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, payload_val->type, is_const, is_volatile, - get_abi_alignment(ira->codegen, payload_val->type), 0, 0); + + TypeTableEntry *field_type = field->type_entry; + if (field_type->id == TypeTableEntryIdVoid) + { + assert(payload_val == nullptr); + payload_val = create_const_vals(1); + payload_val->special = ConstValSpecialStatic; + payload_val->type = field_type; + } + + TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, is_const, is_volatile, + get_abi_alignment(ira->codegen, field_type), 0, 0); IrInstruction *result = ir_get_const(ira, source_instr); ConstExprValue *const_val = &result->value; @@ -15749,7 +15759,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p case TypeTableEntryIdBlock: case TypeTableEntryIdArgTuple: case TypeTableEntryIdOpaque: - // TODO: Construct a valid void payload. return nullptr; case TypeTableEntryIdInt: { -- cgit v1.2.3 From d68aea4f35fe935f3bf80c86dac4da7c4b88dc5b Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Wed, 25 Apr 2018 11:35:46 +0300 Subject: Added checks for field name/index mapping in TypeInfo generation. Abstracted the parent setting out. --- src/ir.cpp | 139 +++++++++++++++++++++++-------------------------------------- 1 file changed, 53 insertions(+), 86 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index aa456f5030..dee093c57e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -13411,7 +13411,6 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, return ira->codegen->invalid_instruction; } - static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, IrInstruction *source_instr, IrInstruction *container_ptr, TypeTableEntry *container_type) { @@ -15738,6 +15737,37 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira, return ira->codegen->builtin_types.entry_num_lit_int; } +static void ensure_field_index(TypeTableEntry *type, const char *field_name, size_t index) { + Buf *field_name_buf; + + assert(type != nullptr && !type_is_invalid(type)); + // Check for our field by creating a buffer in place then using the comma operator to free it so that we don't + // leak memory in debug mode. + assert(find_struct_type_field(type, field_name_buf = buf_create_from_str(field_name))->src_index == index && + (buf_deinit(field_name_buf), true)); +} + +static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExprValue *parent) { + assert(struct_val->type->id == TypeTableEntryIdStruct); + assert(parent->type != nullptr && !type_is_invalid(parent->type)); + + switch (parent->type->id) + { + case TypeTableEntryIdArray: + zig_panic("TODO - Only expected struct or union parent."); + case TypeTableEntryIdStruct: + struct_val->data.x_struct.parent.id = ConstParentIdStruct; + struct_val->data.x_struct.parent.data.p_union.union_val = parent; + break; + case TypeTableEntryIdUnion: + struct_val->data.x_struct.parent.id = ConstParentIdUnion; + struct_val->data.x_struct.parent.data.p_union.union_val = parent; + break; + default: + struct_val->data.x_struct.parent.id = ConstParentIdNone; + } +} + static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, TypeTableEntry *type_entry) { assert(type_entry != nullptr); @@ -15772,26 +15802,15 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(2); payload->data.x_struct.fields = fields; - if (parent->type->id == TypeTableEntryIdStruct) - { - payload->data.x_struct.parent.id = ConstParentIdStruct; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else if (parent->type->id == TypeTableEntryIdUnion) - { - payload->data.x_struct.parent.id = ConstParentIdUnion; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else - { - payload->data.x_struct.parent.id = ConstParentIdNone; - } + ir_type_info_struct_set_parent(payload, parent); // is_signed: bool + ensure_field_index(payload->type, "is_signed", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_bool; fields[0].data.x_bool = type_entry->data.integral.is_signed; // bits: u8 + ensure_field_index(payload->type, "bits", 1); fields[1].special = ConstValSpecialStatic; fields[1].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); @@ -15810,21 +15829,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(1); payload->data.x_struct.fields = fields; - if (parent->type->id == TypeTableEntryIdStruct) - { - payload->data.x_struct.parent.id = ConstParentIdStruct; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else if (parent->type->id == TypeTableEntryIdUnion) - { - payload->data.x_struct.parent.id = ConstParentIdUnion; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else - { - payload->data.x_struct.parent.id = ConstParentIdNone; - } + ir_type_info_struct_set_parent(payload, parent); + // bits: u8 + ensure_field_index(payload->type, "bits", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); @@ -15843,33 +15851,25 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(4); payload->data.x_struct.fields = fields; - if (parent->type->id == TypeTableEntryIdStruct) - { - payload->data.x_struct.parent.id = ConstParentIdStruct; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else if (parent->type->id == TypeTableEntryIdUnion) - { - payload->data.x_struct.parent.id = ConstParentIdUnion; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else - { - payload->data.x_struct.parent.id = ConstParentIdNone; - } + ir_type_info_struct_set_parent(payload, parent); + // is_const: bool + ensure_field_index(payload->type, "is_const", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_bool; fields[0].data.x_bool = type_entry->data.pointer.is_const; // is_volatile: bool + ensure_field_index(payload->type, "is_volatile", 1); fields[1].special = ConstValSpecialStatic; fields[1].type = ira->codegen->builtin_types.entry_bool; fields[1].data.x_bool = type_entry->data.pointer.is_volatile; // alignment: u32 + ensure_field_index(payload->type, "alignment", 2); fields[2].special = ConstValSpecialStatic; fields[2].type = ira->codegen->builtin_types.entry_u32; bigint_init_unsigned(&fields[2].data.x_bigint, type_entry->data.pointer.alignment); // child: &TypeInfo + ensure_field_index(payload->type, "child", 3); ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); assert(type_info_type->type->id == TypeTableEntryIdMetaType); fields[3].special = ConstValSpecialStatic; @@ -15896,25 +15896,15 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(2); payload->data.x_struct.fields = fields; - if (parent->type->id == TypeTableEntryIdStruct) - { - payload->data.x_struct.parent.id = ConstParentIdStruct; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else if (parent->type->id == TypeTableEntryIdUnion) - { - payload->data.x_struct.parent.id = ConstParentIdUnion; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else - { - payload->data.x_struct.parent.id = ConstParentIdNone; - } + ir_type_info_struct_set_parent(payload, parent); + // len: usize + ensure_field_index(payload->type, "len", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_usize; bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); // child: &TypeInfo + ensure_field_index(payload->type, "child", 1); ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); assert(type_info_type->type->id == TypeTableEntryIdMetaType); fields[1].special = ConstValSpecialStatic; @@ -15941,21 +15931,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(1); payload->data.x_struct.fields = fields; - if (parent->type->id == TypeTableEntryIdStruct) - { - payload->data.x_struct.parent.id = ConstParentIdStruct; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else if (parent->type->id == TypeTableEntryIdUnion) - { - payload->data.x_struct.parent.id = ConstParentIdUnion; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else - { - payload->data.x_struct.parent.id = ConstParentIdNone; - } + ir_type_info_struct_set_parent(payload, parent); + // child: &TypeInfo + ensure_field_index(payload->type, "child", 0); ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); assert(type_info_type->type->id == TypeTableEntryIdMetaType); fields[0].special = ConstValSpecialStatic; @@ -15982,21 +15961,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(1); payload->data.x_struct.fields = fields; - if (parent->type->id == TypeTableEntryIdStruct) - { - payload->data.x_struct.parent.id = ConstParentIdStruct; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else if (parent->type->id == TypeTableEntryIdUnion) - { - payload->data.x_struct.parent.id = ConstParentIdUnion; - payload->data.x_struct.parent.data.p_union.union_val = parent; - } - else - { - payload->data.x_struct.parent.id = ConstParentIdNone; - } + ir_type_info_struct_set_parent(payload, parent); + // child: ?&TypeInfo + ensure_field_index(payload->type, "child", 0); ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); assert(type_info_type->type->id == TypeTableEntryIdMetaType); @@ -16046,7 +16014,6 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, assert(var_value->type->id == TypeTableEntryIdMetaType); TypeTableEntry *result_type = var_value->data.x_type; - // TODO: We need to return a const pointer to the typeinfo, not the typeinfo by value. ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); out_val->type = result_type; bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id)); -- cgit v1.2.3 From 2606993cb48e69015a9152b860e48fca29d330e1 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Wed, 25 Apr 2018 11:59:35 +0300 Subject: Fixed ir_type_info_struct_set_parent for struct parents. --- src/ir.cpp | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index dee093c57e..a68747fce4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15747,7 +15747,7 @@ static void ensure_field_index(TypeTableEntry *type, const char *field_name, siz (buf_deinit(field_name_buf), true)); } -static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExprValue *parent) { +static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExprValue *parent, ssize_t parent_field_index) { assert(struct_val->type->id == TypeTableEntryIdStruct); assert(parent->type != nullptr && !type_is_invalid(parent->type)); @@ -15756,10 +15756,13 @@ static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExpr case TypeTableEntryIdArray: zig_panic("TODO - Only expected struct or union parent."); case TypeTableEntryIdStruct: + assert(parent_field_index >= 0); struct_val->data.x_struct.parent.id = ConstParentIdStruct; - struct_val->data.x_struct.parent.data.p_union.union_val = parent; + struct_val->data.x_struct.parent.data.p_struct.struct_val = parent; + struct_val->data.x_struct.parent.data.p_struct.field_index = parent_field_index; break; case TypeTableEntryIdUnion: + assert(parent_field_index == -1); struct_val->data.x_struct.parent.id = ConstParentIdUnion; struct_val->data.x_struct.parent.data.p_union.union_val = parent; break; @@ -15768,7 +15771,8 @@ static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExpr } } -static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, TypeTableEntry *type_entry) +static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, + ssize_t parent_field_index, TypeTableEntry *type_entry) { assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); @@ -15802,7 +15806,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(2); payload->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent); + ir_type_info_struct_set_parent(payload, parent, parent_field_index); // is_signed: bool ensure_field_index(payload->type, "is_signed", 0); @@ -15829,7 +15833,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(1); payload->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent); + ir_type_info_struct_set_parent(payload, parent, parent_field_index); // bits: u8 ensure_field_index(payload->type, "bits", 0); @@ -15851,7 +15855,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(4); payload->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent); + ir_type_info_struct_set_parent(payload, parent, parent_field_index); // is_const: bool ensure_field_index(payload->type, "is_const", 0); @@ -15880,7 +15884,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p union_val->special = ConstValSpecialStatic; union_val->type = type_info_type->data.x_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.pointer.child_type->id)); - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, type_entry->data.pointer.child_type); + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, type_entry->data.pointer.child_type); fields[3].data.x_ptr.data.ref.pointee = union_val; return payload; } @@ -15896,7 +15900,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(2); payload->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent); + ir_type_info_struct_set_parent(payload, parent, parent_field_index); // len: usize ensure_field_index(payload->type, "len", 0); @@ -15915,7 +15919,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p union_val->special = ConstValSpecialStatic; union_val->type = type_info_type->data.x_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.array.child_type->id)); - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, type_entry->data.array.child_type); + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, type_entry->data.array.child_type); fields[1].data.x_ptr.data.ref.pointee = union_val; return payload; } @@ -15931,7 +15935,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(1); payload->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent); + ir_type_info_struct_set_parent(payload, parent, parent_field_index); // child: &TypeInfo ensure_field_index(payload->type, "child", 0); @@ -15945,7 +15949,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p union_val->special = ConstValSpecialStatic; union_val->type = type_info_type->data.x_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.maybe.child_type->id)); - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, type_entry->data.maybe.child_type); + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, type_entry->data.maybe.child_type); fields[0].data.x_ptr.data.ref.pointee = union_val; return payload; } @@ -15961,7 +15965,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *fields = create_const_vals(1); payload->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent); + ir_type_info_struct_set_parent(payload, parent, parent_field_index); // child: ?&TypeInfo ensure_field_index(payload->type, "child", 0); @@ -15990,7 +15994,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p union_val->special = ConstValSpecialStatic; union_val->type = type_info_type->data.x_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.promise.result_type->id)); - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, type_entry->data.promise.result_type); + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, type_entry->data.promise.result_type); maybe_value->data.x_ptr.data.ref.pointee = union_val; fields[0].data.x_maybe = maybe_value; @@ -16017,7 +16021,7 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); out_val->type = result_type; bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id)); - out_val->data.x_union.payload = ir_make_type_info_value(ira, out_val, type_entry); + out_val->data.x_union.payload = ir_make_type_info_value(ira, out_val, -1, type_entry); return result_type; } -- cgit v1.2.3 From bc160821d33a9284cf8bb85cca6cbf161af71d3b Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Wed, 25 Apr 2018 17:50:11 +0300 Subject: Changed TypeInfo layout. --- src/codegen.cpp | 236 ++++++++++++++++++++++++++++---------------------------- src/ir.cpp | 89 +++++++++++++-------- 2 files changed, 174 insertions(+), 151 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 2e7cc937b4..7d83a38bbf 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6349,143 +6349,143 @@ static void define_builtin_compile_vars(CodeGen *g) { { // TODO: Add method info where methods are supported. buf_appendf(contents, - "pub const IntInfo = struct {\n" - " is_signed: bool,\n" - " bits: u8,\n" - "};\n" - "\n" - "pub const FloatInfo = struct {\n" - " bits: u8,\n" - "};\n" + "pub const TypeInfo = union(TypeId) {\n" + " Type: void,\n" + " Void: void,\n" + " Bool: void,\n" + " NoReturn: void,\n" + " Int: Int,\n" + " Float: Float,\n" + " Pointer: Pointer,\n" + " Array: Array,\n" + " Struct: Struct,\n" + " FloatLiteral: void,\n" + " IntLiteral: void,\n" + " UndefinedLiteral: void,\n" + " NullLiteral: void,\n" + " Nullable: Nullable,\n" + " ErrorUnion: ErrorUnion,\n" + " ErrorSet: ErrorSet,\n" + " Enum: Enum,\n" + " Union: Union,\n" + " Fn: Fn,\n" + " Namespace: void,\n" + " Block: void,\n" + " BoundFn: BoundFn,\n" + " ArgTuple: void,\n" + " Opaque: void,\n" + " Promise: Promise,\n" + "\n\n" + " pub const Int = struct {\n" + " is_signed: bool,\n" + " bits: u8,\n" + " };\n" "\n" - "pub const PointerInfo = struct {\n" - " is_const: bool,\n" - " is_volatile: bool,\n" - " alignment: u32,\n" - " child: &TypeInfo,\n" - "};\n" + " pub const Float = struct {\n" + " bits: u8,\n" + " };\n" "\n" - "pub const ArrayInfo = struct {\n" - " len: usize,\n" - " child: &TypeInfo,\n" - "};\n" + " pub const Pointer = struct {\n" + " is_const: bool,\n" + " is_volatile: bool,\n" + " alignment: u32,\n" + " child: &TypeInfo,\n" + " };\n" "\n" - "pub const ContainerLayout = enum {\n" - " Auto,\n" - " Extern,\n" - " Packed,\n" - "};\n" + " pub const Array = struct {\n" + " len: usize,\n" + " child: &TypeInfo,\n" + " };\n" "\n" - "pub const StructFieldInfo = struct {\n" - " name: []const u8,\n" - " offset: usize,\n" - " type_info: TypeInfo,\n" - "};\n" + " pub const ContainerLayout = enum {\n" + " Auto,\n" + " Extern,\n" + " Packed,\n" + " };\n" "\n" - "pub const StructInfo = struct {\n" - " layout: ContainerLayout,\n" - " fields: []StructFieldInfo,\n" - "};\n" + " pub const StructField = struct {\n" + " name: []const u8,\n" + " offset: usize,\n" + " type_info: TypeInfo,\n" + " };\n" "\n" - "pub const NullableInfo = struct {\n" - " child: &TypeInfo,\n" - "};\n" + " pub const Struct = struct {\n" + " layout: ContainerLayout,\n" + " fields: []StructField,\n" + " };\n" "\n" - "pub const ErrorUnionInfo = struct {\n" - " error_set: ErrorSetInfo,\n" - " payload: &TypeInfo,\n" - "};\n" + " pub const Nullable = struct {\n" + " child: &TypeInfo,\n" + " };\n" "\n" - "pub const ErrorInfo = struct {\n" - " name: []const u8,\n" - " value: usize,\n" - "};\n" + " pub const ErrorUnion = struct {\n" + " error_set: ErrorSet,\n" + " payload: &TypeInfo,\n" + " };\n" "\n" - "pub const ErrorSetInfo = struct {\n" - " errors: []ErrorInfo,\n" - "};\n" + " pub const Error = struct {\n" + " name: []const u8,\n" + " value: usize,\n" + " };\n" "\n" - "pub const EnumFieldInfo = struct {\n" - " name: []const u8,\n" - " value: usize,\n" - "};\n" + " pub const ErrorSet = struct {\n" + " errors: []Error,\n" + " };\n" "\n" - "pub const EnumInfo = struct {\n" - " layout: ContainerLayout,\n" - " tag_type: IntInfo,\n" - " fields: []EnumFieldInfo,\n" - "};\n" + " pub const EnumField = struct {\n" + " name: []const u8,\n" + " value: usize,\n" + " };\n" "\n" - "pub const UnionFieldInfo = struct {\n" - " name: []const u8,\n" - " enum_field: EnumFieldInfo,\n" - " type_info: TypeInfo,\n" - "};\n" + " pub const Enum = struct {\n" + " layout: ContainerLayout,\n" + " tag_type: Int,\n" + " fields: []EnumField,\n" + " };\n" "\n" - "pub const UnionInfo = struct {\n" - " layout: ContainerLayout,\n" - " tag_type: ?EnumInfo,\n" - " fields: []UnionFieldInfo,\n" - "};\n" + " pub const UnionField = struct {\n" + " name: []const u8,\n" + " enum_field: EnumField,\n" + " type_info: TypeInfo,\n" + " };\n" "\n" - "pub const CallingConvention = enum {\n" - " Unspecified,\n" - " C,\n" - " Cold,\n" - " Naked,\n" - " Stdcall,\n" - " Async,\n" - "};\n" + " pub const Union = struct {\n" + " layout: ContainerLayout,\n" + " tag_type: ?Enum,\n" + " fields: []UnionField,\n" + " };\n" "\n" - "pub const FnArgInfo = struct {\n" - " is_comptime: bool,\n" - " name: []const u8,\n" - " type_info: TypeInfo,\n" - "};\n" + " pub const CallingConvention = enum {\n" + " Unspecified,\n" + " C,\n" + " Cold,\n" + " Naked,\n" + " Stdcall,\n" + " Async,\n" + " };\n" "\n" - "pub const FnInfo = struct {\n" - " calling_convention: CallingConvention,\n" - " is_generic: bool,\n" - " is_varargs: bool,\n" - " return_type: &TypeInfo,\n" - " args: []FnArgInfo,\n" - "};\n" + " pub const FnArg = struct {\n" + " is_comptime: bool,\n" + " name: []const u8,\n" + " type_info: TypeInfo,\n" + " };\n" "\n" - "pub const BoundFnInfo = struct {\n" - " bound_type: &TypeInfo,\n" - " fn_info: FnInfo,\n" - "};\n" + " pub const Fn = struct {\n" + " calling_convention: CallingConvention,\n" + " is_generic: bool,\n" + " is_varargs: bool,\n" + " return_type: &TypeInfo,\n" + " args: []FnArg,\n" + " };\n" "\n" - "pub const PromiseInfo = struct {\n" - " child: ?&TypeInfo,\n" - "};\n" + " pub const BoundFn = struct {\n" + " bound_type: &TypeInfo,\n" + " fn_info: Fn,\n" + " };\n" "\n" - "pub const TypeInfo = union(TypeId) {\n" - " Type: void,\n" - " Void: void,\n" - " Bool: void,\n" - " NoReturn: void,\n" - " Int: IntInfo,\n" - " Float: FloatInfo,\n" - " Pointer: PointerInfo,\n" - " Array: ArrayInfo,\n" - " Struct: StructInfo,\n" - " FloatLiteral: void,\n" - " IntLiteral: void,\n" - " UndefinedLiteral: void,\n" - " NullLiteral: void,\n" - " Nullable: NullableInfo,\n" - " ErrorUnion: ErrorUnionInfo,\n" - " ErrorSet: ErrorSetInfo,\n" - " Enum: EnumInfo,\n" - " Union: UnionInfo,\n" - " Fn: FnInfo,\n" - " Namespace: void,\n" - " Block: void,\n" - " BoundFn: BoundFnInfo,\n" - " ArgTuple: void,\n" - " Opaque: void,\n" - " Promise: PromiseInfo,\n" + " pub const Promise = struct {\n" + " child: ?&TypeInfo,\n" + " };\n" "};\n\n"); assert(ContainerLayoutAuto == 0); assert(ContainerLayoutExtern == 1); diff --git a/src/ir.cpp b/src/ir.cpp index a68747fce4..1f2ef0e68f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15737,7 +15737,8 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira, return ira->codegen->builtin_types.entry_num_lit_int; } -static void ensure_field_index(TypeTableEntry *type, const char *field_name, size_t index) { +static void ensure_field_index(TypeTableEntry *type, const char *field_name, size_t index) +{ Buf *field_name_buf; assert(type != nullptr && !type_is_invalid(type)); @@ -15747,7 +15748,8 @@ static void ensure_field_index(TypeTableEntry *type, const char *field_name, siz (buf_deinit(field_name_buf), true)); } -static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExprValue *parent, ssize_t parent_field_index) { +static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExprValue *parent, ssize_t parent_field_index) +{ assert(struct_val->type->id == TypeTableEntryIdStruct); assert(parent->type != nullptr && !type_is_invalid(parent->type)); @@ -15771,6 +15773,37 @@ static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExpr } } +static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_name) +{ + ConstExprValue *type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); + assert(type_info_var->type->id == TypeTableEntryIdMetaType); + + TypeTableEntry *type_info_type = type_info_var->data.x_type; + assert(type_info_type->id == TypeTableEntryIdUnion); + + if (type_name == nullptr) + return type_info_type; + + // @TODO + + ScopeDecls *type_info_scope = get_container_scope(type_info_type); + assert(type_info_scope != nullptr); + + Buf field_name = BUF_INIT; + buf_init_from_str(&field_name, type_name); + auto entry = type_info_scope->decl_table.maybe_get(&field_name); + buf_deinit(&field_name); + assert(entry != nullptr); + + TldVar *tld = (TldVar *)entry->value; + assert(tld->base.id == TldIdVar); + + VariableTableEntry *var = tld->var; + + assert(var->value->type->id == TypeTableEntryIdMetaType); + return var->value->data.x_type; +} + static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, ssize_t parent_field_index, TypeTableEntry *type_entry) { @@ -15798,10 +15831,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p { ConstExprValue *payload = create_const_vals(1); payload->special = ConstValSpecialStatic; - - ConstExprValue *int_info_type = get_builtin_value(ira->codegen, "IntInfo"); - assert(int_info_type->type->id == TypeTableEntryIdMetaType); - payload->type = int_info_type->data.x_type; + payload->type = ir_type_info_get_type(ira, "Int"); ConstExprValue *fields = create_const_vals(2); payload->data.x_struct.fields = fields; @@ -15825,10 +15855,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p { ConstExprValue *payload = create_const_vals(1); payload->special = ConstValSpecialStatic; - - ConstExprValue *float_info_type = get_builtin_value(ira->codegen, "FloatInfo"); - assert(float_info_type->type->id == TypeTableEntryIdMetaType); - payload->type = float_info_type->data.x_type; + payload->type = ir_type_info_get_type(ira, "Float"); ConstExprValue *fields = create_const_vals(1); payload->data.x_struct.fields = fields; @@ -15847,10 +15874,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p { ConstExprValue *payload = create_const_vals(1); payload->special = ConstValSpecialStatic; - - ConstExprValue *pointer_info_type = get_builtin_value(ira->codegen, "PointerInfo"); - assert(pointer_info_type->type->id == TypeTableEntryIdMetaType); - payload->type = pointer_info_type->data.x_type; + payload->type = ir_type_info_get_type(ira, "Pointer"); ConstExprValue *fields = create_const_vals(4); payload->data.x_struct.fields = fields; @@ -15884,7 +15908,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p union_val->special = ConstValSpecialStatic; union_val->type = type_info_type->data.x_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.pointer.child_type->id)); - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, type_entry->data.pointer.child_type); + + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, + type_entry->data.pointer.child_type); + fields[3].data.x_ptr.data.ref.pointee = union_val; return payload; } @@ -15892,10 +15919,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p { ConstExprValue *payload = create_const_vals(1); payload->special = ConstValSpecialStatic; - - ConstExprValue *pointer_info_type = get_builtin_value(ira->codegen, "ArrayInfo"); - assert(pointer_info_type->type->id == TypeTableEntryIdMetaType); - payload->type = pointer_info_type->data.x_type; + payload->type = ir_type_info_get_type(ira, "Array"); ConstExprValue *fields = create_const_vals(2); payload->data.x_struct.fields = fields; @@ -15919,7 +15943,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p union_val->special = ConstValSpecialStatic; union_val->type = type_info_type->data.x_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.array.child_type->id)); - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, type_entry->data.array.child_type); + + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, + type_entry->data.array.child_type); + fields[1].data.x_ptr.data.ref.pointee = union_val; return payload; } @@ -15927,10 +15954,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p { ConstExprValue *payload = create_const_vals(1); payload->special = ConstValSpecialStatic; - - ConstExprValue *pointer_info_type = get_builtin_value(ira->codegen, "NullableInfo"); - assert(pointer_info_type->type->id == TypeTableEntryIdMetaType); - payload->type = pointer_info_type->data.x_type; + payload->type = ir_type_info_get_type(ira, "Nullable"); ConstExprValue *fields = create_const_vals(1); payload->data.x_struct.fields = fields; @@ -15949,7 +15973,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p union_val->special = ConstValSpecialStatic; union_val->type = type_info_type->data.x_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.maybe.child_type->id)); - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, type_entry->data.maybe.child_type); + + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, + type_entry->data.maybe.child_type); + fields[0].data.x_ptr.data.ref.pointee = union_val; return payload; } @@ -15957,10 +15984,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p { ConstExprValue *payload = create_const_vals(1); payload->special = ConstValSpecialStatic; - - ConstExprValue *pointer_info_type = get_builtin_value(ira->codegen, "PromiseInfo"); - assert(pointer_info_type->type->id == TypeTableEntryIdMetaType); - payload->type = pointer_info_type->data.x_type; + payload->type = ir_type_info_get_type(ira, "Promise"); ConstExprValue *fields = create_const_vals(1); payload->data.x_struct.fields = fields; @@ -15994,7 +16018,8 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p union_val->special = ConstValSpecialStatic; union_val->type = type_info_type->data.x_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.promise.result_type->id)); - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, type_entry->data.promise.result_type); + union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, + type_entry->data.promise.result_type); maybe_value->data.x_ptr.data.ref.pointee = union_val; fields[0].data.x_maybe = maybe_value; @@ -16014,9 +16039,7 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, if (type_is_invalid(type_entry)) return ira->codegen->builtin_types.entry_invalid; - ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeInfo"); - assert(var_value->type->id == TypeTableEntryIdMetaType); - TypeTableEntry *result_type = var_value->data.x_type; + TypeTableEntry *result_type = ir_type_info_get_type(ira, nullptr); ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); out_val->type = result_type; -- cgit v1.2.3 From dd88d7deda66a4e4e1527831e7b24a3cf358d1b7 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Thu, 26 Apr 2018 13:27:16 +0300 Subject: Cleanup --- src/ir.cpp | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 1f2ef0e68f..cbd8d51b32 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15775,17 +15775,20 @@ static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExpr static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_name) { - ConstExprValue *type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); - assert(type_info_var->type->id == TypeTableEntryIdMetaType); + static ConstExprValue *type_info_var = nullptr; + static TypeTableEntry *type_info_type = nullptr; + if (type_info_var == nullptr) + { + type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); + assert(type_info_var->type->id == TypeTableEntryIdMetaType); - TypeTableEntry *type_info_type = type_info_var->data.x_type; - assert(type_info_type->id == TypeTableEntryIdUnion); + type_info_type = type_info_var->data.x_type; + assert(type_info_type->id == TypeTableEntryIdUnion); + } if (type_name == nullptr) return type_info_type; - // @TODO - ScopeDecls *type_info_scope = get_container_scope(type_info_type); assert(type_info_scope != nullptr); @@ -15898,15 +15901,16 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p bigint_init_unsigned(&fields[2].data.x_bigint, type_entry->data.pointer.alignment); // child: &TypeInfo ensure_field_index(payload->type, "child", 3); - ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); - assert(type_info_type->type->id == TypeTableEntryIdMetaType); + + TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); + fields[3].special = ConstValSpecialStatic; - fields[3].type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false); + fields[3].type = get_pointer_to_type(ira->codegen, type_info_type, false); fields[3].data.x_ptr.special = ConstPtrSpecialRef; fields[3].data.x_ptr.mut = ConstPtrMutComptimeVar; ConstExprValue *union_val = create_const_vals(1); union_val->special = ConstValSpecialStatic; - union_val->type = type_info_type->data.x_type; + union_val->type = type_info_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.pointer.child_type->id)); union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, @@ -15933,15 +15937,16 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); // child: &TypeInfo ensure_field_index(payload->type, "child", 1); - ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); - assert(type_info_type->type->id == TypeTableEntryIdMetaType); + + TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); + fields[1].special = ConstValSpecialStatic; - fields[1].type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false); + fields[1].type = get_pointer_to_type(ira->codegen, type_info_type, false); fields[1].data.x_ptr.special = ConstPtrSpecialRef; fields[1].data.x_ptr.mut = ConstPtrMutComptimeVar; ConstExprValue *union_val = create_const_vals(1); union_val->special = ConstValSpecialStatic; - union_val->type = type_info_type->data.x_type; + union_val->type = type_info_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.array.child_type->id)); union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, @@ -15963,15 +15968,16 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p // child: &TypeInfo ensure_field_index(payload->type, "child", 0); - ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); - assert(type_info_type->type->id == TypeTableEntryIdMetaType); + + TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); + fields[0].special = ConstValSpecialStatic; - fields[0].type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false); + fields[0].type = get_pointer_to_type(ira->codegen, type_info_type, false); fields[0].data.x_ptr.special = ConstPtrSpecialRef; fields[0].data.x_ptr.mut = ConstPtrMutComptimeVar; ConstExprValue *union_val = create_const_vals(1); union_val->special = ConstValSpecialStatic; - union_val->type = type_info_type->data.x_type; + union_val->type = type_info_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.maybe.child_type->id)); union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, @@ -15993,10 +15999,9 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p // child: ?&TypeInfo ensure_field_index(payload->type, "child", 0); - ConstExprValue *type_info_type = get_builtin_value(ira->codegen, "TypeInfo"); - assert(type_info_type->type->id == TypeTableEntryIdMetaType); - TypeTableEntry *type_info_ptr_type = get_pointer_to_type(ira->codegen, type_info_type->data.x_type, false); + TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); + TypeTableEntry *type_info_ptr_type = get_pointer_to_type(ira->codegen, type_info_type, false); fields[0].special = ConstValSpecialStatic; fields[0].type = get_maybe_type(ira->codegen, type_info_ptr_type); @@ -16016,7 +16021,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p ConstExprValue *union_val = create_const_vals(1); union_val->special = ConstValSpecialStatic; - union_val->type = type_info_type->data.x_type; + union_val->type = type_info_type; bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.promise.result_type->id)); union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, type_entry->data.promise.result_type); -- cgit v1.2.3 From bb56360bfaa317809bd3c742a655b357bd5b6226 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Thu, 26 Apr 2018 14:03:19 +0300 Subject: Added TypeInfo cache --- src/all_types.hpp | 1 + src/codegen.cpp | 10 ++++- src/ir.cpp | 109 ++++++++++++++++++++++++++++++------------------------ 3 files changed, 70 insertions(+), 50 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index 332fc5204e..c1c6c9a1a5 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1507,6 +1507,7 @@ struct CodeGen { HashMap exported_symbol_names; HashMap external_prototypes; HashMap string_literals_table; + HashMap type_info_cache; ZigList import_queue; diff --git a/src/codegen.cpp b/src/codegen.cpp index 7d83a38bbf..71df7fcd65 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -88,6 +88,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out g->exported_symbol_names.init(8); g->external_prototypes.init(8); g->string_literals_table.init(16); + g->type_info_cache.init(32); g->is_test_build = false; g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib); buf_resize(&g->global_asm, 0); @@ -6347,7 +6348,8 @@ static void define_builtin_compile_vars(CodeGen *g) { buf_appendf(contents, "};\n\n"); } { - // TODO: Add method info where methods are supported. + // @TODO Add method info where methods are supported. + // @TODO Add Namespace info. buf_appendf(contents, "pub const TypeInfo = union(TypeId) {\n" " Type: void,\n" @@ -6403,6 +6405,11 @@ static void define_builtin_compile_vars(CodeGen *g) { " Packed,\n" " };\n" "\n" + " pub const Method = struct {\n" + " name: []const u8,\n" + " fn_info: Fn,\n" + " };\n" + "\n" " pub const StructField = struct {\n" " name: []const u8,\n" " offset: usize,\n" @@ -6412,6 +6419,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const Struct = struct {\n" " layout: ContainerLayout,\n" " fields: []StructField,\n" + " methods: []Method,\n" " };\n" "\n" " pub const Nullable = struct {\n" diff --git a/src/ir.cpp b/src/ir.cpp index cbd8d51b32..9229e4e89d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15810,6 +15810,15 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, ssize_t parent_field_index, TypeTableEntry *type_entry) { + // Lookup an available value in our cache. + auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); + if (entry != nullptr) + return entry->value; + + ConstExprValue *result = nullptr; + + // @TODO + // We should probably cache the values generated with a type_entry key. assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); @@ -15832,75 +15841,73 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p return nullptr; case TypeTableEntryIdInt: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Int"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Int"); ConstExprValue *fields = create_const_vals(2); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // is_signed: bool - ensure_field_index(payload->type, "is_signed", 0); + ensure_field_index(result->type, "is_signed", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_bool; fields[0].data.x_bool = type_entry->data.integral.is_signed; // bits: u8 - ensure_field_index(payload->type, "bits", 1); + ensure_field_index(result->type, "bits", 1); fields[1].special = ConstValSpecialStatic; fields[1].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); - - return payload; + break; } case TypeTableEntryIdFloat: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Float"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Float"); ConstExprValue *fields = create_const_vals(1); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // bits: u8 - ensure_field_index(payload->type, "bits", 0); + ensure_field_index(result->type, "bits", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); - - return payload; + break; } case TypeTableEntryIdPointer: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Pointer"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Pointer"); ConstExprValue *fields = create_const_vals(4); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // is_const: bool - ensure_field_index(payload->type, "is_const", 0); + ensure_field_index(result->type, "is_const", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_bool; fields[0].data.x_bool = type_entry->data.pointer.is_const; // is_volatile: bool - ensure_field_index(payload->type, "is_volatile", 1); + ensure_field_index(result->type, "is_volatile", 1); fields[1].special = ConstValSpecialStatic; fields[1].type = ira->codegen->builtin_types.entry_bool; fields[1].data.x_bool = type_entry->data.pointer.is_volatile; // alignment: u32 - ensure_field_index(payload->type, "alignment", 2); + ensure_field_index(result->type, "alignment", 2); fields[2].special = ConstValSpecialStatic; fields[2].type = ira->codegen->builtin_types.entry_u32; bigint_init_unsigned(&fields[2].data.x_bigint, type_entry->data.pointer.alignment); // child: &TypeInfo - ensure_field_index(payload->type, "child", 3); + ensure_field_index(result->type, "child", 3); TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); @@ -15917,26 +15924,26 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p type_entry->data.pointer.child_type); fields[3].data.x_ptr.data.ref.pointee = union_val; - return payload; + break; } case TypeTableEntryIdArray: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Array"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Array"); ConstExprValue *fields = create_const_vals(2); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // len: usize - ensure_field_index(payload->type, "len", 0); + ensure_field_index(result->type, "len", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_usize; bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); // child: &TypeInfo - ensure_field_index(payload->type, "child", 1); + ensure_field_index(result->type, "child", 1); TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); @@ -15953,21 +15960,21 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p type_entry->data.array.child_type); fields[1].data.x_ptr.data.ref.pointee = union_val; - return payload; + break; } case TypeTableEntryIdMaybe: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Nullable"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Nullable"); ConstExprValue *fields = create_const_vals(1); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // child: &TypeInfo - ensure_field_index(payload->type, "child", 0); + ensure_field_index(result->type, "child", 0); TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); @@ -15984,21 +15991,21 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p type_entry->data.maybe.child_type); fields[0].data.x_ptr.data.ref.pointee = union_val; - return payload; + break; } case TypeTableEntryIdPromise: { - ConstExprValue *payload = create_const_vals(1); - payload->special = ConstValSpecialStatic; - payload->type = ir_type_info_get_type(ira, "Promise"); + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Promise"); ConstExprValue *fields = create_const_vals(1); - payload->data.x_struct.fields = fields; + result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(payload, parent, parent_field_index); + ir_type_info_struct_set_parent(result, parent, parent_field_index); // child: ?&TypeInfo - ensure_field_index(payload->type, "child", 0); + ensure_field_index(result->type, "child", 0); TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); TypeTableEntry *type_info_ptr_type = get_pointer_to_type(ira->codegen, type_info_type, false); @@ -16029,11 +16036,15 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p maybe_value->data.x_ptr.data.ref.pointee = union_val; fields[0].data.x_maybe = maybe_value; } - return payload; + break; } default: zig_unreachable(); } + + assert(result != nullptr); + ira->codegen->type_info_cache.put(type_entry, result); + return result; } static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, -- cgit v1.2.3 From 7a91e4736a4151bd41b65b6e3b395cc51c443162 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Thu, 26 Apr 2018 14:29:27 +0300 Subject: Reset parent on cached TypeInfo values if we need to. --- src/codegen.cpp | 3 ++- src/ir.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 7 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 71df7fcd65..a8c32044fc 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6348,7 +6348,6 @@ static void define_builtin_compile_vars(CodeGen *g) { buf_appendf(contents, "};\n\n"); } { - // @TODO Add method info where methods are supported. // @TODO Add Namespace info. buf_appendf(contents, "pub const TypeInfo = union(TypeId) {\n" @@ -6449,6 +6448,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " layout: ContainerLayout,\n" " tag_type: Int,\n" " fields: []EnumField,\n" + " methods: []Method,\n" " };\n" "\n" " pub const UnionField = struct {\n" @@ -6461,6 +6461,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " layout: ContainerLayout,\n" " tag_type: ?Enum,\n" " fields: []UnionField,\n" + " methods: []Method,\n" " };\n" "\n" " pub const CallingConvention = enum {\n" diff --git a/src/ir.cpp b/src/ir.cpp index 9229e4e89d..5cffb882f2 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15810,17 +15810,61 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, ssize_t parent_field_index, TypeTableEntry *type_entry) { + assert(type_entry != nullptr); + assert(!type_is_invalid(type_entry)); + // Lookup an available value in our cache. auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); if (entry != nullptr) - return entry->value; + { + // Override the parent if we need to. + ConstExprValue *result = entry->value; - ConstExprValue *result = nullptr; + assert(result->type->id == TypeTableEntryIdStruct); - // @TODO - // We should probably cache the values generated with a type_entry key. - assert(type_entry != nullptr); - assert(!type_is_invalid(type_entry)); + ConstParent *curr_parent = &result->data.x_struct.parent; + if (curr_parent->id == ConstParentIdStruct) + { + if (curr_parent->data.p_struct.struct_val == parent && + parent_field_index != -1 && + curr_parent->data.p_struct.field_index == (size_t)parent_field_index) + { + return result; + } + ConstExprValue *new_result = create_const_vals(1); + copy_const_val(new_result, result, true); + ir_type_info_struct_set_parent(new_result, parent, parent_field_index); + return new_result; + } + else if (curr_parent->id == ConstParentIdUnion) + { + if (curr_parent->data.p_union.union_val == parent) + { + return result; + } + ConstExprValue *new_result = create_const_vals(1); + copy_const_val(new_result, result, true); + ir_type_info_struct_set_parent(new_result, parent, parent_field_index); + return new_result; + } + else if (curr_parent->id == ConstParentIdNone) + { + if (parent->type->id != TypeTableEntryIdStruct && + parent->type->id != TypeTableEntryIdArray && + parent->type->id != TypeTableEntryIdUnion) + { + return result; + } + ConstExprValue *new_result = create_const_vals(1); + copy_const_val(new_result, result, true); + ir_type_info_struct_set_parent(new_result, parent, parent_field_index); + return new_result; + } + + return result; + } + + ConstExprValue *result = nullptr; switch (type_entry->id) { @@ -16042,6 +16086,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p zig_unreachable(); } + // Cache the returned value. assert(result != nullptr); ira->codegen->type_info_cache.put(type_entry, result); return result; -- cgit v1.2.3 From f5977f68ebe344ec9c96507322218b87c24804a1 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Thu, 26 Apr 2018 16:41:59 +0300 Subject: Added Enum TypeInfo except for methods --- src/codegen.cpp | 8 ++-- src/ir.cpp | 125 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 111 insertions(+), 22 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index a8c32044fc..9c4e5b1555 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6412,7 +6412,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const StructField = struct {\n" " name: []const u8,\n" " offset: usize,\n" - " type_info: TypeInfo,\n" + " type_info: &TypeInfo,\n" " };\n" "\n" " pub const Struct = struct {\n" @@ -6446,7 +6446,7 @@ static void define_builtin_compile_vars(CodeGen *g) { "\n" " pub const Enum = struct {\n" " layout: ContainerLayout,\n" - " tag_type: Int,\n" + " tag_type: &Int,\n" " fields: []EnumField,\n" " methods: []Method,\n" " };\n" @@ -6454,7 +6454,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const UnionField = struct {\n" " name: []const u8,\n" " enum_field: EnumField,\n" - " type_info: TypeInfo,\n" + " type_info: &TypeInfo,\n" " };\n" "\n" " pub const Union = struct {\n" @@ -6476,7 +6476,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const FnArg = struct {\n" " is_comptime: bool,\n" " name: []const u8,\n" - " type_info: TypeInfo,\n" + " type_info: &TypeInfo,\n" " };\n" "\n" " pub const Fn = struct {\n" diff --git a/src/ir.cpp b/src/ir.cpp index 5cffb882f2..9ca95d6222 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15864,7 +15864,11 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p return result; } - ConstExprValue *result = nullptr; + // If the value is not present in the cache, we will build it, add it and return it. + // We add values to the cache eagerly, as soon as we have filled out the root object's fields. + // That way, if we need to fetch the value in a recursive call down the line, even if we need to + // copy the value and reajust the parent, the value we get back still points to child values that + // will be filled later. switch (type_entry->id) { @@ -15885,7 +15889,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p return nullptr; case TypeTableEntryIdInt: { - result = create_const_vals(1); + ConstExprValue *result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Int"); @@ -15893,6 +15897,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p result->data.x_struct.fields = fields; ir_type_info_struct_set_parent(result, parent, parent_field_index); + ira->codegen->type_info_cache.put(type_entry, result); // is_signed: bool ensure_field_index(result->type, "is_signed", 0); @@ -15904,11 +15909,12 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p fields[1].special = ConstValSpecialStatic; fields[1].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); - break; + + return result; } case TypeTableEntryIdFloat: { - result = create_const_vals(1); + ConstExprValue *result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Float"); @@ -15916,17 +15922,19 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p result->data.x_struct.fields = fields; ir_type_info_struct_set_parent(result, parent, parent_field_index); + ira->codegen->type_info_cache.put(type_entry, result); // bits: u8 ensure_field_index(result->type, "bits", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); - break; + + return result; } case TypeTableEntryIdPointer: { - result = create_const_vals(1); + ConstExprValue *result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Pointer"); @@ -15934,6 +15942,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p result->data.x_struct.fields = fields; ir_type_info_struct_set_parent(result, parent, parent_field_index); + ira->codegen->type_info_cache.put(type_entry, result); // is_const: bool ensure_field_index(result->type, "is_const", 0); @@ -15968,11 +15977,12 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p type_entry->data.pointer.child_type); fields[3].data.x_ptr.data.ref.pointee = union_val; - break; + + return result; } case TypeTableEntryIdArray: { - result = create_const_vals(1); + ConstExprValue *result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Array"); @@ -15980,6 +15990,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p result->data.x_struct.fields = fields; ir_type_info_struct_set_parent(result, parent, parent_field_index); + ira->codegen->type_info_cache.put(type_entry, result); // len: usize ensure_field_index(result->type, "len", 0); @@ -15988,7 +15999,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); // child: &TypeInfo ensure_field_index(result->type, "child", 1); - TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); fields[1].special = ConstValSpecialStatic; @@ -16004,11 +16014,12 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p type_entry->data.array.child_type); fields[1].data.x_ptr.data.ref.pointee = union_val; - break; + + return result; } case TypeTableEntryIdMaybe: { - result = create_const_vals(1); + ConstExprValue *result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Nullable"); @@ -16016,6 +16027,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p result->data.x_struct.fields = fields; ir_type_info_struct_set_parent(result, parent, parent_field_index); + ira->codegen->type_info_cache.put(type_entry, result); // child: &TypeInfo ensure_field_index(result->type, "child", 0); @@ -16035,11 +16047,12 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p type_entry->data.maybe.child_type); fields[0].data.x_ptr.data.ref.pointee = union_val; - break; + + return result; } case TypeTableEntryIdPromise: { - result = create_const_vals(1); + ConstExprValue *result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Promise"); @@ -16047,6 +16060,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p result->data.x_struct.fields = fields; ir_type_info_struct_set_parent(result, parent, parent_field_index); + ira->codegen->type_info_cache.put(type_entry, result); // child: ?&TypeInfo ensure_field_index(result->type, "child", 0); @@ -16080,16 +16094,91 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p maybe_value->data.x_ptr.data.ref.pointee = union_val; fields[0].data.x_maybe = maybe_value; } - break; + + return result; + } + case TypeTableEntryIdEnum: + { + ConstExprValue *result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Enum"); + + ConstExprValue *fields = create_const_vals(4); + result->data.x_struct.fields = fields; + + ir_type_info_struct_set_parent(result, parent, parent_field_index); + ira->codegen->type_info_cache.put(type_entry, result); + + // layout: ContainerLayout + ensure_field_index(result->type, "layout", 0); + fields[0].special = ConstValSpecialStatic; + fields[0].type = ir_type_info_get_type(ira, "ContainerLayout"); + bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout); + // tag_type: &TypeInfo.Int + ensure_field_index(result->type, "tag_type", 1); + + TypeTableEntry *type_info_int_type = ir_type_info_get_type(ira, "Int"); + + fields[1].special = ConstValSpecialStatic; + fields[1].type = get_pointer_to_type(ira->codegen, type_info_int_type, false); + fields[1].data.x_ptr.special = ConstPtrSpecialRef; + fields[1].data.x_ptr.mut = ConstPtrMutComptimeVar; + + ConstExprValue *tag_type_info_struct = ir_make_type_info_value(ira, &fields[1], -1, + type_entry->data.enumeration.tag_int_type); + assert(tag_type_info_struct->type == type_info_int_type); + fields[1].data.x_ptr.data.ref.pointee = tag_type_info_struct; + // fields: []TypeInfo.EnumField + ensure_field_index(result->type, "fields", 2); + + TypeTableEntry *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField"); + // @TODO Those cause a find_struct_type_field assertion to fail (type_entry->data.structure.complete) + // ensure_field_index(type_info_enum_field_type, "name", 0); + // ensure_field_index(type_info_enum_field_type, "value", 1); + + uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; + + ConstExprValue *enum_field_array = create_const_vals(1); + enum_field_array->special = ConstValSpecialStatic; + enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count); + enum_field_array->data.x_array.special = ConstArraySpecialNone; + enum_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; + enum_field_array->data.x_array.s_none.elements = create_const_vals(enum_field_count); + + init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false); + + for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) + { + TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; + ConstExprValue *enum_field_val = &enum_field_array->data.x_array.s_none.elements[enum_field_index]; + + enum_field_val->special = ConstValSpecialStatic; + enum_field_val->type = type_info_enum_field_type; + + ConstExprValue *inner_fields = create_const_vals(2); + inner_fields[1].special = ConstValSpecialStatic; + inner_fields[1].type = ira->codegen->builtin_types.entry_usize; + + ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); + init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true); + + bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value); + + enum_field_val->data.x_struct.fields = inner_fields; + enum_field_val->data.x_struct.parent.id = ConstParentIdArray; + enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; + enum_field_val->data.x_struct.parent.data.p_array.elem_index = enum_field_index; + } + + // @TODO + // methods: []TypeInfo.Method + return result; } default: zig_unreachable(); } - // Cache the returned value. - assert(result != nullptr); - ira->codegen->type_info_cache.put(type_entry, result); - return result; + zig_unreachable(); } static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, -- cgit v1.2.3 From 4aa5d87ada56f9887d49c7a2a80246e0bb9d5fb9 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Thu, 26 Apr 2018 17:14:38 +0300 Subject: Added ErrorSet TypeInfo generation. --- src/codegen.cpp | 2 +- src/ir.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 9c4e5b1555..8c56af674c 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6426,7 +6426,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " };\n" "\n" " pub const ErrorUnion = struct {\n" - " error_set: ErrorSet,\n" + " error_set: &ErrorSet,\n" " payload: &TypeInfo,\n" " };\n" "\n" diff --git a/src/ir.cpp b/src/ir.cpp index 9ca95d6222..92fd7a7018 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -16172,6 +16172,63 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p // @TODO // methods: []TypeInfo.Method + return result; + } + case TypeTableEntryIdErrorSet: + { + ConstExprValue *result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "ErrorSet"); + + ConstExprValue *fields = create_const_vals(1); + result->data.x_struct.fields = fields; + + ir_type_info_struct_set_parent(result, parent, parent_field_index); + ira->codegen->type_info_cache.put(type_entry, result); + + // errors: []TypeInfo.Error + ensure_field_index(result->type, "errors", 0); + + TypeTableEntry *type_info_error_type = ir_type_info_get_type(ira, "Error"); + // @TODO Same as above in Enum TypeInfo generation. + // ensure_field_index(type_info_error_type, "name", 0); + // ensure_field_index(type_info_error_type, "value", 1); + + uint32_t error_count = type_entry->data.error_set.err_count; + ConstExprValue *error_array = create_const_vals(1); + error_array->special = ConstValSpecialStatic; + error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count); + error_array->data.x_array.special = ConstArraySpecialNone; + error_array->data.x_array.s_none.parent.id = ConstParentIdNone; + error_array->data.x_array.s_none.elements = create_const_vals(error_count); + + init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false); + for (uint32_t error_index = 0; error_index < error_count; error_index++) + { + ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; + ConstExprValue *error_val = &error_array->data.x_array.s_none.elements[error_index]; + + error_val->special = ConstValSpecialStatic; + error_val->type = type_info_error_type; + + ConstExprValue *inner_fields = create_const_vals(2); + inner_fields[1].special = ConstValSpecialStatic; + inner_fields[1].type = ira->codegen->builtin_types.entry_usize; + + ConstExprValue *name = nullptr; + if (error->cached_error_name_val != nullptr) + name = error->cached_error_name_val; + if (name == nullptr) + name = create_const_str_lit(ira->codegen, &error->name); + init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(&error->name), true); + bigint_init_unsigned(&inner_fields[1].data.x_bigint, error->value); + + error_val->data.x_struct.fields = inner_fields; + error_val->data.x_struct.parent.id = ConstParentIdArray; + error_val->data.x_struct.parent.data.p_array.array_val = error_array; + error_val->data.x_struct.parent.data.p_array.elem_index = error_index; + } + return result; } default: -- cgit v1.2.3 From fbbbee6b72991b65c31a8eac8f1edfc3d1a88b59 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Thu, 26 Apr 2018 18:18:47 +0300 Subject: Switched to shallow TypeInfo. --- src/codegen.cpp | 24 ++--- src/ir.cpp | 271 ++++++++++++-------------------------------------------- 2 files changed, 69 insertions(+), 226 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 8c56af674c..c8bb502718 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6390,12 +6390,12 @@ static void define_builtin_compile_vars(CodeGen *g) { " is_const: bool,\n" " is_volatile: bool,\n" " alignment: u32,\n" - " child: &TypeInfo,\n" + " child: type,\n" " };\n" "\n" " pub const Array = struct {\n" " len: usize,\n" - " child: &TypeInfo,\n" + " child: type,\n" " };\n" "\n" " pub const ContainerLayout = enum {\n" @@ -6412,7 +6412,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const StructField = struct {\n" " name: []const u8,\n" " offset: usize,\n" - " type_info: &TypeInfo,\n" + " field_type: type,\n" " };\n" "\n" " pub const Struct = struct {\n" @@ -6422,12 +6422,12 @@ static void define_builtin_compile_vars(CodeGen *g) { " };\n" "\n" " pub const Nullable = struct {\n" - " child: &TypeInfo,\n" + " child: type,\n" " };\n" "\n" " pub const ErrorUnion = struct {\n" " error_set: &ErrorSet,\n" - " payload: &TypeInfo,\n" + " payload: type,\n" " };\n" "\n" " pub const Error = struct {\n" @@ -6446,7 +6446,7 @@ static void define_builtin_compile_vars(CodeGen *g) { "\n" " pub const Enum = struct {\n" " layout: ContainerLayout,\n" - " tag_type: &Int,\n" + " tag_type: type,\n" " fields: []EnumField,\n" " methods: []Method,\n" " };\n" @@ -6454,12 +6454,12 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const UnionField = struct {\n" " name: []const u8,\n" " enum_field: EnumField,\n" - " type_info: &TypeInfo,\n" + " field_type: type,\n" " };\n" "\n" " pub const Union = struct {\n" " layout: ContainerLayout,\n" - " tag_type: ?Enum,\n" + " tag_type: type,\n" " fields: []UnionField,\n" " methods: []Method,\n" " };\n" @@ -6476,24 +6476,24 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const FnArg = struct {\n" " is_comptime: bool,\n" " name: []const u8,\n" - " type_info: &TypeInfo,\n" + " arg_type: type,\n" " };\n" "\n" " pub const Fn = struct {\n" " calling_convention: CallingConvention,\n" " is_generic: bool,\n" " is_varargs: bool,\n" - " return_type: &TypeInfo,\n" + " return_type: type,\n" " args: []FnArg,\n" " };\n" "\n" " pub const BoundFn = struct {\n" - " bound_type: &TypeInfo,\n" + " bound_type: type,\n" " fn_info: Fn,\n" " };\n" "\n" " pub const Promise = struct {\n" - " child: ?&TypeInfo,\n" + " child: type,\n" " };\n" "};\n\n"); assert(ContainerLayoutAuto == 0); diff --git a/src/ir.cpp b/src/ir.cpp index 92fd7a7018..fdf1a0c8ab 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15748,31 +15748,6 @@ static void ensure_field_index(TypeTableEntry *type, const char *field_name, siz (buf_deinit(field_name_buf), true)); } -static void ir_type_info_struct_set_parent(ConstExprValue *struct_val, ConstExprValue *parent, ssize_t parent_field_index) -{ - assert(struct_val->type->id == TypeTableEntryIdStruct); - assert(parent->type != nullptr && !type_is_invalid(parent->type)); - - switch (parent->type->id) - { - case TypeTableEntryIdArray: - zig_panic("TODO - Only expected struct or union parent."); - case TypeTableEntryIdStruct: - assert(parent_field_index >= 0); - struct_val->data.x_struct.parent.id = ConstParentIdStruct; - struct_val->data.x_struct.parent.data.p_struct.struct_val = parent; - struct_val->data.x_struct.parent.data.p_struct.field_index = parent_field_index; - break; - case TypeTableEntryIdUnion: - assert(parent_field_index == -1); - struct_val->data.x_struct.parent.id = ConstParentIdUnion; - struct_val->data.x_struct.parent.data.p_union.union_val = parent; - break; - default: - struct_val->data.x_struct.parent.id = ConstParentIdNone; - } -} - static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_name) { static ConstExprValue *type_info_var = nullptr; @@ -15807,69 +15782,12 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na return var->value->data.x_type; } -static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *parent, - ssize_t parent_field_index, TypeTableEntry *type_entry) +static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry) { assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); - // Lookup an available value in our cache. - auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); - if (entry != nullptr) - { - // Override the parent if we need to. - ConstExprValue *result = entry->value; - - assert(result->type->id == TypeTableEntryIdStruct); - - ConstParent *curr_parent = &result->data.x_struct.parent; - if (curr_parent->id == ConstParentIdStruct) - { - if (curr_parent->data.p_struct.struct_val == parent && - parent_field_index != -1 && - curr_parent->data.p_struct.field_index == (size_t)parent_field_index) - { - return result; - } - ConstExprValue *new_result = create_const_vals(1); - copy_const_val(new_result, result, true); - ir_type_info_struct_set_parent(new_result, parent, parent_field_index); - return new_result; - } - else if (curr_parent->id == ConstParentIdUnion) - { - if (curr_parent->data.p_union.union_val == parent) - { - return result; - } - ConstExprValue *new_result = create_const_vals(1); - copy_const_val(new_result, result, true); - ir_type_info_struct_set_parent(new_result, parent, parent_field_index); - return new_result; - } - else if (curr_parent->id == ConstParentIdNone) - { - if (parent->type->id != TypeTableEntryIdStruct && - parent->type->id != TypeTableEntryIdArray && - parent->type->id != TypeTableEntryIdUnion) - { - return result; - } - ConstExprValue *new_result = create_const_vals(1); - copy_const_val(new_result, result, true); - ir_type_info_struct_set_parent(new_result, parent, parent_field_index); - return new_result; - } - - return result; - } - - // If the value is not present in the cache, we will build it, add it and return it. - // We add values to the cache eagerly, as soon as we have filled out the root object's fields. - // That way, if we need to fetch the value in a recursive call down the line, even if we need to - // copy the value and reajust the parent, the value we get back still points to child values that - // will be filled later. - + ConstExprValue *result = nullptr; switch (type_entry->id) { case TypeTableEntryIdInvalid: @@ -15887,18 +15805,24 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p case TypeTableEntryIdArgTuple: case TypeTableEntryIdOpaque: return nullptr; + default: + { + // Lookup an available value in our cache. + auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); + if (entry != nullptr) + return entry->value; + + // Fallthrough if we don't find one. + } case TypeTableEntryIdInt: { - ConstExprValue *result = create_const_vals(1); + result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Int"); ConstExprValue *fields = create_const_vals(2); result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(result, parent, parent_field_index); - ira->codegen->type_info_cache.put(type_entry, result); - // is_signed: bool ensure_field_index(result->type, "is_signed", 0); fields[0].special = ConstValSpecialStatic; @@ -15910,40 +15834,34 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p fields[1].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); - return result; + break; } case TypeTableEntryIdFloat: { - ConstExprValue *result = create_const_vals(1); + result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Float"); ConstExprValue *fields = create_const_vals(1); result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(result, parent, parent_field_index); - ira->codegen->type_info_cache.put(type_entry, result); - // bits: u8 ensure_field_index(result->type, "bits", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_u8; bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); - return result; + break; } case TypeTableEntryIdPointer: { - ConstExprValue *result = create_const_vals(1); + result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Pointer"); ConstExprValue *fields = create_const_vals(4); result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(result, parent, parent_field_index); - ira->codegen->type_info_cache.put(type_entry, result); - // is_const: bool ensure_field_index(result->type, "is_const", 0); fields[0].special = ConstValSpecialStatic; @@ -15959,175 +15877,94 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p fields[2].special = ConstValSpecialStatic; fields[2].type = ira->codegen->builtin_types.entry_u32; bigint_init_unsigned(&fields[2].data.x_bigint, type_entry->data.pointer.alignment); - // child: &TypeInfo + // child: type ensure_field_index(result->type, "child", 3); - - TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); - fields[3].special = ConstValSpecialStatic; - fields[3].type = get_pointer_to_type(ira->codegen, type_info_type, false); - fields[3].data.x_ptr.special = ConstPtrSpecialRef; - fields[3].data.x_ptr.mut = ConstPtrMutComptimeVar; - ConstExprValue *union_val = create_const_vals(1); - union_val->special = ConstValSpecialStatic; - union_val->type = type_info_type; - bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.pointer.child_type->id)); + fields[3].type = ira->codegen->builtin_types.entry_type; + fields[3].data.x_type = type_entry->data.pointer.child_type; - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, - type_entry->data.pointer.child_type); - - fields[3].data.x_ptr.data.ref.pointee = union_val; - - return result; + break; } case TypeTableEntryIdArray: { - ConstExprValue *result = create_const_vals(1); + result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Array"); ConstExprValue *fields = create_const_vals(2); result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(result, parent, parent_field_index); - ira->codegen->type_info_cache.put(type_entry, result); - // len: usize ensure_field_index(result->type, "len", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ira->codegen->builtin_types.entry_usize; bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); - // child: &TypeInfo + // child: type ensure_field_index(result->type, "child", 1); - TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); - fields[1].special = ConstValSpecialStatic; - fields[1].type = get_pointer_to_type(ira->codegen, type_info_type, false); - fields[1].data.x_ptr.special = ConstPtrSpecialRef; - fields[1].data.x_ptr.mut = ConstPtrMutComptimeVar; - ConstExprValue *union_val = create_const_vals(1); - union_val->special = ConstValSpecialStatic; - union_val->type = type_info_type; - bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.array.child_type->id)); + fields[1].type = ira->codegen->builtin_types.entry_type; + fields[1].data.x_type = type_entry->data.array.child_type; - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, - type_entry->data.array.child_type); - - fields[1].data.x_ptr.data.ref.pointee = union_val; - - return result; + break; } case TypeTableEntryIdMaybe: { - ConstExprValue *result = create_const_vals(1); + result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Nullable"); ConstExprValue *fields = create_const_vals(1); result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(result, parent, parent_field_index); - ira->codegen->type_info_cache.put(type_entry, result); - - // child: &TypeInfo + // child: type ensure_field_index(result->type, "child", 0); - - TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); - fields[0].special = ConstValSpecialStatic; - fields[0].type = get_pointer_to_type(ira->codegen, type_info_type, false); - fields[0].data.x_ptr.special = ConstPtrSpecialRef; - fields[0].data.x_ptr.mut = ConstPtrMutComptimeVar; - ConstExprValue *union_val = create_const_vals(1); - union_val->special = ConstValSpecialStatic; - union_val->type = type_info_type; - bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.maybe.child_type->id)); - - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, - type_entry->data.maybe.child_type); - - fields[0].data.x_ptr.data.ref.pointee = union_val; + fields[0].type = ira->codegen->builtin_types.entry_type; + fields[0].data.x_type = type_entry->data.maybe.child_type; - return result; + break; } case TypeTableEntryIdPromise: { - ConstExprValue *result = create_const_vals(1); + result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Promise"); ConstExprValue *fields = create_const_vals(1); result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(result, parent, parent_field_index); - ira->codegen->type_info_cache.put(type_entry, result); - - // child: ?&TypeInfo + // @TODO ?type instead of using @typeOf(undefined) when we have no type. + // child: type ensure_field_index(result->type, "child", 0); - - TypeTableEntry *type_info_type = ir_type_info_get_type(ira, nullptr); - TypeTableEntry *type_info_ptr_type = get_pointer_to_type(ira->codegen, type_info_type, false); - fields[0].special = ConstValSpecialStatic; - fields[0].type = get_maybe_type(ira->codegen, type_info_ptr_type); + fields[0].type = ira->codegen->builtin_types.entry_type; if (type_entry->data.promise.result_type == nullptr) - { - fields[0].data.x_maybe = nullptr; - } + fields[0].data.x_type = ira->codegen->builtin_types.entry_undef; else - { - ConstExprValue *maybe_value = create_const_vals(1); - maybe_value->special = ConstValSpecialStatic; - maybe_value->type = type_info_ptr_type; - - maybe_value->data.x_ptr.special = ConstPtrSpecialRef; - maybe_value->data.x_ptr.mut = ConstPtrMutComptimeVar; - - ConstExprValue *union_val = create_const_vals(1); - union_val->special = ConstValSpecialStatic; - union_val->type = type_info_type; - bigint_init_unsigned(&union_val->data.x_union.tag, type_id_index(type_entry->data.promise.result_type->id)); - union_val->data.x_union.payload = ir_make_type_info_value(ira, union_val, -1, - type_entry->data.promise.result_type); - - maybe_value->data.x_ptr.data.ref.pointee = union_val; - fields[0].data.x_maybe = maybe_value; - } + fields[0].data.x_type = type_entry->data.promise.result_type; - return result; + break; } case TypeTableEntryIdEnum: { - ConstExprValue *result = create_const_vals(1); + result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Enum"); ConstExprValue *fields = create_const_vals(4); result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(result, parent, parent_field_index); - ira->codegen->type_info_cache.put(type_entry, result); - // layout: ContainerLayout ensure_field_index(result->type, "layout", 0); fields[0].special = ConstValSpecialStatic; fields[0].type = ir_type_info_get_type(ira, "ContainerLayout"); bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout); - // tag_type: &TypeInfo.Int + // tag_type: type ensure_field_index(result->type, "tag_type", 1); - - TypeTableEntry *type_info_int_type = ir_type_info_get_type(ira, "Int"); - fields[1].special = ConstValSpecialStatic; - fields[1].type = get_pointer_to_type(ira->codegen, type_info_int_type, false); - fields[1].data.x_ptr.special = ConstPtrSpecialRef; - fields[1].data.x_ptr.mut = ConstPtrMutComptimeVar; - - ConstExprValue *tag_type_info_struct = ir_make_type_info_value(ira, &fields[1], -1, - type_entry->data.enumeration.tag_int_type); - assert(tag_type_info_struct->type == type_info_int_type); - fields[1].data.x_ptr.data.ref.pointee = tag_type_info_struct; + fields[1].type = ira->codegen->builtin_types.entry_type; + fields[1].data.x_type = type_entry->data.enumeration.tag_int_type; // fields: []TypeInfo.EnumField ensure_field_index(result->type, "fields", 2); @@ -16172,20 +16009,17 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p // @TODO // methods: []TypeInfo.Method - return result; + break; } case TypeTableEntryIdErrorSet: { - ConstExprValue *result = create_const_vals(1); + result = create_const_vals(1); result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "ErrorSet"); ConstExprValue *fields = create_const_vals(1); result->data.x_struct.fields = fields; - ir_type_info_struct_set_parent(result, parent, parent_field_index); - ira->codegen->type_info_cache.put(type_entry, result); - // errors: []TypeInfo.Error ensure_field_index(result->type, "errors", 0); @@ -16229,13 +16063,13 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, ConstExprValue *p error_val->data.x_struct.parent.data.p_array.elem_index = error_index; } - return result; + break; } - default: - zig_unreachable(); } - zig_unreachable(); + assert(result != nullptr); + ira->codegen->type_info_cache.put(type_entry, result); + return result; } static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, @@ -16251,7 +16085,16 @@ static TypeTableEntry *ir_analyze_instruction_type_info(IrAnalyze *ira, ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); out_val->type = result_type; bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry->id)); - out_val->data.x_union.payload = ir_make_type_info_value(ira, out_val, -1, type_entry); + + ConstExprValue *payload = ir_make_type_info_value(ira, type_entry); + out_val->data.x_union.payload = payload; + + if (payload != nullptr) + { + assert(payload->type->id == TypeTableEntryIdStruct); + payload->data.x_struct.parent.id = ConstParentIdUnion; + payload->data.x_struct.parent.data.p_union.union_val = out_val; + } return result_type; } -- cgit v1.2.3 From 884e32d5c3aac470cdcd9b20e15554d6193f5501 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Thu, 26 Apr 2018 19:56:34 +0300 Subject: Added ErrorUnion, Union TypeInfo generation --- src/codegen.cpp | 2 +- src/ir.cpp | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 127 insertions(+), 15 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index c8bb502718..77794c2ab9 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6426,7 +6426,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " };\n" "\n" " pub const ErrorUnion = struct {\n" - " error_set: &ErrorSet,\n" + " error_set: type,\n" " payload: type,\n" " };\n" "\n" diff --git a/src/ir.cpp b/src/ir.cpp index fdf1a0c8ab..f91d1c3edf 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15787,6 +15787,27 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); + const auto make_enum_field_val = [ira](ConstExprValue *enum_field_val, TypeEnumField *enum_field) { + TypeTableEntry *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField"); + // @TODO Those cause a find_struct_type_field assertion to fail (type_entry->data.structure.complete) + // ensure_field_index(type_info_enum_field_type, "name", 0); + // ensure_field_index(type_info_enum_field_type, "value", 1); + + enum_field_val->special = ConstValSpecialStatic; + enum_field_val->type = type_info_enum_field_type; + + ConstExprValue *inner_fields = create_const_vals(2); + inner_fields[1].special = ConstValSpecialStatic; + inner_fields[1].type = ira->codegen->builtin_types.entry_usize; + + ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); + init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true); + + bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value); + + enum_field_val->data.x_struct.fields = inner_fields; + }; + ConstExprValue *result = nullptr; switch (type_entry->id) { @@ -15988,20 +16009,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t { TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; ConstExprValue *enum_field_val = &enum_field_array->data.x_array.s_none.elements[enum_field_index]; - - enum_field_val->special = ConstValSpecialStatic; - enum_field_val->type = type_info_enum_field_type; - - ConstExprValue *inner_fields = create_const_vals(2); - inner_fields[1].special = ConstValSpecialStatic; - inner_fields[1].type = ira->codegen->builtin_types.entry_usize; - - ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); - init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true); - - bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value); - - enum_field_val->data.x_struct.fields = inner_fields; + make_enum_field_val(enum_field_val, enum_field); enum_field_val->data.x_struct.parent.id = ConstParentIdArray; enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; enum_field_val->data.x_struct.parent.data.p_array.elem_index = enum_field_index; @@ -16063,6 +16071,110 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t error_val->data.x_struct.parent.data.p_array.elem_index = error_index; } + break; + } + case TypeTableEntryIdErrorUnion: + { + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "ErrorUnion"); + + ConstExprValue *fields = create_const_vals(2); + result->data.x_struct.fields = fields; + + // error_set: type + ensure_field_index(result->type, "error_set", 0); + fields[0].special = ConstValSpecialStatic; + fields[0].type = ira->codegen->builtin_types.entry_type; + fields[0].data.x_type = type_entry->data.error_union.err_set_type; + + // payload: type + ensure_field_index(result->type, "payload", 1); + fields[1].special = ConstValSpecialStatic; + fields[1].type = ira->codegen->builtin_types.entry_type; + fields[1].data.x_type = type_entry->data.error_union.payload_type; + + break; + } + case TypeTableEntryIdUnion: + { + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Union"); + + ConstExprValue *fields = create_const_vals(4); + result->data.x_struct.fields = fields; + + // layout: ContainerLayout + ensure_field_index(result->type, "layout", 0); + fields[0].special = ConstValSpecialStatic; + fields[0].type = ir_type_info_get_type(ira, "ContainerLayout"); + bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout); + // tag_type: type + ensure_field_index(result->type, "tag_type", 1); + fields[1].special = ConstValSpecialStatic; + fields[1].type = ira->codegen->builtin_types.entry_type; + // @TODO ?type instead of using @typeOf(undefined) when we have no type. + if (type_entry->data.unionation.tag_type == nullptr) + fields[1].data.x_type = ira->codegen->builtin_types.entry_undef; + else + fields[1].data.x_type = type_entry->data.unionation.tag_type; + + fields[1].data.x_type = type_entry->data.unionation.tag_type; + // fields: []TypeInfo.UnionField + ensure_field_index(result->type, "fields", 2); + + TypeTableEntry *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField"); + // @TODO Those cause a find_struct_type_field assertion to fail (type_entry->data.structure.complete) + // ensure_field_index(type_info_union_field_type, "name", 0); + // ensure_field_index(type_info_union_field_type, "enum_field", 1); + // ensure_field_index(type_info_union_field_type, "field_type", 2); + + uint32_t union_field_count = type_entry->data.unionation.src_field_count; + + ConstExprValue *union_field_array = create_const_vals(1); + union_field_array->special = ConstValSpecialStatic; + union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count); + union_field_array->data.x_array.special = ConstArraySpecialNone; + union_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; + union_field_array->data.x_array.s_none.elements = create_const_vals(union_field_count); + + init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); + + for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) + { + TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; + ConstExprValue *union_field_val = &union_field_array->data.x_array.s_none.elements[union_field_index]; + + union_field_val->special = ConstValSpecialStatic; + union_field_val->type = type_info_union_field_type; + + ConstExprValue *inner_fields = create_const_vals(3); + inner_fields[1].special = ConstValSpecialStatic; + make_enum_field_val(&inner_fields[1], union_field->enum_field); + inner_fields[1].data.x_struct.parent.id = ConstParentIdStruct; + inner_fields[1].data.x_struct.parent.data.p_struct.struct_val = union_field_val; + inner_fields[1].data.x_struct.parent.data.p_struct.field_index = 1; + + inner_fields[2].special = ConstValSpecialStatic; + inner_fields[2].type = ira->codegen->builtin_types.entry_type; + inner_fields[2].data.x_type = union_field->type_entry; + + ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name); + init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true); + + + union_field_val->data.x_struct.fields = inner_fields; + union_field_val->data.x_struct.parent.id = ConstParentIdArray; + union_field_val->data.x_struct.parent.data.p_array.array_val = union_field_array; + union_field_val->data.x_struct.parent.data.p_array.elem_index = union_field_index; + + // @TODO Check if TypeUnionField::enum_field == nullptr when tag_type == nullptr + // If it is, make enum_field: ?EnumField, set it when available, done. + } + + // @TODO + // methods: []TypeInfo.Method break; } } -- cgit v1.2.3 From 9041d0d37e59e3f07d568f93bd680cc0065d1cd2 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Fri, 27 Apr 2018 02:05:24 +0300 Subject: Fixed enum tag type detection in TypeInfo generation. --- src/codegen.cpp | 8 +++++++- src/ir.cpp | 56 +++++++++++++++++++++++--------------------------------- 2 files changed, 30 insertions(+), 34 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 77794c2ab9..b6236197cc 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6349,6 +6349,12 @@ static void define_builtin_compile_vars(CodeGen *g) { } { // @TODO Add Namespace info. + // @TODO Methods -> definitions + // @TODO Includes type definitions (name + type bound) + functions + const variable definitions (+ type of variable) + // @TODO Type definitions are defined as variable definitions of type 'type' + // @TODO This should give us everything available. + // @TODO An alternative is exposing the value of every variable definition, check out if it's possible and wether we want that. + // @TODO I don't think so, @field gives it to us for free. buf_appendf(contents, "pub const TypeInfo = union(TypeId) {\n" " Type: void,\n" @@ -6453,7 +6459,7 @@ static void define_builtin_compile_vars(CodeGen *g) { "\n" " pub const UnionField = struct {\n" " name: []const u8,\n" - " enum_field: EnumField,\n" + " enum_field: ?EnumField,\n" " field_type: type,\n" " };\n" "\n" diff --git a/src/ir.cpp b/src/ir.cpp index f91d1c3edf..a6012b0a91 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15787,8 +15787,8 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); - const auto make_enum_field_val = [ira](ConstExprValue *enum_field_val, TypeEnumField *enum_field) { - TypeTableEntry *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField"); + const auto make_enum_field_val = [ira](ConstExprValue *enum_field_val, TypeEnumField *enum_field, + TypeTableEntry *type_info_enum_field_type) { // @TODO Those cause a find_struct_type_field assertion to fail (type_entry->data.structure.complete) // ensure_field_index(type_info_enum_field_type, "name", 0); // ensure_field_index(type_info_enum_field_type, "value", 1); @@ -15990,10 +15990,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t ensure_field_index(result->type, "fields", 2); TypeTableEntry *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField"); - // @TODO Those cause a find_struct_type_field assertion to fail (type_entry->data.structure.complete) - // ensure_field_index(type_info_enum_field_type, "name", 0); - // ensure_field_index(type_info_enum_field_type, "value", 1); - uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; ConstExprValue *enum_field_array = create_const_vals(1); @@ -16009,14 +16005,13 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t { TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; ConstExprValue *enum_field_val = &enum_field_array->data.x_array.s_none.elements[enum_field_index]; - make_enum_field_val(enum_field_val, enum_field); + make_enum_field_val(enum_field_val, enum_field, type_info_enum_field_type); enum_field_val->data.x_struct.parent.id = ConstParentIdArray; enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; enum_field_val->data.x_struct.parent.data.p_array.elem_index = enum_field_index; } - // @TODO - // methods: []TypeInfo.Method + // @TODO Definitions break; } case TypeTableEntryIdErrorSet: @@ -16032,10 +16027,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t ensure_field_index(result->type, "errors", 0); TypeTableEntry *type_info_error_type = ir_type_info_get_type(ira, "Error"); - // @TODO Same as above in Enum TypeInfo generation. - // ensure_field_index(type_info_error_type, "name", 0); - // ensure_field_index(type_info_error_type, "value", 1); - uint32_t error_count = type_entry->data.error_set.err_count; ConstExprValue *error_array = create_const_vals(1); error_array->special = ConstValSpecialStatic; @@ -16115,21 +16106,18 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t fields[1].special = ConstValSpecialStatic; fields[1].type = ira->codegen->builtin_types.entry_type; // @TODO ?type instead of using @typeOf(undefined) when we have no type. - if (type_entry->data.unionation.tag_type == nullptr) - fields[1].data.x_type = ira->codegen->builtin_types.entry_undef; - else + AstNode *union_decl_node = type_entry->data.unionation.decl_node; + if (union_decl_node->data.container_decl.auto_enum || + union_decl_node->data.container_decl.init_arg_expr != nullptr) + { fields[1].data.x_type = type_entry->data.unionation.tag_type; - - fields[1].data.x_type = type_entry->data.unionation.tag_type; + } + else + fields[1].data.x_type = ira->codegen->builtin_types.entry_undef; // fields: []TypeInfo.UnionField ensure_field_index(result->type, "fields", 2); TypeTableEntry *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField"); - // @TODO Those cause a find_struct_type_field assertion to fail (type_entry->data.structure.complete) - // ensure_field_index(type_info_union_field_type, "name", 0); - // ensure_field_index(type_info_union_field_type, "enum_field", 1); - // ensure_field_index(type_info_union_field_type, "field_type", 2); - uint32_t union_field_count = type_entry->data.unionation.src_field_count; ConstExprValue *union_field_array = create_const_vals(1); @@ -16141,6 +16129,8 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); + TypeTableEntry *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField"); + for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; @@ -16151,10 +16141,15 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t ConstExprValue *inner_fields = create_const_vals(3); inner_fields[1].special = ConstValSpecialStatic; - make_enum_field_val(&inner_fields[1], union_field->enum_field); - inner_fields[1].data.x_struct.parent.id = ConstParentIdStruct; - inner_fields[1].data.x_struct.parent.data.p_struct.struct_val = union_field_val; - inner_fields[1].data.x_struct.parent.data.p_struct.field_index = 1; + inner_fields[1].type = get_maybe_type(ira->codegen, type_info_enum_field_type); + + if (fields[1].data.x_type == ira->codegen->builtin_types.entry_undef) + inner_fields[1].data.x_maybe = nullptr; + else + { + inner_fields[1].data.x_maybe = create_const_vals(1); + make_enum_field_val(inner_fields[1].data.x_maybe, union_field->enum_field, type_info_enum_field_type); + } inner_fields[2].special = ConstValSpecialStatic; inner_fields[2].type = ira->codegen->builtin_types.entry_type; @@ -16163,18 +16158,13 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name); init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true); - union_field_val->data.x_struct.fields = inner_fields; union_field_val->data.x_struct.parent.id = ConstParentIdArray; union_field_val->data.x_struct.parent.data.p_array.array_val = union_field_array; union_field_val->data.x_struct.parent.data.p_array.elem_index = union_field_index; - - // @TODO Check if TypeUnionField::enum_field == nullptr when tag_type == nullptr - // If it is, make enum_field: ?EnumField, set it when available, done. } - // @TODO - // methods: []TypeInfo.Method + // @TODO Definitions break; } } -- cgit v1.2.3 From a2dadbc206f80dcf39b42f3be97a8d74795d0381 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Fri, 27 Apr 2018 02:52:09 +0300 Subject: Added struct TypeInfo generation. --- src/codegen.cpp | 2 +- src/ir.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index b6236197cc..873cf18072 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6417,7 +6417,7 @@ static void define_builtin_compile_vars(CodeGen *g) { "\n" " pub const StructField = struct {\n" " name: []const u8,\n" - " offset: usize,\n" + " offset: ?usize,\n" " field_type: type,\n" " };\n" "\n" diff --git a/src/ir.cpp b/src/ir.cpp index a6012b0a91..f167d76ca1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15787,6 +15787,8 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t assert(type_entry != nullptr); assert(!type_is_invalid(type_entry)); + ensure_complete_type(ira->codegen, type_entry); + const auto make_enum_field_val = [ira](ConstExprValue *enum_field_val, TypeEnumField *enum_field, TypeTableEntry *type_info_enum_field_type) { // @TODO Those cause a find_struct_type_field assertion to fail (type_entry->data.structure.complete) @@ -16164,6 +16166,72 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t union_field_val->data.x_struct.parent.data.p_array.elem_index = union_field_index; } + // @TODO Definitions + break; + } + case TypeTableEntryIdStruct: + { + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Struct"); + + ConstExprValue *fields = create_const_vals(3); + result->data.x_struct.fields = fields; + + // layout: ContainerLayout + ensure_field_index(result->type, "layout", 0); + fields[0].special = ConstValSpecialStatic; + fields[0].type = ir_type_info_get_type(ira, "ContainerLayout"); + bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.structure.layout); + // fields: []TypeInfo.StructField + ensure_field_index(result->type, "fields", 1); + + TypeTableEntry *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField"); + uint32_t struct_field_count = type_entry->data.structure.src_field_count; + + ConstExprValue *struct_field_array = create_const_vals(1); + struct_field_array->special = ConstValSpecialStatic; + struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count); + struct_field_array->data.x_array.special = ConstArraySpecialNone; + struct_field_array->data.x_array.s_none.parent.id = ConstParentIdNone; + struct_field_array->data.x_array.s_none.elements = create_const_vals(struct_field_count); + + init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false); + + for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) + { + TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index]; + ConstExprValue *struct_field_val = &struct_field_array->data.x_array.s_none.elements[struct_field_index]; + + struct_field_val->special = ConstValSpecialStatic; + struct_field_val->type = type_info_struct_field_type; + + ConstExprValue *inner_fields = create_const_vals(3); + inner_fields[1].special = ConstValSpecialStatic; + inner_fields[1].type = get_maybe_type(ira->codegen, ira->codegen->builtin_types.entry_usize); + + if (!type_has_bits(struct_field->type_entry)) + inner_fields[1].data.x_maybe = nullptr; + else + { + size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index); + inner_fields[1].data.x_maybe = create_const_vals(1); + inner_fields[1].data.x_maybe->type = ira->codegen->builtin_types.entry_usize; + bigint_init_unsigned(&inner_fields[1].data.x_maybe->data.x_bigint, byte_offset); + } + + inner_fields[2].special = ConstValSpecialStatic; + inner_fields[2].type = ira->codegen->builtin_types.entry_type; + inner_fields[2].data.x_type = struct_field->type_entry; + + ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name); + init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(struct_field->name), true); + + struct_field_val->data.x_struct.fields = inner_fields; + struct_field_val->data.x_struct.parent.id = ConstParentIdArray; + struct_field_val->data.x_struct.parent.data.p_array.array_val = struct_field_array; + struct_field_val->data.x_struct.parent.data.p_array.elem_index = struct_field_index; + } // @TODO Definitions break; } -- cgit v1.2.3 From 8f703f919f13e23b2c09f577a446aabb7799e27c Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Fri, 27 Apr 2018 04:29:50 +0300 Subject: Added Fn TypeInfo generation. --- src/codegen.cpp | 7 +++-- src/ir.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 3 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 873cf18072..ee85d7d3c4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6480,16 +6480,17 @@ static void define_builtin_compile_vars(CodeGen *g) { " };\n" "\n" " pub const FnArg = struct {\n" - " is_comptime: bool,\n" - " name: []const u8,\n" + " is_generic: bool,\n" + " is_noalias: bool,\n" " arg_type: type,\n" " };\n" "\n" " pub const Fn = struct {\n" " calling_convention: CallingConvention,\n" " is_generic: bool,\n" - " is_varargs: bool,\n" + " is_var_args: bool,\n" " return_type: type,\n" + " async_allocator_type: type,\n" " args: []FnArg,\n" " };\n" "\n" diff --git a/src/ir.cpp b/src/ir.cpp index f167d76ca1..a7076a3243 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -16233,6 +16233,98 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t struct_field_val->data.x_struct.parent.data.p_array.elem_index = struct_field_index; } // @TODO Definitions + break; + } + case TypeTableEntryIdFn: + { + result = create_const_vals(1); + result->special = ConstValSpecialStatic; + result->type = ir_type_info_get_type(ira, "Fn"); + + ConstExprValue *fields = create_const_vals(5); + result->data.x_struct.fields = fields; + + // @TODO Fix type = undefined with ?type + + // calling_convention: TypeInfo.CallingConvention + ensure_field_index(result->type, "calling_convention", 0); + fields[0].special = ConstValSpecialStatic; + fields[0].type = ir_type_info_get_type(ira, "CallingConvention"); + bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); + // is_generic: bool + ensure_field_index(result->type, "is_generic", 1); + bool is_generic = type_entry->data.fn.is_generic; + fields[1].special = ConstValSpecialStatic; + fields[1].type = ira->codegen->builtin_types.entry_bool; + fields[1].data.x_bool = is_generic; + // is_varargs: bool + ensure_field_index(result->type, "is_var_args", 2); + bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; + fields[2].special = ConstValSpecialStatic; + fields[2].type = ira->codegen->builtin_types.entry_bool; + fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; + // return_type: type + ensure_field_index(result->type, "return_type", 3); + fields[3].special = ConstValSpecialStatic; + fields[3].type = ira->codegen->builtin_types.entry_type; + if (type_entry->data.fn.fn_type_id.return_type == nullptr) + fields[3].data.x_type = ira->codegen->builtin_types.entry_undef; + else + fields[3].data.x_type = type_entry->data.fn.fn_type_id.return_type; + // async_allocator_type: type + ensure_field_index(result->type, "async_allocator_type", 4); + fields[4].special = ConstValSpecialStatic; + fields[4].type = ira->codegen->builtin_types.entry_type; + if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr) + fields[4].data.x_type = ira->codegen->builtin_types.entry_undef; + else + fields[4].data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type; + // args: []TypeInfo.FnArg + TypeTableEntry *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg"); + size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - + (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); + + ConstExprValue *fn_arg_array = create_const_vals(1); + fn_arg_array->special = ConstValSpecialStatic; + fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count); + fn_arg_array->data.x_array.special = ConstArraySpecialNone; + fn_arg_array->data.x_array.s_none.parent.id = ConstParentIdNone; + fn_arg_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); + + init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false); + + for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) + { + FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; + ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.s_none.elements[fn_arg_index]; + + fn_arg_val->special = ConstValSpecialStatic; + fn_arg_val->type = type_info_fn_arg_type; + + bool arg_is_generic = fn_param_info->type == nullptr; + if (arg_is_generic) assert(is_generic); + + ConstExprValue *inner_fields = create_const_vals(3); + inner_fields[0].special = ConstValSpecialStatic; + inner_fields[0].type = ira->codegen->builtin_types.entry_bool; + inner_fields[0].data.x_bool = arg_is_generic; + inner_fields[1].special = ConstValSpecialStatic; + inner_fields[1].type = ira->codegen->builtin_types.entry_bool; + inner_fields[1].data.x_bool = fn_param_info->is_noalias; + inner_fields[2].special = ConstValSpecialStatic; + inner_fields[2].type = ira->codegen->builtin_types.entry_type; + + if (arg_is_generic) + inner_fields[2].data.x_type = ira->codegen->builtin_types.entry_undef; + else + inner_fields[2].data.x_type = fn_param_info->type; + + fn_arg_val->data.x_struct.fields = inner_fields; + fn_arg_val->data.x_struct.parent.id = ConstParentIdArray; + fn_arg_val->data.x_struct.parent.data.p_array.array_val = fn_arg_array; + fn_arg_val->data.x_struct.parent.data.p_array.elem_index = fn_arg_index; + } + break; } } -- cgit v1.2.3 From ea2596280fc2c78f71b08921db3a4c9826eb93e0 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Fri, 27 Apr 2018 05:10:20 +0300 Subject: Added BoundFn TypeInfo generation. --- src/codegen.cpp | 7 +------ src/ir.cpp | 11 ++++++++++- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index ee85d7d3c4..fc872e1908 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6378,7 +6378,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " Fn: Fn,\n" " Namespace: void,\n" " Block: void,\n" - " BoundFn: BoundFn,\n" + " BoundFn: Fn,\n" " ArgTuple: void,\n" " Opaque: void,\n" " Promise: Promise,\n" @@ -6494,11 +6494,6 @@ static void define_builtin_compile_vars(CodeGen *g) { " args: []FnArg,\n" " };\n" "\n" - " pub const BoundFn = struct {\n" - " bound_type: type,\n" - " fn_info: Fn,\n" - " };\n" - "\n" " pub const Promise = struct {\n" " child: type,\n" " };\n" diff --git a/src/ir.cpp b/src/ir.cpp index a7076a3243..c2da83886a 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -16241,7 +16241,7 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Fn"); - ConstExprValue *fields = create_const_vals(5); + ConstExprValue *fields = create_const_vals(6); result->data.x_struct.fields = fields; // @TODO Fix type = undefined with ?type @@ -16325,6 +16325,15 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t fn_arg_val->data.x_struct.parent.data.p_array.elem_index = fn_arg_index; } + break; + } + case TypeTableEntryIdBoundFn: + { + // @TODO figure out memory corruption error. + TypeTableEntry *fn_type = type_entry->data.bound_fn.fn_type; + assert(fn_type->id == TypeTableEntryIdFn); + result = ir_make_type_info_value(ira, fn_type); + break; } } -- cgit v1.2.3 From 61b01805968939669a29f7189f4ce7fab46ab2da Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Sat, 28 Apr 2018 17:01:19 +0300 Subject: Added definition TypeInfo generation, except for function definitions. --- src/codegen.cpp | 30 ++++++------ src/ir.cpp | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 154 insertions(+), 26 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index fc872e1908..be1d59c26a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6348,13 +6348,6 @@ static void define_builtin_compile_vars(CodeGen *g) { buf_appendf(contents, "};\n\n"); } { - // @TODO Add Namespace info. - // @TODO Methods -> definitions - // @TODO Includes type definitions (name + type bound) + functions + const variable definitions (+ type of variable) - // @TODO Type definitions are defined as variable definitions of type 'type' - // @TODO This should give us everything available. - // @TODO An alternative is exposing the value of every variable definition, check out if it's possible and wether we want that. - // @TODO I don't think so, @field gives it to us for free. buf_appendf(contents, "pub const TypeInfo = union(TypeId) {\n" " Type: void,\n" @@ -6410,11 +6403,6 @@ static void define_builtin_compile_vars(CodeGen *g) { " Packed,\n" " };\n" "\n" - " pub const Method = struct {\n" - " name: []const u8,\n" - " fn_info: Fn,\n" - " };\n" - "\n" " pub const StructField = struct {\n" " name: []const u8,\n" " offset: ?usize,\n" @@ -6424,7 +6412,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const Struct = struct {\n" " layout: ContainerLayout,\n" " fields: []StructField,\n" - " methods: []Method,\n" + " defs: []Definition,\n" " };\n" "\n" " pub const Nullable = struct {\n" @@ -6454,7 +6442,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " layout: ContainerLayout,\n" " tag_type: type,\n" " fields: []EnumField,\n" - " methods: []Method,\n" + " defs: []Definition,\n" " };\n" "\n" " pub const UnionField = struct {\n" @@ -6467,7 +6455,7 @@ static void define_builtin_compile_vars(CodeGen *g) { " layout: ContainerLayout,\n" " tag_type: type,\n" " fields: []UnionField,\n" - " methods: []Method,\n" + " defs: []Definition,\n" " };\n" "\n" " pub const CallingConvention = enum {\n" @@ -6497,6 +6485,18 @@ static void define_builtin_compile_vars(CodeGen *g) { " pub const Promise = struct {\n" " child: type,\n" " };\n" + "\n" + " pub const Definition = struct {\n" + " name: []const u8,\n" + " is_pub: bool,\n" + " data: Data,\n" + "\n" + " const Data = union(enum) {\n" + " Type: type,\n" + " Var: type,\n" + " Fn: void,\n" + " };\n" + " };\n" "};\n\n"); assert(ContainerLayoutAuto == 0); assert(ContainerLayoutExtern == 1); diff --git a/src/ir.cpp b/src/ir.cpp index c2da83886a..d8da5b3172 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15748,7 +15748,7 @@ static void ensure_field_index(TypeTableEntry *type, const char *field_name, siz (buf_deinit(field_name_buf), true)); } -static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_name) +static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, TypeTableEntry *root = nullptr) { static ConstExprValue *type_info_var = nullptr; static TypeTableEntry *type_info_type = nullptr; @@ -15761,10 +15761,14 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na assert(type_info_type->id == TypeTableEntryIdUnion); } - if (type_name == nullptr) + if (type_name == nullptr && root == nullptr) return type_info_type; + else if (type_name == nullptr) + return root; - ScopeDecls *type_info_scope = get_container_scope(type_info_type); + TypeTableEntry *root_type = (root == nullptr) ? type_info_type : root; + + ScopeDecls *type_info_scope = get_container_scope(root_type); assert(type_info_scope != nullptr); Buf field_name = BUF_INIT; @@ -15782,6 +15786,128 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na return var->value->data.x_type; } +static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, ScopeDecls *decls_scope) +{ + TypeTableEntry *type_info_definition_type = ir_type_info_get_type(ira, "Definition"); + ensure_complete_type(ira->codegen, type_info_definition_type); + ensure_field_index(type_info_definition_type, "name", 0); + ensure_field_index(type_info_definition_type, "is_pub", 1); + ensure_field_index(type_info_definition_type, "data", 2); + + TypeTableEntry *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type); + ensure_complete_type(ira->codegen, type_info_definition_data_type); + + // Loop through our definitions once to figure out how many definitions we will generate info for. + auto decl_it = decls_scope->decl_table.entry_iterator(); + decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; + int definition_count = 0; + + while ((curr_entry = decl_it.next()) != nullptr) + { + // Skip comptime blocks. + if (curr_entry->value->id != TldIdCompTime) + { + definition_count += 1; + } + } + + ConstExprValue *definition_array = create_const_vals(1); + definition_array->special = ConstValSpecialStatic; + definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count); + definition_array->data.x_array.special = ConstArraySpecialNone; + definition_array->data.x_array.s_none.parent.id = ConstParentIdNone; + definition_array->data.x_array.s_none.elements = create_const_vals(definition_count); + init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false); + + // Loop through the definitions and generate info. + decl_it = decls_scope->decl_table.entry_iterator(); + curr_entry = nullptr; + int definition_index = 0; + while ((curr_entry = decl_it.next()) != nullptr) + { + // Skip comptime blocks + if (curr_entry->value->id == TldIdCompTime) + continue; + + ConstExprValue *definition_val = &definition_array->data.x_array.s_none.elements[definition_index]; + + definition_val->special = ConstValSpecialStatic; + definition_val->type = type_info_definition_type; + + ConstExprValue *inner_fields = create_const_vals(3); + ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); + init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true); + inner_fields[1].special = ConstValSpecialStatic; + inner_fields[1].type = ira->codegen->builtin_types.entry_bool; + inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub; + inner_fields[2].special = ConstValSpecialStatic; + inner_fields[2].type = type_info_definition_data_type; + inner_fields[2].data.x_union.parent.id = ConstParentIdStruct; + inner_fields[2].data.x_union.parent.data.p_struct.struct_val = definition_val; + inner_fields[2].data.x_union.parent.data.p_struct.field_index = 1; + + switch (curr_entry->value->id) + { + case TldIdVar: + { + VariableTableEntry *var = ((TldVar *)curr_entry->value)->var; + ensure_complete_type(ira->codegen, var->value->type); + if (var->value->type->id == TypeTableEntryIdMetaType) + { + // We have a variable of type 'type', so it's actually a type definition. + // 0: Data.Type: type + bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); + inner_fields[2].data.x_union.payload = var->value; + } + else + { + // We have a variable of another type, so we store the type of the variable. + // 1: Data.Var: type + bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1); + + ConstExprValue *payload = create_const_vals(1); + payload->type = ira->codegen->builtin_types.entry_type; + payload->data.x_type = var->value->type; + + inner_fields[2].data.x_union.payload = payload; + } + + break; + } + case TldIdFn: + { + // 2: Data.Fn: Data.FnDef + bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); + // @TODO Data.FnDef + inner_fields[2].data.x_union.payload = nullptr; + break; + } + case TldIdContainer: + { + TypeTableEntry *type_entry = ((TldContainer *)curr_entry->value)->type_entry; + ensure_complete_type(ira->codegen, type_entry); + // This is a type. + bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); + + ConstExprValue *payload = create_const_vals(1); + payload->type = ira->codegen->builtin_types.entry_type; + payload->data.x_type = type_entry; + + inner_fields[2].data.x_union.payload = payload; + + break; + } + default: + zig_unreachable(); + } + + definition_val->data.x_struct.fields = inner_fields; + definition_index++; + } + + assert(definition_index == definition_count); +} + static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *type_entry) { assert(type_entry != nullptr); @@ -15791,10 +15917,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t const auto make_enum_field_val = [ira](ConstExprValue *enum_field_val, TypeEnumField *enum_field, TypeTableEntry *type_info_enum_field_type) { - // @TODO Those cause a find_struct_type_field assertion to fail (type_entry->data.structure.complete) - // ensure_field_index(type_info_enum_field_type, "name", 0); - // ensure_field_index(type_info_enum_field_type, "value", 1); - enum_field_val->special = ConstValSpecialStatic; enum_field_val->type = type_info_enum_field_type; @@ -16012,8 +16134,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; enum_field_val->data.x_struct.parent.data.p_array.elem_index = enum_field_index; } + // defs: []TypeInfo.Definition + ensure_field_index(result->type, "defs", 3); + ir_make_type_info_defs(ira, &fields[3], type_entry->data.enumeration.decls_scope); - // @TODO Definitions break; } case TypeTableEntryIdErrorSet: @@ -16165,8 +16289,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t union_field_val->data.x_struct.parent.data.p_array.array_val = union_field_array; union_field_val->data.x_struct.parent.data.p_array.elem_index = union_field_index; } + // defs: []TypeInfo.Definition + ensure_field_index(result->type, "defs", 3); + ir_make_type_info_defs(ira, &fields[3], type_entry->data.unionation.decls_scope); - // @TODO Definitions break; } case TypeTableEntryIdStruct: @@ -16232,7 +16358,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t struct_field_val->data.x_struct.parent.data.p_array.array_val = struct_field_array; struct_field_val->data.x_struct.parent.data.p_array.elem_index = struct_field_index; } - // @TODO Definitions + // defs: []TypeInfo.Definition + ensure_field_index(result->type, "defs", 2); + ir_make_type_info_defs(ira, &fields[2], type_entry->data.structure.decls_scope); + break; } case TypeTableEntryIdFn: @@ -16329,7 +16458,6 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t } case TypeTableEntryIdBoundFn: { - // @TODO figure out memory corruption error. TypeTableEntry *fn_type = type_entry->data.bound_fn.fn_type; assert(fn_type->id == TypeTableEntryIdFn); result = ir_make_type_info_value(ira, fn_type); -- cgit v1.2.3 From 9ba400673d798ea6f0842e4c207039c9faffb27e Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Sat, 28 Apr 2018 18:38:38 +0300 Subject: Generating TypeInfo's now forces definitions to be resolved. --- src/ir.cpp | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index d8da5b3172..6a3b4953c4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15804,9 +15804,26 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop while ((curr_entry = decl_it.next()) != nullptr) { - // Skip comptime blocks. + // If the definition is unresolved, force it to be resolved again. + if (curr_entry->value->resolution == TldResolutionUnresolved) + { + resolve_top_level_decl(ira->codegen, curr_entry->value, false, curr_entry->value->source_node); + if (curr_entry->value->resolution != TldResolutionOk) + { + return; + } + } + + // Skip comptime blocks and test functions. if (curr_entry->value->id != TldIdCompTime) { + if (curr_entry->value->id == TldIdFn) + { + FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; + if (fn_entry->is_test) + continue; + } + definition_count += 1; } } @@ -15825,9 +15842,15 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop int definition_index = 0; while ((curr_entry = decl_it.next()) != nullptr) { - // Skip comptime blocks + // Skip comptime blocks and test functions. if (curr_entry->value->id == TldIdCompTime) continue; + else if (curr_entry->value->id == TldIdFn) + { + FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; + if (fn_entry->is_test) + continue; + } ConstExprValue *definition_val = &definition_array->data.x_array.s_none.elements[definition_index]; @@ -15878,7 +15901,10 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop { // 2: Data.Fn: Data.FnDef bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); - // @TODO Data.FnDef + + FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; + assert(!fn_entry->is_test); + inner_fields[2].data.x_union.payload = nullptr; break; } -- cgit v1.2.3 From af73462da46611ea9293f283ce8a6920ad73b10f Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Sat, 28 Apr 2018 19:57:59 +0300 Subject: Started work on function definition TypeInfo generation. --- src/codegen.cpp | 18 +++++++++++++++++- src/ir.cpp | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index be1d59c26a..414a34d5cb 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6494,7 +6494,19 @@ static void define_builtin_compile_vars(CodeGen *g) { " const Data = union(enum) {\n" " Type: type,\n" " Var: type,\n" - " Fn: void,\n" + " Fn: FnDef,\n" + "\n" + " const FnDef = struct {\n" + " fn_type: type,\n" + " inline_type: Inline,\n" + " calling_convention: CallingConvention,\n" + "\n" + " const Inline = enum {\n" + " Auto,\n" + " Always,\n" + " Never,\n" + " };\n" + " };\n" " };\n" " };\n" "};\n\n"); @@ -6508,6 +6520,10 @@ static void define_builtin_compile_vars(CodeGen *g) { assert(CallingConventionNaked == 3); assert(CallingConventionStdcall == 4); assert(CallingConventionAsync == 5); + + assert(FnInlineAuto == 0); + assert(FnInlineAlways == 1); + assert(FnInlineNever == 2); } { buf_appendf(contents, diff --git a/src/ir.cpp b/src/ir.cpp index 6a3b4953c4..8fadc7f7a3 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15797,6 +15797,12 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop TypeTableEntry *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type); ensure_complete_type(ira->codegen, type_info_definition_data_type); + TypeTableEntry *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type); + ensure_complete_type(ira->codegen, type_info_fn_def_type); + + TypeTableEntry *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type); + ensure_complete_type(ira->codegen, type_info_fn_def_inline_type); + // Loop through our definitions once to figure out how many definitions we will generate info for. auto decl_it = decls_scope->decl_table.entry_iterator(); decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; @@ -15905,7 +15911,35 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; assert(!fn_entry->is_test); - inner_fields[2].data.x_union.payload = nullptr; + AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node); + + ConstExprValue *fn_def_val = create_const_vals(1); + fn_def_val->special = ConstValSpecialStatic; + fn_def_val->type = type_info_fn_def_type; + fn_def_val->data.x_struct.parent.id = ConstParentIdUnion; + fn_def_val->data.x_struct.parent.data.p_union.union_val = &inner_fields[2]; + + // @TODO Add fields + ConstExprValue *fn_def_fields = create_const_vals(3); + fn_def_val->data.x_struct.fields = fn_def_fields; + + // fn_type: type + ensure_field_index(fn_def_val->type, "fn_type", 0); + fn_def_fields[0].special = ConstValSpecialStatic; + fn_def_fields[0].type = ira->codegen->builtin_types.entry_type; + fn_def_fields[0].data.x_type = fn_entry->type_entry; + // inline_type: Data.FnDef.Inline + ensure_field_index(fn_def_val->type, "inline_type", 1); + fn_def_fields[1].special = ConstValSpecialStatic; + fn_def_fields[1].type = type_info_fn_def_inline_type; + bigint_init_unsigned(&fn_def_fields[1].data.x_enum_tag, fn_entry->fn_inline); + // calling_convention: TypeInfo.CallingConvention + ensure_field_index(fn_def_val->type, "calling_convention", 2); + fn_def_fields[2].special = ConstValSpecialStatic; + fn_def_fields[2].type = ir_type_info_get_type(ira, "CallingConvention"); + bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc); + + inner_fields[2].data.x_union.payload = fn_def_val; break; } case TldIdContainer: -- cgit v1.2.3 From 66aa760f83529cf932d35090adfa6fb84264ff7a Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Sun, 29 Apr 2018 14:03:55 +0300 Subject: More FnDef TypeInfo generation. --- src/codegen.cpp | 4 ++++ src/ir.cpp | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 414a34d5cb..507b9afe8b 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6500,6 +6500,10 @@ static void define_builtin_compile_vars(CodeGen *g) { " fn_type: type,\n" " inline_type: Inline,\n" " calling_convention: CallingConvention,\n" + " is_var_args: bool,\n" + " is_extern: bool,\n" + " is_export: bool,\n" + " lib_name: ?[]const u8,\n" "\n" " const Inline = enum {\n" " Auto,\n" diff --git a/src/ir.cpp b/src/ir.cpp index 8fadc7f7a3..e3add4d612 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15920,7 +15920,7 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop fn_def_val->data.x_struct.parent.data.p_union.union_val = &inner_fields[2]; // @TODO Add fields - ConstExprValue *fn_def_fields = create_const_vals(3); + ConstExprValue *fn_def_fields = create_const_vals(7); fn_def_val->data.x_struct.fields = fn_def_fields; // fn_type: type @@ -15938,6 +15938,40 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop fn_def_fields[2].special = ConstValSpecialStatic; fn_def_fields[2].type = ir_type_info_get_type(ira, "CallingConvention"); bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc); + // is_var_args: bool + ensure_field_index(fn_def_val->type, "is_var_args", 3); + fn_def_fields[3].special = ConstValSpecialStatic; + fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool; + fn_def_fields[3].data.x_bool = fn_node->is_var_args; + // is_extern: bool + ensure_field_index(fn_def_val->type, "is_extern", 4); + fn_def_fields[4].special = ConstValSpecialStatic; + fn_def_fields[4].type = ira->codegen->builtin_types.entry_bool; + fn_def_fields[4].data.x_bool = fn_node->is_extern; + // is_export: bool + ensure_field_index(fn_def_val->type, "is_export", 5); + fn_def_fields[5].special = ConstValSpecialStatic; + fn_def_fields[5].type = ira->codegen->builtin_types.entry_bool; + fn_def_fields[5].data.x_bool = fn_node->is_export; + // lib_name: ?[]const u8 + ensure_field_index(fn_def_val->type, "lib_name", 6); + fn_def_fields[6].special = ConstValSpecialStatic; + fn_def_fields[6].type = get_maybe_type(ira->codegen, + get_slice_type(ira->codegen, get_pointer_to_type(ira->codegen, + ira->codegen->builtin_types.entry_u8, true))); + + + if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) + { + fn_def_fields[6].data.x_maybe = create_const_vals(1); + // @TODO Figure out if lib_name is always non-null for extern fns. + ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); + init_const_slice(ira->codegen, fn_def_fields[6].data.x_maybe, lib_name, 0, buf_len(fn_node->lib_name), true); + } + else + { + fn_def_fields[6].data.x_maybe = nullptr; + } inner_fields[2].data.x_union.payload = fn_def_val; break; -- cgit v1.2.3 From 013f548202ae1ffb584c211a0ea2cea53b745583 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Sun, 29 Apr 2018 15:40:26 +0300 Subject: Finished FnDef TypeInfo generation (warning: may be buggy). --- src/codegen.cpp | 8 +++++--- src/ir.cpp | 47 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 45 insertions(+), 10 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 507b9afe8b..db69708e9a 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6491,12 +6491,12 @@ static void define_builtin_compile_vars(CodeGen *g) { " is_pub: bool,\n" " data: Data,\n" "\n" - " const Data = union(enum) {\n" + " pub const Data = union(enum) {\n" " Type: type,\n" " Var: type,\n" " Fn: FnDef,\n" "\n" - " const FnDef = struct {\n" + " pub const FnDef = struct {\n" " fn_type: type,\n" " inline_type: Inline,\n" " calling_convention: CallingConvention,\n" @@ -6504,8 +6504,10 @@ static void define_builtin_compile_vars(CodeGen *g) { " is_extern: bool,\n" " is_export: bool,\n" " lib_name: ?[]const u8,\n" + " return_type: type,\n" + " arg_names: [][] const u8,\n" "\n" - " const Inline = enum {\n" + " pub const Inline = enum {\n" " Auto,\n" " Always,\n" " Never,\n" diff --git a/src/ir.cpp b/src/ir.cpp index e3add4d612..3bce9c51cd 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15911,6 +15911,10 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop FnTableEntry *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; assert(!fn_entry->is_test); + analyze_fn_body(ira->codegen, fn_entry); + if (fn_entry->anal_state == FnAnalStateInvalid) + return; + AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node); ConstExprValue *fn_def_val = create_const_vals(1); @@ -15919,8 +15923,7 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop fn_def_val->data.x_struct.parent.id = ConstParentIdUnion; fn_def_val->data.x_struct.parent.data.p_union.union_val = &inner_fields[2]; - // @TODO Add fields - ConstExprValue *fn_def_fields = create_const_vals(7); + ConstExprValue *fn_def_fields = create_const_vals(9); fn_def_val->data.x_struct.fields = fn_def_fields; // fn_type: type @@ -15940,9 +15943,10 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc); // is_var_args: bool ensure_field_index(fn_def_val->type, "is_var_args", 3); + bool is_varargs = fn_node->is_var_args; fn_def_fields[3].special = ConstValSpecialStatic; fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool; - fn_def_fields[3].data.x_bool = fn_node->is_var_args; + fn_def_fields[3].data.x_bool = is_varargs; // is_extern: bool ensure_field_index(fn_def_val->type, "is_extern", 4); fn_def_fields[4].special = ConstValSpecialStatic; @@ -15959,18 +15963,47 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop fn_def_fields[6].type = get_maybe_type(ira->codegen, get_slice_type(ira->codegen, get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true))); - - if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) { fn_def_fields[6].data.x_maybe = create_const_vals(1); - // @TODO Figure out if lib_name is always non-null for extern fns. ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); init_const_slice(ira->codegen, fn_def_fields[6].data.x_maybe, lib_name, 0, buf_len(fn_node->lib_name), true); } else - { fn_def_fields[6].data.x_maybe = nullptr; + // return_type: type + ensure_field_index(fn_def_val->type, "return_type", 7); + fn_def_fields[7].special = ConstValSpecialStatic; + fn_def_fields[7].type = ira->codegen->builtin_types.entry_type; + // @TODO Check whether this is correct. + if (fn_entry->src_implicit_return_type != nullptr) + fn_def_fields[7].data.x_type = fn_entry->src_implicit_return_type; + else if (fn_entry->type_entry->data.fn.gen_return_type != nullptr) + fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.gen_return_type; + else + fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; + // arg_names: [][] const u8 + ensure_field_index(fn_def_val->type, "arg_names", 8); + size_t fn_arg_count = fn_entry->variable_list.length; + ConstExprValue *fn_arg_name_array = create_const_vals(1); + fn_arg_name_array->special = ConstValSpecialStatic; + fn_arg_name_array->type = get_array_type(ira->codegen, get_slice_type(ira->codegen, + get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true)), fn_arg_count); + fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; + fn_arg_name_array->data.x_array.s_none.parent.id = ConstParentIdNone; + fn_arg_name_array->data.x_array.s_none.elements = create_const_vals(fn_arg_count); + + init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false); + + for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) + { + VariableTableEntry *arg_var = fn_entry->variable_list.at(fn_arg_index); + ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.s_none.elements[fn_arg_index]; + ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name); + init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true); + fn_arg_name_val->data.x_struct.parent.id = ConstParentIdArray; + fn_arg_name_val->data.x_struct.parent.data.p_array.array_val = fn_arg_name_array; + fn_arg_name_val->data.x_struct.parent.data.p_array.elem_index = fn_arg_index; } inner_fields[2].data.x_union.payload = fn_def_val; -- cgit v1.2.3 From ff1c4e1f13943b63dcb6d257a2ee58ae88d4b12a Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 1 May 2018 13:00:39 +0300 Subject: Added tests. --- src/ir.cpp | 1 - test/cases/union.zig | 10 ++++++++++ test/compile_errors.zig | 12 ++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 3bce9c51cd..dfffb41873 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15975,7 +15975,6 @@ static void ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Scop ensure_field_index(fn_def_val->type, "return_type", 7); fn_def_fields[7].special = ConstValSpecialStatic; fn_def_fields[7].type = ira->codegen->builtin_types.entry_type; - // @TODO Check whether this is correct. if (fn_entry->src_implicit_return_type != nullptr) fn_def_fields[7].data.x_type = fn_entry->src_implicit_return_type; else if (fn_entry->type_entry->data.fn.gen_return_type != nullptr) diff --git a/test/cases/union.zig b/test/cases/union.zig index dc2a7c3414..e7d9c23d77 100644 --- a/test/cases/union.zig +++ b/test/cases/union.zig @@ -45,6 +45,16 @@ test "basic unions" { assert(foo.float == 12.34); } +test "comptime union field access" { + comptime { + var foo = Foo { .int = 0 }; + assert(foo.int == 0); + + foo = Foo { .float = 42.42 }; + assert(foo.float == 42.42); + } +} + test "init union with runtime value" { var foo: Foo = undefined; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index f8febc27b8..d9454adf2c 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -3209,4 +3209,16 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { \\} , ".tmp_source.zig:5:42: error: zero-bit field 'val' in struct 'Empty' has no offset"); + + cases.add("invalid union field access in comptime", + \\const Foo = union { + \\ Bar: u8, + \\ Baz: void, + \\}; + \\comptime { + \\ var foo = Foo {.Baz = {}}; + \\ const bar_val = foo.Bar; + \\} + , + ".tmp_source.zig:7:24: error: accessing union field 'Bar' while field 'Baz' is set"); } -- cgit v1.2.3 From 849ea61fa11460b1a6df2529063a6b0cabc6e5e4 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Tue, 1 May 2018 17:10:50 +0300 Subject: Small fix. --- src/ir.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index ff81ebfd86..cffee9bebc 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15765,6 +15765,7 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); assert(type_info_var->type->id == TypeTableEntryIdMetaType); + ensure_complete_type(ira->codegen, type_info_var->data.x_type); type_info_type = type_info_var->data.x_type; assert(type_info_type->id == TypeTableEntryIdUnion); } @@ -15790,6 +15791,7 @@ static TypeTableEntry *ir_type_info_get_type(IrAnalyze *ira, const char *type_na VariableTableEntry *var = tld->var; + ensure_complete_type(ira->codegen, var->value->type); assert(var->value->type->id == TypeTableEntryIdMetaType); return var->value->data.x_type; } -- cgit v1.2.3