One step towards @typeInfo
parent
89a4c373d3
commit
7eab62325b
|
@ -1293,6 +1293,7 @@ enum BuiltinFnId {
|
|||
BuiltinFnIdMemberType,
|
||||
BuiltinFnIdMemberName,
|
||||
BuiltinFnIdField,
|
||||
BuiltinFnIdTypeInfo,
|
||||
BuiltinFnIdTypeof,
|
||||
BuiltinFnIdAddWithOverflow,
|
||||
BuiltinFnIdSubWithOverflow,
|
||||
|
@ -2037,6 +2038,7 @@ enum IrInstructionId {
|
|||
IrInstructionIdTagType,
|
||||
IrInstructionIdFieldParentPtr,
|
||||
IrInstructionIdOffsetOf,
|
||||
IrInstructionIdTypeInfo,
|
||||
IrInstructionIdTypeId,
|
||||
IrInstructionIdSetEvalBranchQuota,
|
||||
IrInstructionIdPtrTypeOf,
|
||||
|
@ -2858,6 +2860,12 @@ struct IrInstructionOffsetOf {
|
|||
IrInstruction *field_name;
|
||||
};
|
||||
|
||||
struct IrInstructionTypeInfo {
|
||||
IrInstruction base;
|
||||
|
||||
IrInstruction *type_value;
|
||||
};
|
||||
|
||||
struct IrInstructionTypeId {
|
||||
IrInstruction base;
|
||||
|
||||
|
|
153
src/codegen.cpp
153
src/codegen.cpp
|
@ -4502,6 +4502,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
|||
case IrInstructionIdDeclRef:
|
||||
case IrInstructionIdSwitchVar:
|
||||
case IrInstructionIdOffsetOf:
|
||||
case IrInstructionIdTypeInfo:
|
||||
case IrInstructionIdTypeId:
|
||||
case IrInstructionIdSetEvalBranchQuota:
|
||||
case IrInstructionIdPtrTypeOf:
|
||||
|
@ -6125,6 +6126,7 @@ static void define_builtin_fns(CodeGen *g) {
|
|||
create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
|
||||
create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
|
||||
create_builtin_fn(g, BuiltinFnIdField, "field", 2);
|
||||
create_builtin_fn(g, BuiltinFnIdTypeInfo, "typeInfo", 1);
|
||||
create_builtin_fn(g, BuiltinFnIdTypeof, "typeOf", 1); // TODO rename to TypeOf
|
||||
create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4);
|
||||
create_builtin_fn(g, BuiltinFnIdSubWithOverflow, "subWithOverflow", 4);
|
||||
|
@ -6344,6 +6346,157 @@ static void define_builtin_compile_vars(CodeGen *g) {
|
|||
}
|
||||
buf_appendf(contents, "};\n\n");
|
||||
}
|
||||
{
|
||||
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"
|
||||
"\n"
|
||||
"pub const PointerInfo = struct {\n"
|
||||
" is_const: bool,\n"
|
||||
" is_volatile: bool,\n"
|
||||
" alignment: u32,\n"
|
||||
" child: &TypeInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const ArrayInfo = struct {\n"
|
||||
" len: u64,\n"
|
||||
" child: &TypeInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const ContainerLayout = enum {\n"
|
||||
" Auto,\n"
|
||||
" Extern,\n"
|
||||
" Packed,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const StructFieldInfo = struct {\n"
|
||||
" name: []const u8,\n"
|
||||
" offset: usize,\n"
|
||||
" type_info: TypeInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const StructInfo = struct {\n"
|
||||
" layout: ContainerLayout,\n"
|
||||
" fields: []StructFieldInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const NullableInfo = struct {\n"
|
||||
" child: &TypeInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const ErrorUnionInfo = struct {\n"
|
||||
" error_set: ErrorSetInfo,\n"
|
||||
" payload: &TypeInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const ErrorInfo = struct {\n"
|
||||
" name: []const u8,\n"
|
||||
" value: usize,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const ErrorSetInfo = struct {\n"
|
||||
" errors: []ErrorInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const EnumFieldInfo = struct {\n"
|
||||
" name: []const u8,\n"
|
||||
" value: usize,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const EnumInfo = struct {\n"
|
||||
" layout: ContainerLayout,\n"
|
||||
" tag_type: IntInfo,\n"
|
||||
" fields: []EnumFieldInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const UnionFieldInfo = struct {\n"
|
||||
" name: []const u8,\n"
|
||||
" enum_field: EnumFieldInfo,\n"
|
||||
" type_info: TypeInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const UnionInfo = struct {\n"
|
||||
" layout: ContainerLayout,\n"
|
||||
" tag_type: ?EnumInfo,\n"
|
||||
" fields: []UnionFieldInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const CallingConvention = enum {\n"
|
||||
" Unspecified,\n"
|
||||
" C,\n"
|
||||
" Cold,\n"
|
||||
" Naked,\n"
|
||||
" Stdcall,\n"
|
||||
" Async,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const FnArgInfo = struct {\n"
|
||||
" is_comptime: bool,\n"
|
||||
" name: []const u8,\n"
|
||||
" type_info: TypeInfo,\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"
|
||||
"\n"
|
||||
"pub const BoundFnInfo = struct {\n"
|
||||
" bound_type: &TypeInfo,\n"
|
||||
" fn_info: FnInfo,\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"pub const PromiseInfo = struct {\n"
|
||||
" child: ?&TypeInfo,\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"
|
||||
"};\n\n");
|
||||
assert(ContainerLayoutAuto == 0);
|
||||
assert(ContainerLayoutExtern == 1);
|
||||
assert(ContainerLayoutPacked == 2);
|
||||
|
||||
assert(CallingConventionUnspecified == 0);
|
||||
assert(CallingConventionC == 1);
|
||||
assert(CallingConventionCold == 2);
|
||||
assert(CallingConventionNaked == 3);
|
||||
assert(CallingConventionStdcall == 4);
|
||||
assert(CallingConventionAsync == 5);
|
||||
}
|
||||
{
|
||||
buf_appendf(contents,
|
||||
"pub const FloatMode = enum {\n"
|
||||
|
|
47
src/ir.cpp
47
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<IrInstructionTypeInfo>(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:
|
||||
|
|
|
@ -966,6 +966,12 @@ static void ir_print_offset_of(IrPrint *irp, IrInstructionOffsetOf *instruction)
|
|||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_type_info(IrPrint *irp, IrInstructionTypeInfo *instruction) {
|
||||
fprintf(irp->f, "@typeInfo(");
|
||||
ir_print_other_instruction(irp, instruction->type_value);
|
||||
fprintf(irp->f, ")");
|
||||
}
|
||||
|
||||
static void ir_print_type_id(IrPrint *irp, IrInstructionTypeId *instruction) {
|
||||
fprintf(irp->f, "@typeId(");
|
||||
ir_print_other_instruction(irp, instruction->type_value);
|
||||
|
@ -1536,6 +1542,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
|||
case IrInstructionIdOffsetOf:
|
||||
ir_print_offset_of(irp, (IrInstructionOffsetOf *)instruction);
|
||||
break;
|
||||
case IrInstructionIdTypeInfo:
|
||||
ir_print_type_info(irp, (IrInstructionTypeInfo *)instruction);
|
||||
break;
|
||||
case IrInstructionIdTypeId:
|
||||
ir_print_type_id(irp, (IrInstructionTypeId *)instruction);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue