Skip to content

Metaprogramming - @typeInfo [DONE] #951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
May 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
7eab623
One step towards @typeInfo
alexnask Apr 23, 2018
fb88f5a
@typeInfo with void payloads now works!
alexnask Apr 24, 2018
ec2a3ed
Attempt at adding comptime union field access
alexnask Apr 24, 2018
e9309d3
Fixed IntInfo generation.
alexnask Apr 24, 2018
0e5fb03
Added (broken) pointer info, float info
alexnask Apr 24, 2018
189e8e9
PointerInfo child is a pointer to a TypeInfo union, still not working…
alexnask Apr 24, 2018
2d8553c
Fixed PointerInfo generation
alexnask Apr 24, 2018
09d7033
PointerInfo child is known at comptime
alexnask Apr 24, 2018
182a9fa
Added ArrayInfo, NullableInfo, PromiseInfo generation
alexnask Apr 24, 2018
778b931
Fixed comptime union void field access
alexnask Apr 24, 2018
d68aea4
Added checks for field name/index mapping in TypeInfo generation. Abs…
alexnask Apr 25, 2018
2606993
Fixed ir_type_info_struct_set_parent for struct parents.
alexnask Apr 25, 2018
bc16082
Changed TypeInfo layout.
alexnask Apr 25, 2018
dd88d7d
Cleanup
alexnask Apr 26, 2018
bb56360
Added TypeInfo cache
alexnask Apr 26, 2018
7a91e47
Reset parent on cached TypeInfo values if we need to.
alexnask Apr 26, 2018
f5977f6
Added Enum TypeInfo except for methods
alexnask Apr 26, 2018
4aa5d87
Added ErrorSet TypeInfo generation.
alexnask Apr 26, 2018
fbbbee6
Switched to shallow TypeInfo.
alexnask Apr 26, 2018
884e32d
Added ErrorUnion, Union TypeInfo generation
alexnask Apr 26, 2018
9041d0d
Fixed enum tag type detection in TypeInfo generation.
alexnask Apr 26, 2018
a2dadbc
Added struct TypeInfo generation.
alexnask Apr 26, 2018
8f703f9
Added Fn TypeInfo generation.
alexnask Apr 27, 2018
ea25962
Added BoundFn TypeInfo generation.
alexnask Apr 27, 2018
61b0180
Added definition TypeInfo generation, except for function definitions.
alexnask Apr 28, 2018
9ba4006
Generating TypeInfo's now forces definitions to be resolved.
alexnask Apr 28, 2018
af73462
Started work on function definition TypeInfo generation.
alexnask Apr 28, 2018
66aa760
More FnDef TypeInfo generation.
alexnask Apr 29, 2018
013f548
Finished FnDef TypeInfo generation (warning: may be buggy).
alexnask Apr 29, 2018
ff1c4e1
Added tests.
alexnask May 1, 2018
e1535ee
Added typeInfo tests
alexnask May 1, 2018
255c0ef
Resolved merge conflict.
alexnask May 1, 2018
1b6e973
Added type info tests to behavior test listing
alexnask May 1, 2018
7d23941
Fixed type info test, added documentation.
alexnask May 1, 2018
5794083
Added typeInfo to langref built_ins
alexnask May 1, 2018
849ea61
Small fix.
alexnask May 1, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
393 changes: 388 additions & 5 deletions doc/langref.html.in

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/all_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,7 @@ enum BuiltinFnId {
BuiltinFnIdMemberType,
BuiltinFnIdMemberName,
BuiltinFnIdField,
BuiltinFnIdTypeInfo,
BuiltinFnIdTypeof,
BuiltinFnIdAddWithOverflow,
BuiltinFnIdSubWithOverflow,
Expand Down Expand Up @@ -1506,6 +1507,7 @@ struct CodeGen {
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names;
HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> string_literals_table;
HashMap<const TypeTableEntry *, ConstExprValue *, type_ptr_hash, type_ptr_eql> type_info_cache;


ZigList<ImportTableEntry *> import_queue;
Expand Down Expand Up @@ -2037,6 +2039,7 @@ enum IrInstructionId {
IrInstructionIdTagType,
IrInstructionIdFieldParentPtr,
IrInstructionIdOffsetOf,
IrInstructionIdTypeInfo,
IrInstructionIdTypeId,
IrInstructionIdSetEvalBranchQuota,
IrInstructionIdPtrTypeOf,
Expand Down Expand Up @@ -2858,6 +2861,12 @@ struct IrInstructionOffsetOf {
IrInstruction *field_name;
};

struct IrInstructionTypeInfo {
IrInstruction base;

IrInstruction *type_value;
};

struct IrInstructionTypeId {
IrInstruction base;

Expand Down
187 changes: 187 additions & 0 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -4502,6 +4503,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdDeclRef:
case IrInstructionIdSwitchVar:
case IrInstructionIdOffsetOf:
case IrInstructionIdTypeInfo:
case IrInstructionIdTypeId:
case IrInstructionIdSetEvalBranchQuota:
case IrInstructionIdPtrTypeOf:
Expand Down Expand Up @@ -6125,6 +6127,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);
Expand Down Expand Up @@ -6344,6 +6347,190 @@ static void define_builtin_compile_vars(CodeGen *g) {
}
buf_appendf(contents, "};\n\n");
}
{
buf_appendf(contents,
"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: Fn,\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 Float = struct {\n"
" bits: u8,\n"
" };\n"
"\n"
" pub const Pointer = struct {\n"
" is_const: bool,\n"
" is_volatile: bool,\n"
" alignment: u32,\n"
" child: type,\n"
" };\n"
"\n"
" pub const Array = struct {\n"
" len: usize,\n"
" child: type,\n"
" };\n"
"\n"
" pub const ContainerLayout = enum {\n"
" Auto,\n"
" Extern,\n"
" Packed,\n"
" };\n"
"\n"
" pub const StructField = struct {\n"
" name: []const u8,\n"
" offset: ?usize,\n"
" field_type: type,\n"
" };\n"
"\n"
" pub const Struct = struct {\n"
" layout: ContainerLayout,\n"
" fields: []StructField,\n"
" defs: []Definition,\n"
" };\n"
"\n"
" pub const Nullable = struct {\n"
" child: type,\n"
" };\n"
"\n"
" pub const ErrorUnion = struct {\n"
" error_set: type,\n"
" payload: type,\n"
" };\n"
"\n"
" pub const Error = struct {\n"
" name: []const u8,\n"
" value: usize,\n"
" };\n"
"\n"
" pub const ErrorSet = struct {\n"
" errors: []Error,\n"
" };\n"
"\n"
" pub const EnumField = struct {\n"
" name: []const u8,\n"
" value: usize,\n"
" };\n"
"\n"
" pub const Enum = struct {\n"
" layout: ContainerLayout,\n"
" tag_type: type,\n"
" fields: []EnumField,\n"
" defs: []Definition,\n"
" };\n"
"\n"
" pub const UnionField = struct {\n"
" name: []const u8,\n"
" enum_field: ?EnumField,\n"
" field_type: type,\n"
" };\n"
"\n"
" pub const Union = struct {\n"
" layout: ContainerLayout,\n"
" tag_type: type,\n"
" fields: []UnionField,\n"
" defs: []Definition,\n"
" };\n"
"\n"
" pub const CallingConvention = enum {\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good as is, but just a note, this is going to become a top level export of builtin.zig after #661

" Unspecified,\n"
" C,\n"
" Cold,\n"
" Naked,\n"
" Stdcall,\n"
" Async,\n"
" };\n"
"\n"
" pub const FnArg = struct {\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_var_args: bool,\n"
" return_type: type,\n"
" async_allocator_type: type,\n"
" args: []FnArg,\n"
" };\n"
"\n"
" 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"
" pub const Data = union(enum) {\n"
" Type: type,\n"
" Var: type,\n"
" Fn: FnDef,\n"
"\n"
" pub const FnDef = struct {\n"
" 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"
" return_type: type,\n"
" arg_names: [][] const u8,\n"
"\n"
" pub const Inline = enum {\n"
" Auto,\n"
" Always,\n"
" Never,\n"
" };\n"
" };\n"
" };\n"
" };\n"
"};\n\n");
assert(ContainerLayoutAuto == 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these asserts are appreciated, and will for sure prevent bugs in the future 👍

assert(ContainerLayoutExtern == 1);
assert(ContainerLayoutPacked == 2);

assert(CallingConventionUnspecified == 0);
assert(CallingConventionC == 1);
assert(CallingConventionCold == 2);
assert(CallingConventionNaked == 3);
assert(CallingConventionStdcall == 4);
assert(CallingConventionAsync == 5);

assert(FnInlineAuto == 0);
assert(FnInlineAlways == 1);
assert(FnInlineNever == 2);
}
{
buf_appendf(contents,
"pub const FloatMode = enum {\n"
Expand Down
Loading