Commit 3fd8ac092e
Changed files (3)
lib
std
zig
lib/std/zig/ast.zig
@@ -1833,7 +1833,7 @@ pub const Tree = struct {
var result: full.FnProto = .{
.ast = info,
.visib_token = null,
- .extern_export_token = null,
+ .extern_export_inline_token = null,
.lib_name = null,
.name_token = null,
.lparen = undefined,
@@ -1842,7 +1842,11 @@ pub const Tree = struct {
while (i > 0) {
i -= 1;
switch (token_tags[i]) {
- .keyword_extern, .keyword_export => result.extern_export_token = i,
+ .keyword_extern,
+ .keyword_export,
+ .keyword_inline,
+ .keyword_noinline,
+ => result.extern_export_inline_token = i,
.keyword_pub => result.visib_token = i,
.string_literal => result.lib_name = i,
else => break,
@@ -2123,7 +2127,7 @@ pub const full = struct {
pub const FnProto = struct {
visib_token: ?TokenIndex,
- extern_export_token: ?TokenIndex,
+ extern_export_inline_token: ?TokenIndex,
lib_name: ?TokenIndex,
name_token: ?TokenIndex,
lparen: TokenIndex,
src/AstGen.zig
@@ -995,7 +995,7 @@ fn fnProtoExpr(
const token_tags = tree.tokens.items(.tag);
const is_extern = blk: {
- const maybe_extern_token = fn_proto.extern_export_token orelse break :blk false;
+ const maybe_extern_token = fn_proto.extern_export_inline_token orelse break :blk false;
break :blk token_tags[maybe_extern_token] == .keyword_extern;
};
assert(!is_extern);
@@ -2735,15 +2735,20 @@ fn fnDecl(
};
defer decl_gz.instructions.deinit(gpa);
+ // TODO: support noinline
const is_pub = fn_proto.visib_token != null;
const is_export = blk: {
- const maybe_export_token = fn_proto.extern_export_token orelse break :blk false;
+ const maybe_export_token = fn_proto.extern_export_inline_token orelse break :blk false;
break :blk token_tags[maybe_export_token] == .keyword_export;
};
const is_extern = blk: {
- const maybe_extern_token = fn_proto.extern_export_token orelse break :blk false;
+ const maybe_extern_token = fn_proto.extern_export_inline_token orelse break :blk false;
break :blk token_tags[maybe_extern_token] == .keyword_extern;
};
+ const has_inline_keyword = blk: {
+ const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false;
+ break :blk token_tags[maybe_inline_token] == .keyword_inline;
+ };
const align_inst: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: {
break :inst try expr(&decl_gz, &decl_gz.base, align_rl, fn_proto.ast.align_expr);
};
@@ -2812,17 +2817,30 @@ fn fnDecl(
fn_proto.ast.return_type,
);
- const cc: Zir.Inst.Ref = if (fn_proto.ast.callconv_expr != 0)
- try AstGen.expr(
- &decl_gz,
- &decl_gz.base,
- .{ .ty = .calling_convention_type },
- fn_proto.ast.callconv_expr,
- )
- else if (is_extern) // note: https://github.com/ziglang/zig/issues/5269
- Zir.Inst.Ref.calling_convention_c
- else
- Zir.Inst.Ref.none;
+ const cc: Zir.Inst.Ref = blk: {
+ if (fn_proto.ast.callconv_expr != 0) {
+ if (has_inline_keyword) {
+ return astgen.failNode(
+ fn_proto.ast.callconv_expr,
+ "explicit callconv incompatible with inline keyword",
+ .{},
+ );
+ }
+ break :blk try AstGen.expr(
+ &decl_gz,
+ &decl_gz.base,
+ .{ .ty = .calling_convention_type },
+ fn_proto.ast.callconv_expr,
+ );
+ } else if (is_extern) {
+ // note: https://github.com/ziglang/zig/issues/5269
+ break :blk .calling_convention_c;
+ } else if (has_inline_keyword) {
+ break :blk .calling_convention_inline;
+ } else {
+ break :blk .none;
+ }
+ };
const func_inst: Zir.Inst.Ref = if (body_node == 0) func: {
if (!is_extern) {
src/Zir.zig
@@ -1687,6 +1687,8 @@ pub const Inst = struct {
one_usize,
/// `std.builtin.CallingConvention.C`
calling_convention_c,
+ /// `std.builtin.CallingConvention.Inline`
+ calling_convention_inline,
_,
@@ -1954,6 +1956,10 @@ pub const Inst = struct {
.ty = Type.initTag(.calling_convention),
.val = .{ .ptr_otherwise = &calling_convention_c_payload.base },
},
+ .calling_convention_inline = .{
+ .ty = Type.initTag(.calling_convention),
+ .val = .{ .ptr_otherwise = &calling_convention_inline_payload.base },
+ },
});
};
@@ -1964,6 +1970,13 @@ pub const Inst = struct {
.data = @enumToInt(std.builtin.CallingConvention.C),
};
+ /// We would like this to be const but `Value` wants a mutable pointer for
+ /// its payload field. Nothing should mutate this though.
+ var calling_convention_inline_payload: Value.Payload.U32 = .{
+ .base = .{ .tag = .enum_field_index },
+ .data = @enumToInt(std.builtin.CallingConvention.Inline),
+ };
+
/// All instructions have an 8-byte payload, which is contained within
/// this union. `Tag` determines which union field is active, as well as
/// how to interpret the data within.