One step towards @typeInfo
parent
89a4c373d3
commit
7eab62325b
|
@ -1293,6 +1293,7 @@ enum BuiltinFnId {
|
||||||
BuiltinFnIdMemberType,
|
BuiltinFnIdMemberType,
|
||||||
BuiltinFnIdMemberName,
|
BuiltinFnIdMemberName,
|
||||||
BuiltinFnIdField,
|
BuiltinFnIdField,
|
||||||
|
BuiltinFnIdTypeInfo,
|
||||||
BuiltinFnIdTypeof,
|
BuiltinFnIdTypeof,
|
||||||
BuiltinFnIdAddWithOverflow,
|
BuiltinFnIdAddWithOverflow,
|
||||||
BuiltinFnIdSubWithOverflow,
|
BuiltinFnIdSubWithOverflow,
|
||||||
|
@ -2037,6 +2038,7 @@ enum IrInstructionId {
|
||||||
IrInstructionIdTagType,
|
IrInstructionIdTagType,
|
||||||
IrInstructionIdFieldParentPtr,
|
IrInstructionIdFieldParentPtr,
|
||||||
IrInstructionIdOffsetOf,
|
IrInstructionIdOffsetOf,
|
||||||
|
IrInstructionIdTypeInfo,
|
||||||
IrInstructionIdTypeId,
|
IrInstructionIdTypeId,
|
||||||
IrInstructionIdSetEvalBranchQuota,
|
IrInstructionIdSetEvalBranchQuota,
|
||||||
IrInstructionIdPtrTypeOf,
|
IrInstructionIdPtrTypeOf,
|
||||||
|
@ -2858,6 +2860,12 @@ struct IrInstructionOffsetOf {
|
||||||
IrInstruction *field_name;
|
IrInstruction *field_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct IrInstructionTypeInfo {
|
||||||
|
IrInstruction base;
|
||||||
|
|
||||||
|
IrInstruction *type_value;
|
||||||
|
};
|
||||||
|
|
||||||
struct IrInstructionTypeId {
|
struct IrInstructionTypeId {
|
||||||
IrInstruction base;
|
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 IrInstructionIdDeclRef:
|
||||||
case IrInstructionIdSwitchVar:
|
case IrInstructionIdSwitchVar:
|
||||||
case IrInstructionIdOffsetOf:
|
case IrInstructionIdOffsetOf:
|
||||||
|
case IrInstructionIdTypeInfo:
|
||||||
case IrInstructionIdTypeId:
|
case IrInstructionIdTypeId:
|
||||||
case IrInstructionIdSetEvalBranchQuota:
|
case IrInstructionIdSetEvalBranchQuota:
|
||||||
case IrInstructionIdPtrTypeOf:
|
case IrInstructionIdPtrTypeOf:
|
||||||
|
@ -6125,6 +6126,7 @@ static void define_builtin_fns(CodeGen *g) {
|
||||||
create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
|
create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
|
||||||
create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
|
create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
|
||||||
create_builtin_fn(g, BuiltinFnIdField, "field", 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, BuiltinFnIdTypeof, "typeOf", 1); // TODO rename to TypeOf
|
||||||
create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4);
|
create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4);
|
||||||
create_builtin_fn(g, BuiltinFnIdSubWithOverflow, "subWithOverflow", 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, "};\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,
|
buf_appendf(contents,
|
||||||
"pub const FloatMode = enum {\n"
|
"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;
|
return IrInstructionIdOffsetOf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) {
|
||||||
|
return IrInstructionIdTypeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) {
|
static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) {
|
||||||
return IrInstructionIdTypeId;
|
return IrInstructionIdTypeId;
|
||||||
}
|
}
|
||||||
|
@ -2440,6 +2444,16 @@ static IrInstruction *ir_build_offset_of(IrBuilder *irb, Scope *scope, AstNode *
|
||||||
return &instruction->base;
|
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,
|
static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node,
|
||||||
IrInstruction *type_value)
|
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);
|
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:
|
case BuiltinFnIdBreakpoint:
|
||||||
return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval);
|
return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval);
|
||||||
case BuiltinFnIdReturnAddress:
|
case BuiltinFnIdReturnAddress:
|
||||||
|
@ -15669,6 +15693,26 @@ static TypeTableEntry *ir_analyze_instruction_offset_of(IrAnalyze *ira,
|
||||||
return ira->codegen->builtin_types.entry_num_lit_int;
|
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,
|
static TypeTableEntry *ir_analyze_instruction_type_id(IrAnalyze *ira,
|
||||||
IrInstructionTypeId *instruction)
|
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);
|
return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction);
|
||||||
case IrInstructionIdOffsetOf:
|
case IrInstructionIdOffsetOf:
|
||||||
return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction);
|
return ir_analyze_instruction_offset_of(ira, (IrInstructionOffsetOf *)instruction);
|
||||||
|
case IrInstructionIdTypeInfo:
|
||||||
|
return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction);
|
||||||
case IrInstructionIdTypeId:
|
case IrInstructionIdTypeId:
|
||||||
return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction);
|
return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction);
|
||||||
case IrInstructionIdSetEvalBranchQuota:
|
case IrInstructionIdSetEvalBranchQuota:
|
||||||
|
@ -18821,6 +18867,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
|
||||||
case IrInstructionIdTagName:
|
case IrInstructionIdTagName:
|
||||||
case IrInstructionIdFieldParentPtr:
|
case IrInstructionIdFieldParentPtr:
|
||||||
case IrInstructionIdOffsetOf:
|
case IrInstructionIdOffsetOf:
|
||||||
|
case IrInstructionIdTypeInfo:
|
||||||
case IrInstructionIdTypeId:
|
case IrInstructionIdTypeId:
|
||||||
case IrInstructionIdAlignCast:
|
case IrInstructionIdAlignCast:
|
||||||
case IrInstructionIdOpaqueType:
|
case IrInstructionIdOpaqueType:
|
||||||
|
|
|
@ -966,6 +966,12 @@ static void ir_print_offset_of(IrPrint *irp, IrInstructionOffsetOf *instruction)
|
||||||
fprintf(irp->f, ")");
|
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) {
|
static void ir_print_type_id(IrPrint *irp, IrInstructionTypeId *instruction) {
|
||||||
fprintf(irp->f, "@typeId(");
|
fprintf(irp->f, "@typeId(");
|
||||||
ir_print_other_instruction(irp, instruction->type_value);
|
ir_print_other_instruction(irp, instruction->type_value);
|
||||||
|
@ -1536,6 +1542,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||||
case IrInstructionIdOffsetOf:
|
case IrInstructionIdOffsetOf:
|
||||||
ir_print_offset_of(irp, (IrInstructionOffsetOf *)instruction);
|
ir_print_offset_of(irp, (IrInstructionOffsetOf *)instruction);
|
||||||
break;
|
break;
|
||||||
|
case IrInstructionIdTypeInfo:
|
||||||
|
ir_print_type_info(irp, (IrInstructionTypeInfo *)instruction);
|
||||||
|
break;
|
||||||
case IrInstructionIdTypeId:
|
case IrInstructionIdTypeId:
|
||||||
ir_print_type_id(irp, (IrInstructionTypeId *)instruction);
|
ir_print_type_id(irp, (IrInstructionTypeId *)instruction);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue