mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
AstGen: implement function prototypes with alignment exprs
This commit is contained in:
parent
2eef83e85f
commit
ba9b9cb38d
@ -1,3 +1,4 @@
|
||||
* decouple AstGen from Module, Compilation
|
||||
* modify dbg_stmt ZIR instructions to have line/column rather than node indexes
|
||||
* AstGen threadlocal
|
||||
* extern "foo" for vars and for functions
|
||||
|
||||
@ -1048,10 +1048,12 @@ pub fn fnProtoExpr(
|
||||
assert(param_type_i == param_count);
|
||||
}
|
||||
|
||||
if (fn_proto.ast.align_expr != 0) {
|
||||
return astgen.failNode(fn_proto.ast.align_expr, "TODO: AstGen: implement function prototypes with alignment expressions", .{});
|
||||
const align_inst: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: {
|
||||
break :inst try expr(gz, scope, align_rl, fn_proto.ast.align_expr);
|
||||
};
|
||||
if (fn_proto.ast.section_expr != 0) {
|
||||
return astgen.failNode(fn_proto.ast.section_expr, "linksection not allowed on function prototypes", .{});
|
||||
}
|
||||
assert(fn_proto.ast.section_expr == 0); // caught by the parser
|
||||
|
||||
const maybe_bang = tree.firstToken(fn_proto.ast.return_type) - 1;
|
||||
const is_inferred_error = token_tags[maybe_bang] == .bang;
|
||||
@ -1081,6 +1083,7 @@ pub fn fnProtoExpr(
|
||||
.param_types = param_types,
|
||||
.body = &[0]Zir.Inst.Index{},
|
||||
.cc = cc,
|
||||
.align_inst = align_inst,
|
||||
.lib_name = 0,
|
||||
.is_var_args = is_var_args,
|
||||
.is_inferred_error = false,
|
||||
@ -2794,6 +2797,7 @@ fn fnDecl(
|
||||
.param_types = param_types,
|
||||
.body = &[0]Zir.Inst.Index{},
|
||||
.cc = cc,
|
||||
.align_inst = .none, // passed in the per-decl data
|
||||
.lib_name = lib_name,
|
||||
.is_var_args = is_var_args,
|
||||
.is_inferred_error = false,
|
||||
@ -2866,6 +2870,7 @@ fn fnDecl(
|
||||
.param_types = param_types,
|
||||
.body = fn_gz.instructions.items,
|
||||
.cc = cc,
|
||||
.align_inst = .none, // passed in the per-decl data
|
||||
.lib_name = lib_name,
|
||||
.is_var_args = is_var_args,
|
||||
.is_inferred_error = is_inferred_error,
|
||||
@ -3167,6 +3172,7 @@ fn testDecl(
|
||||
.param_types = &[0]Zir.Inst.Ref{},
|
||||
.body = fn_block.instructions.items,
|
||||
.cc = .none,
|
||||
.align_inst = .none,
|
||||
.lib_name = 0,
|
||||
.is_var_args = false,
|
||||
.is_inferred_error = true,
|
||||
|
||||
@ -1372,6 +1372,7 @@ pub const Scope = struct {
|
||||
body: []const Zir.Inst.Index,
|
||||
ret_ty: Zir.Inst.Ref,
|
||||
cc: Zir.Inst.Ref,
|
||||
align_inst: Zir.Inst.Ref,
|
||||
lib_name: u32,
|
||||
is_var_args: bool,
|
||||
is_inferred_error: bool,
|
||||
@ -1385,12 +1386,15 @@ pub const Scope = struct {
|
||||
try gz.instructions.ensureUnusedCapacity(gpa, 1);
|
||||
try astgen.instructions.ensureUnusedCapacity(gpa, 1);
|
||||
|
||||
if (args.cc != .none or args.lib_name != 0 or args.is_var_args or args.is_test) {
|
||||
if (args.cc != .none or args.lib_name != 0 or
|
||||
args.is_var_args or args.is_test or args.align_inst != .none)
|
||||
{
|
||||
try astgen.extra.ensureUnusedCapacity(
|
||||
gpa,
|
||||
@typeInfo(Zir.Inst.ExtendedFunc).Struct.fields.len +
|
||||
args.param_types.len + args.body.len +
|
||||
@boolToInt(args.lib_name != 0) +
|
||||
@boolToInt(args.align_inst != .none) +
|
||||
@boolToInt(args.cc != .none),
|
||||
);
|
||||
const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedFunc{
|
||||
@ -1399,11 +1403,14 @@ pub const Scope = struct {
|
||||
.param_types_len = @intCast(u32, args.param_types.len),
|
||||
.body_len = @intCast(u32, args.body.len),
|
||||
});
|
||||
if (args.lib_name != 0) {
|
||||
astgen.extra.appendAssumeCapacity(args.lib_name);
|
||||
}
|
||||
if (args.cc != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.cc));
|
||||
}
|
||||
if (args.lib_name != 0) {
|
||||
astgen.extra.appendAssumeCapacity(args.lib_name);
|
||||
if (args.align_inst != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.align_inst));
|
||||
}
|
||||
astgen.appendRefsAssumeCapacity(args.param_types);
|
||||
astgen.extra.appendSliceAssumeCapacity(args.body);
|
||||
@ -1418,6 +1425,7 @@ pub const Scope = struct {
|
||||
.is_inferred_error = args.is_inferred_error,
|
||||
.has_lib_name = args.lib_name != 0,
|
||||
.has_cc = args.cc != .none,
|
||||
.has_align = args.align_inst != .none,
|
||||
.is_test = args.is_test,
|
||||
}),
|
||||
.operand = payload_index,
|
||||
|
||||
17
src/Sema.zig
17
src/Sema.zig
@ -2737,6 +2737,7 @@ fn zirFunc(
|
||||
body,
|
||||
extra.data.return_type,
|
||||
.Unspecified,
|
||||
Value.initTag(.null_value),
|
||||
false,
|
||||
inferred_error_set,
|
||||
);
|
||||
@ -2750,6 +2751,7 @@ fn funcCommon(
|
||||
body: []const Zir.Inst.Index,
|
||||
zir_return_type: Zir.Inst.Ref,
|
||||
cc: std.builtin.CallingConvention,
|
||||
align_val: Value,
|
||||
var_args: bool,
|
||||
inferred_error_set: bool,
|
||||
) InnerError!*Inst {
|
||||
@ -2762,7 +2764,7 @@ fn funcCommon(
|
||||
}
|
||||
|
||||
// Hot path for some common function types.
|
||||
if (zir_param_types.len == 0 and !var_args) {
|
||||
if (zir_param_types.len == 0 and !var_args and align_val.tag() == .null_value) {
|
||||
if (return_type.zigTypeTag() == .NoReturn and cc == .Unspecified) {
|
||||
return sema.mod.constType(sema.arena, src, Type.initTag(.fn_noreturn_no_args));
|
||||
}
|
||||
@ -2789,6 +2791,10 @@ fn funcCommon(
|
||||
param_types[i] = try sema.resolveType(block, src, param_type);
|
||||
}
|
||||
|
||||
if (align_val.tag() != .null_value) {
|
||||
return sema.mod.fail(&block.base, src, "TODO implement support for function prototypes to have alignment specified", .{});
|
||||
}
|
||||
|
||||
const fn_ty = try Type.Tag.function.create(sema.arena, .{
|
||||
.param_types = param_types,
|
||||
.return_type = return_type,
|
||||
@ -5432,6 +5438,7 @@ fn zirFuncExtended(
|
||||
const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, extended.operand);
|
||||
const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
|
||||
const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node };
|
||||
const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align
|
||||
const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
|
||||
|
||||
var extra_index: usize = extra.end;
|
||||
@ -5455,6 +5462,13 @@ fn zirFuncExtended(
|
||||
break :blk cc;
|
||||
} else .Unspecified;
|
||||
|
||||
const align_val: Value = if (small.has_align) blk: {
|
||||
const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
const align_tv = try sema.resolveInstConst(block, align_src, align_ref);
|
||||
break :blk align_tv.val;
|
||||
} else Value.initTag(.null_value);
|
||||
|
||||
const param_types = sema.code.refSlice(extra_index, extra.data.param_types_len);
|
||||
extra_index += param_types.len;
|
||||
|
||||
@ -5467,6 +5481,7 @@ fn zirFuncExtended(
|
||||
body,
|
||||
extra.data.return_type,
|
||||
cc,
|
||||
align_val,
|
||||
small.is_var_args,
|
||||
small.is_inferred_error,
|
||||
);
|
||||
|
||||
17
src/Zir.zig
17
src/Zir.zig
@ -2189,8 +2189,9 @@ pub const Inst = struct {
|
||||
/// Trailing:
|
||||
/// 0. lib_name: u32, // null terminated string index, if has_lib_name is set
|
||||
/// 1. cc: Ref, // if has_cc is set
|
||||
/// 2. param_type: Ref // for each param_types_len
|
||||
/// 3. body: Index // for each body_len
|
||||
/// 2. align: Ref, // if has_align is set
|
||||
/// 3. param_type: Ref // for each param_types_len
|
||||
/// 4. body: Index // for each body_len
|
||||
pub const ExtendedFunc = struct {
|
||||
src_node: i32,
|
||||
return_type: Ref,
|
||||
@ -2202,8 +2203,9 @@ pub const Inst = struct {
|
||||
is_inferred_error: bool,
|
||||
has_lib_name: bool,
|
||||
has_cc: bool,
|
||||
has_align: bool,
|
||||
is_test: bool,
|
||||
_: u11 = undefined,
|
||||
_: u10 = undefined,
|
||||
};
|
||||
};
|
||||
|
||||
@ -3966,6 +3968,7 @@ const Writer = struct {
|
||||
inferred_error_set,
|
||||
false,
|
||||
.none,
|
||||
.none,
|
||||
body,
|
||||
src,
|
||||
);
|
||||
@ -3988,6 +3991,11 @@ const Writer = struct {
|
||||
extra_index += 1;
|
||||
break :blk cc;
|
||||
};
|
||||
const align_inst: Inst.Ref = if (!small.has_align) .none else blk: {
|
||||
const align_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
break :blk align_inst;
|
||||
};
|
||||
|
||||
const param_types = self.code.refSlice(extra_index, extra.data.param_types_len);
|
||||
extra_index += param_types.len;
|
||||
@ -4001,6 +4009,7 @@ const Writer = struct {
|
||||
small.is_inferred_error,
|
||||
small.is_var_args,
|
||||
cc,
|
||||
align_inst,
|
||||
body,
|
||||
src,
|
||||
);
|
||||
@ -4053,6 +4062,7 @@ const Writer = struct {
|
||||
inferred_error_set: bool,
|
||||
var_args: bool,
|
||||
cc: Inst.Ref,
|
||||
align_inst: Inst.Ref,
|
||||
body: []const Inst.Index,
|
||||
src: LazySrcLoc,
|
||||
) !void {
|
||||
@ -4064,6 +4074,7 @@ const Writer = struct {
|
||||
try stream.writeAll("], ");
|
||||
try self.writeInstRef(stream, ret_ty);
|
||||
try self.writeOptionalInstRef(stream, ", cc=", cc);
|
||||
try self.writeOptionalInstRef(stream, ", align=", align_inst);
|
||||
try self.writeFlag(stream, ", vargs", var_args);
|
||||
try self.writeFlag(stream, ", inferror", inferred_error_set);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user