From 97ab720d84ac6af5174ed93f371fedfa2331445d Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Wed, 23 Sep 2020 11:49:44 -0600 Subject: [PATCH] stage1: Add alignment to TypeInfo.Fn --- lib/std/builtin.zig | 1 + src/stage1/ir.cpp | 37 +++++++++++++++++------------- test/stage1/behavior/type_info.zig | 6 ++++- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index d80d0e88fe..34452bee09 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -343,6 +343,7 @@ pub const TypeInfo = union(enum) { /// therefore must be kept in sync with the compiler implementation. pub const Fn = struct { calling_convention: CallingConvention, + alignment: u29, is_generic: bool, is_var_args: bool, return_type: ?type, diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 8da207cab7..6d309ef16b 100644 --- a/src/stage1/ir.cpp +++ b/src/stage1/ir.cpp @@ -25564,7 +25564,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy result->special = ConstValSpecialStatic; result->type = ir_type_info_get_type(ira, "Fn", nullptr); - ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5); + ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 6); result->data.x_struct.fields = fields; // calling_convention: TypeInfo.CallingConvention @@ -25572,30 +25572,35 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy fields[0]->special = ConstValSpecialStatic; fields[0]->type = get_builtin_type(ira->codegen, "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; + // alignment: u29 + ensure_field_index(result->type, "alignment", 1); 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[1]->type = ira->codegen->builtin_types.entry_u29; + bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.fn.fn_type_id.alignment); + // is_generic: bool + ensure_field_index(result->type, "is_generic", 2); + bool is_generic = type_entry->data.fn.is_generic; 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[2]->data.x_bool = is_generic; + // is_varargs: bool + ensure_field_index(result->type, "is_var_args", 3); + bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; fields[3]->special = ConstValSpecialStatic; - fields[3]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); + fields[3]->type = ira->codegen->builtin_types.entry_bool; + fields[3]->data.x_bool = is_varargs; + // return_type: ?type + ensure_field_index(result->type, "return_type", 4); + fields[4]->special = ConstValSpecialStatic; + fields[4]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); if (type_entry->data.fn.fn_type_id.return_type == nullptr) - fields[3]->data.x_optional = nullptr; + fields[4]->data.x_optional = nullptr; else { ZigValue *return_type = ira->codegen->pass1_arena->create(); return_type->special = ConstValSpecialStatic; return_type->type = ira->codegen->builtin_types.entry_type; return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; - fields[3]->data.x_optional = return_type; + fields[4]->data.x_optional = return_type; } // args: []TypeInfo.FnArg ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); @@ -25611,7 +25616,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy fn_arg_array->data.x_array.special = ConstArraySpecialNone; fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate(fn_arg_count); - init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false); + 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]; diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index f5b37fe3f0..bb6dede96d 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -273,11 +273,14 @@ test "type info: function type info" { fn testFunction() void { const fn_info = @typeInfo(@TypeOf(foo)); expect(fn_info == .Fn); + expect(fn_info.Fn.alignment == 0); expect(fn_info.Fn.calling_convention == .C); expect(!fn_info.Fn.is_generic); expect(fn_info.Fn.args.len == 2); expect(fn_info.Fn.is_var_args); expect(fn_info.Fn.return_type.? == usize); + const fn_aligned_info = @typeInfo(@TypeOf(fooAligned)); + expect(fn_aligned_info.Fn.alignment == 4); const test_instance: TestStruct = undefined; const bound_fn_info = @typeInfo(@TypeOf(test_instance.foo)); @@ -285,7 +288,8 @@ fn testFunction() void { expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct); } -extern fn foo(a: usize, b: bool, ...) usize; +extern fn foo(a: usize, b: bool, ...) callconv(.C) usize; +extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize; test "typeInfo with comptime parameter in struct fn def" { const S = struct {