ir: emit zir for fntype
This commit is contained in:
parent
993e654554
commit
b1a86040dd
@ -880,7 +880,20 @@ const EmitZIR = struct {
|
||||
break :blk &unreach_inst.base;
|
||||
},
|
||||
.constant => unreachable, // excluded from function bodies
|
||||
.assembly => @panic("TODO emit zir asm instruction"),
|
||||
.assembly => blk: {
|
||||
const old_inst = inst.cast(ir.Inst.Assembly).?;
|
||||
const new_inst = try self.arena.allocator.create(Inst.Asm);
|
||||
new_inst.* = .{
|
||||
.base = .{ .src = inst.src, .tag = Inst.Asm.base_tag },
|
||||
.positionals = .{
|
||||
.asm_source = try self.emitStringLiteral(inst.src, old_inst.args.asm_source),
|
||||
.return_type = try self.emitType(inst.src, inst.ty),
|
||||
},
|
||||
// TODO emit more kw_args
|
||||
.kw_args = .{},
|
||||
};
|
||||
break :blk &new_inst.base;
|
||||
},
|
||||
.ptrtoint => blk: {
|
||||
const old_inst = inst.cast(ir.Inst.PtrToInt).?;
|
||||
const new_inst = try self.arena.allocator.create(Inst.PtrToInt);
|
||||
@ -918,7 +931,7 @@ const EmitZIR = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn emitType(self: *EmitZIR, src: usize, ty: Type) !*Inst {
|
||||
pub fn emitType(self: *EmitZIR, src: usize, ty: Type) Allocator.Error!*Inst {
|
||||
switch (ty.tag()) {
|
||||
.isize => return self.emitPrimitiveType(src, .isize),
|
||||
.usize => return self.emitPrimitiveType(src, .usize),
|
||||
@ -944,6 +957,30 @@ const EmitZIR = struct {
|
||||
.Type => return self.emitPrimitiveType(src, .type),
|
||||
.ComptimeInt => return self.emitPrimitiveType(src, .comptime_int),
|
||||
.ComptimeFloat => return self.emitPrimitiveType(src, .comptime_float),
|
||||
.Fn => {
|
||||
const param_types = try self.allocator.alloc(Type, ty.fnParamLen());
|
||||
defer self.allocator.free(param_types);
|
||||
|
||||
ty.fnParamTypes(param_types);
|
||||
const emitted_params = try self.arena.allocator.alloc(*Inst, param_types.len);
|
||||
for (param_types) |param_type, i| {
|
||||
emitted_params[i] = try self.emitType(src, param_type);
|
||||
}
|
||||
|
||||
const fntype_inst = try self.arena.allocator.create(Inst.FnType);
|
||||
fntype_inst.* = .{
|
||||
.base = .{ .src = src, .tag = Inst.FnType.base_tag },
|
||||
.positionals = .{
|
||||
.param_types = emitted_params,
|
||||
.return_type = try self.emitType(src, ty.fnReturnType()),
|
||||
},
|
||||
.kw_args = .{
|
||||
.cc = ty.fnCallingConvention(),
|
||||
},
|
||||
};
|
||||
try self.decls.append(&fntype_inst.base);
|
||||
return &fntype_inst.base;
|
||||
},
|
||||
else => std.debug.panic("TODO implement emitType for {}", .{ty}),
|
||||
},
|
||||
}
|
||||
|
@ -422,6 +422,163 @@ pub const Type = extern union {
|
||||
};
|
||||
}
|
||||
|
||||
/// Asserts the type is a function.
|
||||
pub fn fnParamLen(self: Type) usize {
|
||||
return switch (self.tag()) {
|
||||
.fn_naked_noreturn_no_args => 0,
|
||||
|
||||
.f16,
|
||||
.f32,
|
||||
.f64,
|
||||
.f128,
|
||||
.c_longdouble,
|
||||
.c_void,
|
||||
.bool,
|
||||
.void,
|
||||
.type,
|
||||
.anyerror,
|
||||
.comptime_int,
|
||||
.comptime_float,
|
||||
.noreturn,
|
||||
.array,
|
||||
.single_const_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
.usize,
|
||||
.isize,
|
||||
.c_short,
|
||||
.c_ushort,
|
||||
.c_int,
|
||||
.c_uint,
|
||||
.c_long,
|
||||
.c_ulong,
|
||||
.c_longlong,
|
||||
.c_ulonglong,
|
||||
=> unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
/// Asserts the type is a function. The length of the slice must be at least the length
|
||||
/// given by `fnParamLen`.
|
||||
pub fn fnParamTypes(self: Type, types: []Type) void {
|
||||
switch (self.tag()) {
|
||||
.fn_naked_noreturn_no_args => return,
|
||||
|
||||
.f16,
|
||||
.f32,
|
||||
.f64,
|
||||
.f128,
|
||||
.c_longdouble,
|
||||
.c_void,
|
||||
.bool,
|
||||
.void,
|
||||
.type,
|
||||
.anyerror,
|
||||
.comptime_int,
|
||||
.comptime_float,
|
||||
.noreturn,
|
||||
.array,
|
||||
.single_const_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
.usize,
|
||||
.isize,
|
||||
.c_short,
|
||||
.c_ushort,
|
||||
.c_int,
|
||||
.c_uint,
|
||||
.c_long,
|
||||
.c_ulong,
|
||||
.c_longlong,
|
||||
.c_ulonglong,
|
||||
=> unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
/// Asserts the type is a function.
|
||||
pub fn fnReturnType(self: Type) Type {
|
||||
return switch (self.tag()) {
|
||||
.fn_naked_noreturn_no_args => Type.initTag(.noreturn),
|
||||
|
||||
.f16,
|
||||
.f32,
|
||||
.f64,
|
||||
.f128,
|
||||
.c_longdouble,
|
||||
.c_void,
|
||||
.bool,
|
||||
.void,
|
||||
.type,
|
||||
.anyerror,
|
||||
.comptime_int,
|
||||
.comptime_float,
|
||||
.noreturn,
|
||||
.array,
|
||||
.single_const_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
.usize,
|
||||
.isize,
|
||||
.c_short,
|
||||
.c_ushort,
|
||||
.c_int,
|
||||
.c_uint,
|
||||
.c_long,
|
||||
.c_ulong,
|
||||
.c_longlong,
|
||||
.c_ulonglong,
|
||||
=> unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
/// Asserts the type is a function.
|
||||
pub fn fnCallingConvention(self: Type) std.builtin.CallingConvention {
|
||||
return switch (self.tag()) {
|
||||
.fn_naked_noreturn_no_args => .Naked,
|
||||
|
||||
.f16,
|
||||
.f32,
|
||||
.f64,
|
||||
.f128,
|
||||
.c_longdouble,
|
||||
.c_void,
|
||||
.bool,
|
||||
.void,
|
||||
.type,
|
||||
.anyerror,
|
||||
.comptime_int,
|
||||
.comptime_float,
|
||||
.noreturn,
|
||||
.array,
|
||||
.single_const_pointer,
|
||||
.single_const_pointer_to_comptime_int,
|
||||
.array_u8_sentinel_0,
|
||||
.const_slice_u8,
|
||||
.u8,
|
||||
.i8,
|
||||
.usize,
|
||||
.isize,
|
||||
.c_short,
|
||||
.c_ushort,
|
||||
.c_int,
|
||||
.c_uint,
|
||||
.c_long,
|
||||
.c_ulong,
|
||||
.c_longlong,
|
||||
.c_ulonglong,
|
||||
=> unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
/// This enum does not directly correspond to `std.builtin.TypeId` because
|
||||
/// it has extra enum tags in it, as a way of using less memory. For example,
|
||||
/// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types
|
||||
|
Loading…
x
Reference in New Issue
Block a user