mirror of
https://github.com/ziglang/zig.git
synced 2025-12-24 07:03:11 +00:00
CBE: implement the future
Turns out f(...) will be supported one day.
This commit is contained in:
parent
1f3d9f79c1
commit
f8aecef670
@ -6876,17 +6876,16 @@ fn airCVaStart(f: *Function, inst: Air.Inst.Index) !CValue {
|
|||||||
|
|
||||||
const inst_ty = f.air.typeOfIndex(inst);
|
const inst_ty = f.air.typeOfIndex(inst);
|
||||||
const fn_cty = try f.typeToCType(f.object.dg.decl.?.ty, .complete);
|
const fn_cty = try f.typeToCType(f.object.dg.decl.?.ty, .complete);
|
||||||
|
|
||||||
const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;
|
const param_len = fn_cty.castTag(.varargs_function).?.data.param_types.len;
|
||||||
if (param_len == 0)
|
|
||||||
return f.fail("CBE: C requires at least one runtime argument for varargs functions", .{});
|
|
||||||
|
|
||||||
const writer = f.object.writer();
|
const writer = f.object.writer();
|
||||||
const local = try f.allocLocal(inst, inst_ty);
|
const local = try f.allocLocal(inst, inst_ty);
|
||||||
try writer.writeAll("va_start(*(va_list *)&");
|
try writer.writeAll("va_start(*(va_list *)&");
|
||||||
try f.writeCValue(writer, local, .Other);
|
try f.writeCValue(writer, local, .Other);
|
||||||
try writer.writeAll(", ");
|
if (param_len > 0) {
|
||||||
try f.writeCValue(writer, .{ .arg = param_len - 1 }, .FunctionArgument);
|
try writer.writeAll(", ");
|
||||||
|
try f.writeCValue(writer, .{ .arg = param_len - 1 }, .FunctionArgument);
|
||||||
|
}
|
||||||
try writer.writeAll(");\n");
|
try writer.writeAll(");\n");
|
||||||
return local;
|
return local;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -111,6 +111,12 @@ test "simple variadic function" {
|
|||||||
return @cVaArg(&ap, c_int);
|
return @cVaArg(&ap, c_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compatible(_: c_int, ...) callconv(.C) c_int {
|
||||||
|
var ap = @cVaStart();
|
||||||
|
defer @cVaEnd(&ap);
|
||||||
|
return @cVaArg(&ap, c_int);
|
||||||
|
}
|
||||||
|
|
||||||
fn add(count: c_int, ...) callconv(.C) c_int {
|
fn add(count: c_int, ...) callconv(.C) c_int {
|
||||||
var ap = @cVaStart();
|
var ap = @cVaStart();
|
||||||
defer @cVaEnd(&ap);
|
defer @cVaEnd(&ap);
|
||||||
@ -123,10 +129,13 @@ test "simple variadic function" {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (builtin.zig_backend != .stage2_c) { // C doesn't support varargs without a preceding runtime arg.
|
if (builtin.zig_backend != .stage2_c) {
|
||||||
|
// pre C23 doesn't support varargs without a preceding runtime arg.
|
||||||
try std.testing.expectEqual(@as(c_int, 0), S.simple(@as(c_int, 0)));
|
try std.testing.expectEqual(@as(c_int, 0), S.simple(@as(c_int, 0)));
|
||||||
try std.testing.expectEqual(@as(c_int, 1024), S.simple(@as(c_int, 1024)));
|
try std.testing.expectEqual(@as(c_int, 1024), S.simple(@as(c_int, 1024)));
|
||||||
}
|
}
|
||||||
|
try std.testing.expectEqual(@as(c_int, 0), S.compatible(undefined, @as(c_int, 0)));
|
||||||
|
try std.testing.expectEqual(@as(c_int, 1024), S.compatible(undefined, @as(c_int, 1024)));
|
||||||
try std.testing.expectEqual(@as(c_int, 0), S.add(0));
|
try std.testing.expectEqual(@as(c_int, 0), S.add(0));
|
||||||
try std.testing.expectEqual(@as(c_int, 1), S.add(1, @as(c_int, 1)));
|
try std.testing.expectEqual(@as(c_int, 1), S.add(1, @as(c_int, 1)));
|
||||||
try std.testing.expectEqual(@as(c_int, 3), S.add(2, @as(c_int, 1), @as(c_int, 2)));
|
try std.testing.expectEqual(@as(c_int, 3), S.add(2, @as(c_int, 1), @as(c_int, 2)));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user