diff options
| -rw-r--r-- | src/Module.zig | 35 | ||||
| -rw-r--r-- | src/type.zig | 4 | ||||
| -rw-r--r-- | src/zir.zig | 9 | ||||
| -rw-r--r-- | src/zir_sema.zig | 32 |
4 files changed, 38 insertions, 42 deletions
diff --git a/src/Module.zig b/src/Module.zig index a90998a386..322f190673 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1087,14 +1087,23 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { if (fn_proto.getSectionExpr()) |sect_expr| { return self.failNode(&fn_type_scope.base, sect_expr, "TODO implement function section expression", .{}); } - if (fn_proto.getCallconvExpr()) |callconv_expr| { - return self.failNode( - &fn_type_scope.base, - callconv_expr, - "TODO implement function calling convention expression", - .{}, - ); - } + + const enum_literal_type = try astgen.addZIRInstConst(self, &fn_type_scope.base, fn_src, .{ + .ty = Type.initTag(.type), + .val = Value.initTag(.enum_literal_type), + }); + const enum_literal_type_rl: astgen.ResultLoc = .{ .ty = enum_literal_type }; + const cc = if (fn_proto.getCallconvExpr()) |callconv_expr| + try astgen.expr(self, &fn_type_scope.base, enum_literal_type_rl, callconv_expr) + else + try astgen.addZIRInstConst(self, &fn_type_scope.base, fn_src, .{ + .ty = Type.initTag(.enum_literal), + .val = try Value.Tag.enum_literal.create( + &fn_type_scope_arena.allocator, + try fn_type_scope_arena.allocator.dupe(u8, "Unspecified"), + ), + }); + const return_type_expr = switch (fn_proto.return_type) { .Explicit => |node| node, .InferErrorSet => |node| return self.failNode(&fn_type_scope.base, node, "TODO implement inferred error sets", .{}), @@ -1105,6 +1114,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { const fn_type_inst = try astgen.addZIRInst(self, &fn_type_scope.base, fn_src, zir.Inst.FnType, .{ .return_type = return_type_inst, .param_types = param_types, + .cc = cc, }, .{}); if (std.builtin.mode == .Debug and self.comp.verbose_ir) { @@ -1230,14 +1240,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool { }; }; - const is_inline = blk: { - if (fn_proto.getExternExportInlineToken()) |maybe_inline_token| { - if (tree.token_ids[maybe_inline_token] == .Keyword_inline) { - break :blk true; - } - } - break :blk false; - }; + const is_inline = fn_type.fnCallingConvention() == .Inline; const anal_state = ([2]Fn.Analysis{ .queued, .inline_only })[@boolToInt(is_inline)]; new_func.* = .{ diff --git a/src/type.zig b/src/type.zig index 837e1ad29a..e1006e554c 100644 --- a/src/type.zig +++ b/src/type.zig @@ -552,7 +552,9 @@ pub const Type = extern union { if (i != 0) try out_stream.writeAll(", "); try param_type.format("", .{}, out_stream); } - try out_stream.writeAll(") "); + try out_stream.writeAll(") callconv(."); + try out_stream.writeAll(@tagName(payload.cc)); + try out_stream.writeAll(")"); ty = payload.return_type; continue; }, diff --git a/src/zir.zig b/src/zir.zig index 30bfeead9b..eefded0c6f 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -863,9 +863,7 @@ pub const Inst = struct { fn_type: *Inst, body: Body, }, - kw_args: struct { - is_inline: bool = false, - }, + kw_args: struct {}, }; pub const FnType = struct { @@ -875,10 +873,9 @@ pub const Inst = struct { positionals: struct { param_types: []*Inst, return_type: *Inst, + cc: *Inst, }, - kw_args: struct { - cc: std.builtin.CallingConvention = .Unspecified, - }, + kw_args: struct {}, }; pub const IntType = struct { diff --git a/src/zir_sema.zig b/src/zir_sema.zig index a8120108a4..480e0b4c33 100644 --- a/src/zir_sema.zig +++ b/src/zir_sema.zig @@ -980,18 +980,8 @@ fn zirCall(mod: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerError!*Inst { const b = try mod.requireFunctionBlock(scope, inst.base.src); const is_comptime_call = b.is_comptime or inst.kw_args.modifier == .compile_time; - const is_inline_call = is_comptime_call or inst.kw_args.modifier == .always_inline or blk: { - // This logic will get simplified by - // https://github.com/ziglang/zig/issues/6429 - if (try mod.resolveDefinedValue(scope, func)) |func_val| { - const module_fn = switch (func_val.tag()) { - .function => func_val.castTag(.function).?.data, - else => break :blk false, - }; - break :blk module_fn.state == .inline_only; - } - break :blk false; - }; + const is_inline_call = is_comptime_call or inst.kw_args.modifier == .always_inline or + func.ty.fnCallingConvention() == .Inline; if (is_inline_call) { const func_val = try mod.resolveConstValue(scope, func); const module_fn = switch (func_val.tag()) { @@ -1075,7 +1065,7 @@ fn zirFn(mod: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError!*Inst { const fn_type = try resolveType(mod, scope, fn_inst.positionals.fn_type); const new_func = try scope.arena().create(Module.Fn); new_func.* = .{ - .state = if (fn_inst.kw_args.is_inline) .inline_only else .queued, + .state = if (fn_type.fnCallingConvention() == .Inline) .inline_only else .queued, .zir = fn_inst.positionals.body, .body = undefined, .owner_decl = scope.ownerDecl().?, @@ -1305,22 +1295,26 @@ fn zirFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!* const tracy = trace(@src()); defer tracy.end(); const return_type = try resolveType(mod, scope, fntype.positionals.return_type); + const cc_tv = try resolveInstConst(mod, scope, fntype.positionals.cc); + const cc_str = cc_tv.val.castTag(.enum_literal).?.data; + const cc = std.meta.stringToEnum(std.builtin.CallingConvention, cc_str) orelse + return mod.fail(scope, fntype.positionals.cc.src, "Unknown calling convention {s}", .{cc_str}); // Hot path for some common function types. if (fntype.positionals.param_types.len == 0) { - if (return_type.zigTypeTag() == .NoReturn and fntype.kw_args.cc == .Unspecified) { + if (return_type.zigTypeTag() == .NoReturn and cc == .Unspecified) { return mod.constType(scope, fntype.base.src, Type.initTag(.fn_noreturn_no_args)); } - if (return_type.zigTypeTag() == .Void and fntype.kw_args.cc == .Unspecified) { + if (return_type.zigTypeTag() == .Void and cc == .Unspecified) { return mod.constType(scope, fntype.base.src, Type.initTag(.fn_void_no_args)); } - if (return_type.zigTypeTag() == .NoReturn and fntype.kw_args.cc == .Naked) { + if (return_type.zigTypeTag() == .NoReturn and cc == .Naked) { return mod.constType(scope, fntype.base.src, Type.initTag(.fn_naked_noreturn_no_args)); } - if (return_type.zigTypeTag() == .Void and fntype.kw_args.cc == .C) { + if (return_type.zigTypeTag() == .Void and cc == .C) { return mod.constType(scope, fntype.base.src, Type.initTag(.fn_ccc_void_no_args)); } } @@ -1337,9 +1331,9 @@ fn zirFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!* } const fn_ty = try Type.Tag.function.create(arena, .{ - .cc = fntype.kw_args.cc, - .return_type = return_type, .param_types = param_types, + .return_type = return_type, + .cc = cc, }); return mod.constType(scope, fntype.base.src, fn_ty); } |
