Skip to content

Commit b9e320d

Browse files
authored
Merge pull request #951 from alexnask/reflect_reify
Metaprogramming - @typeinfo [DONE]
2 parents aa2586d + 849ea61 commit b9e320d

File tree

9 files changed

+1758
-7
lines changed

9 files changed

+1758
-7
lines changed

doc/langref.html.in

Lines changed: 388 additions & 5 deletions
Large diffs are not rendered by default.

src/all_types.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,7 @@ enum BuiltinFnId {
12931293
BuiltinFnIdMemberType,
12941294
BuiltinFnIdMemberName,
12951295
BuiltinFnIdField,
1296+
BuiltinFnIdTypeInfo,
12961297
BuiltinFnIdTypeof,
12971298
BuiltinFnIdAddWithOverflow,
12981299
BuiltinFnIdSubWithOverflow,
@@ -1506,6 +1507,7 @@ struct CodeGen {
15061507
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names;
15071508
HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
15081509
HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> string_literals_table;
1510+
HashMap<const TypeTableEntry *, ConstExprValue *, type_ptr_hash, type_ptr_eql> type_info_cache;
15091511

15101512

15111513
ZigList<ImportTableEntry *> import_queue;
@@ -2037,6 +2039,7 @@ enum IrInstructionId {
20372039
IrInstructionIdTagType,
20382040
IrInstructionIdFieldParentPtr,
20392041
IrInstructionIdOffsetOf,
2042+
IrInstructionIdTypeInfo,
20402043
IrInstructionIdTypeId,
20412044
IrInstructionIdSetEvalBranchQuota,
20422045
IrInstructionIdPtrTypeOf,
@@ -2858,6 +2861,12 @@ struct IrInstructionOffsetOf {
28582861
IrInstruction *field_name;
28592862
};
28602863

2864+
struct IrInstructionTypeInfo {
2865+
IrInstruction base;
2866+
2867+
IrInstruction *type_value;
2868+
};
2869+
28612870
struct IrInstructionTypeId {
28622871
IrInstruction base;
28632872

src/codegen.cpp

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
8888
g->exported_symbol_names.init(8);
8989
g->external_prototypes.init(8);
9090
g->string_literals_table.init(16);
91+
g->type_info_cache.init(32);
9192
g->is_test_build = false;
9293
g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);
9394
buf_resize(&g->global_asm, 0);
@@ -4502,6 +4503,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
45024503
case IrInstructionIdDeclRef:
45034504
case IrInstructionIdSwitchVar:
45044505
case IrInstructionIdOffsetOf:
4506+
case IrInstructionIdTypeInfo:
45054507
case IrInstructionIdTypeId:
45064508
case IrInstructionIdSetEvalBranchQuota:
45074509
case IrInstructionIdPtrTypeOf:
@@ -6125,6 +6127,7 @@ static void define_builtin_fns(CodeGen *g) {
61256127
create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
61266128
create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
61276129
create_builtin_fn(g, BuiltinFnIdField, "field", 2);
6130+
create_builtin_fn(g, BuiltinFnIdTypeInfo, "typeInfo", 1);
61286131
create_builtin_fn(g, BuiltinFnIdTypeof, "typeOf", 1); // TODO rename to TypeOf
61296132
create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4);
61306133
create_builtin_fn(g, BuiltinFnIdSubWithOverflow, "subWithOverflow", 4);
@@ -6344,6 +6347,190 @@ static void define_builtin_compile_vars(CodeGen *g) {
63446347
}
63456348
buf_appendf(contents, "};\n\n");
63466349
}
6350+
{
6351+
buf_appendf(contents,
6352+
"pub const TypeInfo = union(TypeId) {\n"
6353+
" Type: void,\n"
6354+
" Void: void,\n"
6355+
" Bool: void,\n"
6356+
" NoReturn: void,\n"
6357+
" Int: Int,\n"
6358+
" Float: Float,\n"
6359+
" Pointer: Pointer,\n"
6360+
" Array: Array,\n"
6361+
" Struct: Struct,\n"
6362+
" FloatLiteral: void,\n"
6363+
" IntLiteral: void,\n"
6364+
" UndefinedLiteral: void,\n"
6365+
" NullLiteral: void,\n"
6366+
" Nullable: Nullable,\n"
6367+
" ErrorUnion: ErrorUnion,\n"
6368+
" ErrorSet: ErrorSet,\n"
6369+
" Enum: Enum,\n"
6370+
" Union: Union,\n"
6371+
" Fn: Fn,\n"
6372+
" Namespace: void,\n"
6373+
" Block: void,\n"
6374+
" BoundFn: Fn,\n"
6375+
" ArgTuple: void,\n"
6376+
" Opaque: void,\n"
6377+
" Promise: Promise,\n"
6378+
"\n\n"
6379+
" pub const Int = struct {\n"
6380+
" is_signed: bool,\n"
6381+
" bits: u8,\n"
6382+
" };\n"
6383+
"\n"
6384+
" pub const Float = struct {\n"
6385+
" bits: u8,\n"
6386+
" };\n"
6387+
"\n"
6388+
" pub const Pointer = struct {\n"
6389+
" is_const: bool,\n"
6390+
" is_volatile: bool,\n"
6391+
" alignment: u32,\n"
6392+
" child: type,\n"
6393+
" };\n"
6394+
"\n"
6395+
" pub const Array = struct {\n"
6396+
" len: usize,\n"
6397+
" child: type,\n"
6398+
" };\n"
6399+
"\n"
6400+
" pub const ContainerLayout = enum {\n"
6401+
" Auto,\n"
6402+
" Extern,\n"
6403+
" Packed,\n"
6404+
" };\n"
6405+
"\n"
6406+
" pub const StructField = struct {\n"
6407+
" name: []const u8,\n"
6408+
" offset: ?usize,\n"
6409+
" field_type: type,\n"
6410+
" };\n"
6411+
"\n"
6412+
" pub const Struct = struct {\n"
6413+
" layout: ContainerLayout,\n"
6414+
" fields: []StructField,\n"
6415+
" defs: []Definition,\n"
6416+
" };\n"
6417+
"\n"
6418+
" pub const Nullable = struct {\n"
6419+
" child: type,\n"
6420+
" };\n"
6421+
"\n"
6422+
" pub const ErrorUnion = struct {\n"
6423+
" error_set: type,\n"
6424+
" payload: type,\n"
6425+
" };\n"
6426+
"\n"
6427+
" pub const Error = struct {\n"
6428+
" name: []const u8,\n"
6429+
" value: usize,\n"
6430+
" };\n"
6431+
"\n"
6432+
" pub const ErrorSet = struct {\n"
6433+
" errors: []Error,\n"
6434+
" };\n"
6435+
"\n"
6436+
" pub const EnumField = struct {\n"
6437+
" name: []const u8,\n"
6438+
" value: usize,\n"
6439+
" };\n"
6440+
"\n"
6441+
" pub const Enum = struct {\n"
6442+
" layout: ContainerLayout,\n"
6443+
" tag_type: type,\n"
6444+
" fields: []EnumField,\n"
6445+
" defs: []Definition,\n"
6446+
" };\n"
6447+
"\n"
6448+
" pub const UnionField = struct {\n"
6449+
" name: []const u8,\n"
6450+
" enum_field: ?EnumField,\n"
6451+
" field_type: type,\n"
6452+
" };\n"
6453+
"\n"
6454+
" pub const Union = struct {\n"
6455+
" layout: ContainerLayout,\n"
6456+
" tag_type: type,\n"
6457+
" fields: []UnionField,\n"
6458+
" defs: []Definition,\n"
6459+
" };\n"
6460+
"\n"
6461+
" pub const CallingConvention = enum {\n"
6462+
" Unspecified,\n"
6463+
" C,\n"
6464+
" Cold,\n"
6465+
" Naked,\n"
6466+
" Stdcall,\n"
6467+
" Async,\n"
6468+
" };\n"
6469+
"\n"
6470+
" pub const FnArg = struct {\n"
6471+
" is_generic: bool,\n"
6472+
" is_noalias: bool,\n"
6473+
" arg_type: type,\n"
6474+
" };\n"
6475+
"\n"
6476+
" pub const Fn = struct {\n"
6477+
" calling_convention: CallingConvention,\n"
6478+
" is_generic: bool,\n"
6479+
" is_var_args: bool,\n"
6480+
" return_type: type,\n"
6481+
" async_allocator_type: type,\n"
6482+
" args: []FnArg,\n"
6483+
" };\n"
6484+
"\n"
6485+
" pub const Promise = struct {\n"
6486+
" child: type,\n"
6487+
" };\n"
6488+
"\n"
6489+
" pub const Definition = struct {\n"
6490+
" name: []const u8,\n"
6491+
" is_pub: bool,\n"
6492+
" data: Data,\n"
6493+
"\n"
6494+
" pub const Data = union(enum) {\n"
6495+
" Type: type,\n"
6496+
" Var: type,\n"
6497+
" Fn: FnDef,\n"
6498+
"\n"
6499+
" pub const FnDef = struct {\n"
6500+
" fn_type: type,\n"
6501+
" inline_type: Inline,\n"
6502+
" calling_convention: CallingConvention,\n"
6503+
" is_var_args: bool,\n"
6504+
" is_extern: bool,\n"
6505+
" is_export: bool,\n"
6506+
" lib_name: ?[]const u8,\n"
6507+
" return_type: type,\n"
6508+
" arg_names: [][] const u8,\n"
6509+
"\n"
6510+
" pub const Inline = enum {\n"
6511+
" Auto,\n"
6512+
" Always,\n"
6513+
" Never,\n"
6514+
" };\n"
6515+
" };\n"
6516+
" };\n"
6517+
" };\n"
6518+
"};\n\n");
6519+
assert(ContainerLayoutAuto == 0);
6520+
assert(ContainerLayoutExtern == 1);
6521+
assert(ContainerLayoutPacked == 2);
6522+
6523+
assert(CallingConventionUnspecified == 0);
6524+
assert(CallingConventionC == 1);
6525+
assert(CallingConventionCold == 2);
6526+
assert(CallingConventionNaked == 3);
6527+
assert(CallingConventionStdcall == 4);
6528+
assert(CallingConventionAsync == 5);
6529+
6530+
assert(FnInlineAuto == 0);
6531+
assert(FnInlineAlways == 1);
6532+
assert(FnInlineNever == 2);
6533+
}
63476534
{
63486535
buf_appendf(contents,
63496536
"pub const FloatMode = enum {\n"

0 commit comments

Comments
 (0)