translate-c: get all translate-c tests passing
This commit is contained in:
@@ -622,7 +622,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
|
||||
return; // Avoid processing this decl twice
|
||||
|
||||
const is_pub = mangled_name == null;
|
||||
const is_thread_local = var_decl.getTLSKind() != .None;
|
||||
const is_threadlocal = var_decl.getTLSKind() != .None;
|
||||
const scope = &c.global_scope.base;
|
||||
|
||||
// TODO https://github.com/ziglang/zig/issues/3756
|
||||
@@ -706,6 +706,7 @@ fn visitVarDecl(c: *Context, var_decl: *const clang.VarDecl, mangled_name: ?[]co
|
||||
.is_const = is_const,
|
||||
.is_extern = is_extern,
|
||||
.is_export = is_export,
|
||||
.is_threadlocal = is_threadlocal,
|
||||
.linksection_string = linksection_string,
|
||||
.alignment = alignment,
|
||||
.name = checked_name,
|
||||
@@ -1307,6 +1308,7 @@ fn transDeclStmtOne(
|
||||
.is_const = is_const,
|
||||
.is_extern = false,
|
||||
.is_export = false,
|
||||
.is_threadlocal = false,
|
||||
.linksection_string = null,
|
||||
.alignment = null,
|
||||
.name = mangled_name,
|
||||
@@ -2886,11 +2888,11 @@ fn transCreateCompoundAssign(
|
||||
if ((is_mod or is_div) and is_signed) {
|
||||
const rhs_node = try transExpr(c, &block_scope.base, rhs, .used);
|
||||
const builtin = if (is_mod)
|
||||
try Tag.rem.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node })
|
||||
try Tag.rem.create(c.arena, .{ .lhs = ref_node, .rhs = rhs_node })
|
||||
else
|
||||
try Tag.div_trunc.create(c.arena, .{ .lhs = lhs_node, .rhs = rhs_node });
|
||||
try Tag.div_trunc.create(c.arena, .{ .lhs = ref_node, .rhs = rhs_node });
|
||||
|
||||
const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, lhs_node, builtin, .used);
|
||||
const assign = try transCreateNodeInfixOp(c, &block_scope.base, .assign, ref_node, builtin, .used);
|
||||
try block_scope.statements.append(assign);
|
||||
} else {
|
||||
var rhs_node = try transExpr(c, &block_scope.base, rhs, .used);
|
||||
@@ -4794,6 +4796,10 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!Node {
|
||||
.LBracket => {
|
||||
const index = try macroBoolToInt(c, try parseCExpr(c, m, scope));
|
||||
node = try Tag.array_access.create(c.arena, .{ .lhs = node, .rhs = index });
|
||||
if (m.next().? != .RBracket) {
|
||||
try m.fail(c, "unable to translate C expr: expected ']'", .{});
|
||||
return error.ParseError;
|
||||
}
|
||||
},
|
||||
.LParen => {
|
||||
var args = std.ArrayList(Node).init(c.gpa);
|
||||
|
||||
@@ -458,6 +458,7 @@ pub const Payload = struct {
|
||||
is_const: bool,
|
||||
is_extern: bool,
|
||||
is_export: bool,
|
||||
is_threadlocal: bool,
|
||||
alignment: ?c_uint,
|
||||
linksection_string: ?[]const u8,
|
||||
name: []const u8,
|
||||
@@ -1164,42 +1165,42 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
},
|
||||
});
|
||||
},
|
||||
.add => return renderBinOp(c, node, .add, .plus, "+"),
|
||||
.add => return renderBinOpGrouped(c, node, .add, .plus, "+"),
|
||||
.add_assign => return renderBinOp(c, node, .assign_add, .plus_equal, "+="),
|
||||
.add_wrap => return renderBinOp(c, node, .add_wrap, .plus_percent, "+%"),
|
||||
.add_wrap => return renderBinOpGrouped(c, node, .add_wrap, .plus_percent, "+%"),
|
||||
.add_wrap_assign => return renderBinOp(c, node, .assign_add_wrap, .plus_percent_equal, "+%="),
|
||||
.sub => return renderBinOp(c, node, .sub, .minus, "-"),
|
||||
.sub => return renderBinOpGrouped(c, node, .sub, .minus, "-"),
|
||||
.sub_assign => return renderBinOp(c, node, .assign_sub, .minus_equal, "-="),
|
||||
.sub_wrap => return renderBinOp(c, node, .sub_wrap, .minus_percent, "-%"),
|
||||
.sub_wrap => return renderBinOpGrouped(c, node, .sub_wrap, .minus_percent, "-%"),
|
||||
.sub_wrap_assign => return renderBinOp(c, node, .assign_sub_wrap, .minus_percent_equal, "-%="),
|
||||
.mul => return renderBinOp(c, node, .mul, .asterisk, "*"),
|
||||
.mul => return renderBinOpGrouped(c, node, .mul, .asterisk, "*"),
|
||||
.mul_assign => return renderBinOp(c, node, .assign_mul, .asterisk_equal, "*="),
|
||||
.mul_wrap => return renderBinOp(c, node, .mul_wrap, .asterisk_percent, "*="),
|
||||
.mul_wrap => return renderBinOpGrouped(c, node, .mul_wrap, .asterisk_percent, "*%"),
|
||||
.mul_wrap_assign => return renderBinOp(c, node, .assign_mul_wrap, .asterisk_percent_equal, "*%="),
|
||||
.div => return renderBinOp(c, node, .div, .slash, "/"),
|
||||
.div => return renderBinOpGrouped(c, node, .div, .slash, "/"),
|
||||
.div_assign => return renderBinOp(c, node, .assign_div, .slash_equal, "/="),
|
||||
.shl => return renderBinOp(c, node, .bit_shift_left, .angle_bracket_angle_bracket_left, "<<"),
|
||||
.shl => return renderBinOpGrouped(c, node, .bit_shift_left, .angle_bracket_angle_bracket_left, "<<"),
|
||||
.shl_assign => return renderBinOp(c, node, .assign_bit_shift_left, .angle_bracket_angle_bracket_left_equal, "<<="),
|
||||
.shr => return renderBinOp(c, node, .bit_shift_right, .angle_bracket_angle_bracket_right, ">>"),
|
||||
.shr => return renderBinOpGrouped(c, node, .bit_shift_right, .angle_bracket_angle_bracket_right, ">>"),
|
||||
.shr_assign => return renderBinOp(c, node, .assign_bit_shift_right, .angle_bracket_angle_bracket_right_equal, ">>="),
|
||||
.mod => return renderBinOp(c, node, .mod, .percent, "%"),
|
||||
.mod => return renderBinOpGrouped(c, node, .mod, .percent, "%"),
|
||||
.mod_assign => return renderBinOp(c, node, .assign_mod, .percent_equal, "%="),
|
||||
.@"and" => return renderBinOp(c, node, .bool_and, .keyword_and, "and"),
|
||||
.@"or" => return renderBinOp(c, node, .bool_or, .keyword_or, "or"),
|
||||
.less_than => return renderBinOp(c, node, .less_than, .angle_bracket_left, "<"),
|
||||
.less_than_equal => return renderBinOp(c, node, .less_or_equal, .angle_bracket_left_equal, "<="),
|
||||
.greater_than => return renderBinOp(c, node, .greater_than, .angle_bracket_right, ">="),
|
||||
.greater_than_equal => return renderBinOp(c, node, .greater_or_equal, .angle_bracket_right_equal, ">="),
|
||||
.equal => return renderBinOp(c, node, .equal_equal, .equal_equal, "=="),
|
||||
.not_equal => return renderBinOp(c, node, .bang_equal, .bang_equal, "!="),
|
||||
.bit_and => return renderBinOp(c, node, .bit_and, .ampersand, "&"),
|
||||
.@"and" => return renderBinOpGrouped(c, node, .bool_and, .keyword_and, "and"),
|
||||
.@"or" => return renderBinOpGrouped(c, node, .bool_or, .keyword_or, "or"),
|
||||
.less_than => return renderBinOpGrouped(c, node, .less_than, .angle_bracket_left, "<"),
|
||||
.less_than_equal => return renderBinOpGrouped(c, node, .less_or_equal, .angle_bracket_left_equal, "<="),
|
||||
.greater_than => return renderBinOpGrouped(c, node, .greater_than, .angle_bracket_right, ">="),
|
||||
.greater_than_equal => return renderBinOpGrouped(c, node, .greater_or_equal, .angle_bracket_right_equal, ">="),
|
||||
.equal => return renderBinOpGrouped(c, node, .equal_equal, .equal_equal, "=="),
|
||||
.not_equal => return renderBinOpGrouped(c, node, .bang_equal, .bang_equal, "!="),
|
||||
.bit_and => return renderBinOpGrouped(c, node, .bit_and, .ampersand, "&"),
|
||||
.bit_and_assign => return renderBinOp(c, node, .assign_bit_and, .ampersand_equal, "&="),
|
||||
.bit_or => return renderBinOp(c, node, .bit_or, .pipe, "|"),
|
||||
.bit_or => return renderBinOpGrouped(c, node, .bit_or, .pipe, "|"),
|
||||
.bit_or_assign => return renderBinOp(c, node, .assign_bit_or, .pipe_equal, "|="),
|
||||
.bit_xor => return renderBinOp(c, node, .bit_xor, .caret, "^"),
|
||||
.bit_xor => return renderBinOpGrouped(c, node, .bit_xor, .caret, "^"),
|
||||
.bit_xor_assign => return renderBinOp(c, node, .assign_bit_xor, .caret_equal, "^="),
|
||||
.array_cat => return renderBinOp(c, node, .array_cat, .plus_plus, "++"),
|
||||
.ellipsis3 => return renderBinOp(c, node, .switch_range, .ellipsis3, "..."),
|
||||
.ellipsis3 => return renderBinOpGrouped(c, node, .switch_range, .ellipsis3, "..."),
|
||||
.assign => return renderBinOp(c, node, .assign, .equal, "="),
|
||||
.empty_block => {
|
||||
const l_brace = try c.addToken(.l_brace, "{");
|
||||
@@ -1222,7 +1223,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
|
||||
_ = try c.addToken(.r_brace, "}");
|
||||
return c.addNode(.{
|
||||
.tag = .block_two,
|
||||
.tag = .block_two_semicolon,
|
||||
.main_token = l_brace,
|
||||
.data = .{
|
||||
.lhs = stmt,
|
||||
@@ -1410,13 +1411,13 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
var cases = try c.gpa.alloc(NodeIndex, payload.cases.len);
|
||||
defer c.gpa.free(cases);
|
||||
for (payload.cases) |case, i| {
|
||||
if (i != 0) _ = try c.addToken(.comma, ",");
|
||||
cases[i] = try renderNode(c, case);
|
||||
_ = try c.addToken(.comma, ",");
|
||||
}
|
||||
const span = try c.listToSpan(cases);
|
||||
_ = try c.addToken(.r_brace, "}");
|
||||
return c.addNode(.{
|
||||
.tag = .@"switch",
|
||||
.tag = .switch_comma,
|
||||
.main_token = switch_tok,
|
||||
.data = .{
|
||||
.lhs = cond,
|
||||
@@ -1623,9 +1624,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
const payload = node.castTag(.tuple).?.data;
|
||||
_ = try c.addToken(.period, ".");
|
||||
const l_brace = try c.addToken(.l_brace, "{");
|
||||
var inits = try c.gpa.alloc(NodeIndex, std.math.max(payload.len, 1));
|
||||
var inits = try c.gpa.alloc(NodeIndex, std.math.max(payload.len, 2));
|
||||
defer c.gpa.free(inits);
|
||||
inits[0] = 0;
|
||||
inits[1] = 0;
|
||||
for (payload) |init, i| {
|
||||
if (i != 0) _ = try c.addToken(.comma, ",");
|
||||
inits[i] = try renderNode(c, init);
|
||||
@@ -1661,17 +1663,17 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
defer c.gpa.free(inits);
|
||||
inits[0] = 0;
|
||||
for (payload.inits) |init, i| {
|
||||
if (i != 0) _ = try c.addToken(.comma, ",");
|
||||
_ = try c.addToken(.period, ".");
|
||||
_ = try c.addIdentifier(init.name);
|
||||
_ = try c.addToken(.equal, "=");
|
||||
inits[i] = try renderNode(c, init.value);
|
||||
_ = try c.addToken(.comma, ",");
|
||||
}
|
||||
_ = try c.addToken(.r_brace, "}");
|
||||
|
||||
if (payload.inits.len < 2) {
|
||||
return c.addNode(.{
|
||||
.tag = .struct_init_one,
|
||||
.tag = .struct_init_one_comma,
|
||||
.main_token = l_brace,
|
||||
.data = .{
|
||||
.lhs = lhs,
|
||||
@@ -1681,7 +1683,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
|
||||
} else {
|
||||
const span = try c.listToSpan(inits);
|
||||
return c.addNode(.{
|
||||
.tag = .struct_init,
|
||||
.tag = .struct_init_comma,
|
||||
.main_token = l_brace,
|
||||
.data = .{
|
||||
.lhs = lhs,
|
||||
@@ -1791,13 +1793,13 @@ fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex
|
||||
defer c.gpa.free(rendered);
|
||||
rendered[0] = 0;
|
||||
for (inits) |init, i| {
|
||||
if (i != 0) _ = try c.addToken(.comma, ",");
|
||||
rendered[i] = try renderNode(c, init);
|
||||
_ = try c.addToken(.comma, ",");
|
||||
}
|
||||
_ = try c.addToken(.r_brace, "}");
|
||||
if (inits.len < 2) {
|
||||
return c.addNode(.{
|
||||
.tag = .array_init_one,
|
||||
.tag = .array_init_one_comma,
|
||||
.main_token = l_brace,
|
||||
.data = .{
|
||||
.lhs = lhs,
|
||||
@@ -1807,7 +1809,7 @@ fn renderArrayInit(c: *Context, lhs: NodeIndex, inits: []const Node) !NodeIndex
|
||||
} else {
|
||||
const span = try c.listToSpan(rendered);
|
||||
return c.addNode(.{
|
||||
.tag = .array_init,
|
||||
.tag = .array_init_comma,
|
||||
.main_token = l_brace,
|
||||
.data = .{
|
||||
.lhs = lhs,
|
||||
@@ -1842,25 +1844,32 @@ fn renderArrayType(c: *Context, len: usize, elem_type: Node) !NodeIndex {
|
||||
fn addSemicolonIfNeeded(c: *Context, node: Node) !void {
|
||||
switch (node.tag()) {
|
||||
.warning => unreachable,
|
||||
.var_decl, .var_simple, .arg_redecl, .alias, .enum_redecl, .block, .empty_block, .@"switch" => {},
|
||||
.var_decl, .var_simple, .arg_redecl, .alias, .enum_redecl, .block, .empty_block, .block_single, .@"switch" => {},
|
||||
.while_true => {
|
||||
const payload = node.castTag(.while_true).?.data;
|
||||
return addSemicolonIfNeeded(c, payload);
|
||||
return addSemicolonIfNotBlock(c, payload);
|
||||
},
|
||||
.@"while" => {
|
||||
const payload = node.castTag(.@"while").?.data;
|
||||
return addSemicolonIfNeeded(c, payload.body);
|
||||
return addSemicolonIfNotBlock(c, payload.body);
|
||||
},
|
||||
.@"if" => {
|
||||
const payload = node.castTag(.@"if").?.data;
|
||||
if (payload.@"else") |some|
|
||||
return addSemicolonIfNeeded(c, some);
|
||||
return addSemicolonIfNeeded(c, payload.then);
|
||||
return addSemicolonIfNotBlock(c, some);
|
||||
return addSemicolonIfNotBlock(c, payload.then);
|
||||
},
|
||||
else => _ = try c.addToken(.semicolon, ";"),
|
||||
}
|
||||
}
|
||||
|
||||
fn addSemicolonIfNotBlock(c: *Context, node: Node) !void {
|
||||
switch (node.tag()) {
|
||||
.block, .empty_block, .block_single, => {},
|
||||
else => _ = try c.addToken(.semicolon, ";"),
|
||||
}
|
||||
}
|
||||
|
||||
fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
|
||||
switch (node.tag()) {
|
||||
.null_literal,
|
||||
@@ -1918,6 +1927,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
|
||||
.func,
|
||||
.call,
|
||||
.array_type,
|
||||
.bool_to_int,
|
||||
=> {
|
||||
// no grouping needed
|
||||
return renderNode(c, node);
|
||||
@@ -1926,7 +1936,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
|
||||
.opaque_literal,
|
||||
.empty_array,
|
||||
.block_single,
|
||||
.bool_to_int,
|
||||
.add,
|
||||
.add_wrap,
|
||||
.sub,
|
||||
@@ -2022,7 +2031,7 @@ fn renderPrefixOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: T
|
||||
});
|
||||
}
|
||||
|
||||
fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
|
||||
fn renderBinOpGrouped(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
|
||||
const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
|
||||
const lhs = try renderNodeGrouped(c, payload.lhs);
|
||||
return c.addNode(.{
|
||||
@@ -2035,6 +2044,19 @@ fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: Toke
|
||||
});
|
||||
}
|
||||
|
||||
fn renderBinOp(c: *Context, node: Node, tag: std.zig.ast.Node.Tag, tok_tag: TokenTag, bytes: []const u8) !NodeIndex {
|
||||
const payload = @fieldParentPtr(Payload.BinOp, "base", node.ptr_otherwise).data;
|
||||
const lhs = try renderNode(c, payload.lhs);
|
||||
return c.addNode(.{
|
||||
.tag = tag,
|
||||
.main_token = try c.addToken(tok_tag, bytes),
|
||||
.data = .{
|
||||
.lhs = lhs,
|
||||
.rhs = try renderNode(c, payload.rhs),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
fn renderStdImport(c: *Context, first: []const u8, second: []const u8) !NodeIndex {
|
||||
const import_tok = try c.addToken(.builtin, "@import");
|
||||
_ = try c.addToken(.l_paren, "(");
|
||||
@@ -2143,6 +2165,7 @@ fn renderVar(c: *Context, node: Node) !NodeIndex {
|
||||
if (payload.is_pub) _ = try c.addToken(.keyword_pub, "pub");
|
||||
if (payload.is_extern) _ = try c.addToken(.keyword_extern, "extern");
|
||||
if (payload.is_export) _ = try c.addToken(.keyword_export, "export");
|
||||
if (payload.is_threadlocal) _ = try c.addToken(.keyword_threadlocal, "threadlocal");
|
||||
const mut_tok = if (payload.is_const)
|
||||
try c.addToken(.keyword_const, "const")
|
||||
else
|
||||
|
||||
@@ -3,6 +3,14 @@ const std = @import("std");
|
||||
const CrossTarget = std.zig.CrossTarget;
|
||||
|
||||
pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("use cast param as macro fn return type",
|
||||
\\#define MEM_PHYSICAL_TO_K0(x) (void*)((u32)(x) + SYS_BASE_CACHED)
|
||||
, &[_][]const u8{
|
||||
\\pub fn MEM_PHYSICAL_TO_K0(x: anytype) callconv(.Inline) ?*c_void {
|
||||
\\ return @import("std").meta.cast(?*c_void, @import("std").meta.cast(u32, x) + SYS_BASE_CACHED);
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("variadic function demoted to prototype",
|
||||
\\int foo(int bar, ...) {
|
||||
\\ return 1;
|
||||
@@ -21,11 +29,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ Foo *bar;
|
||||
\\} Bar;
|
||||
, &[_][]const u8{
|
||||
\\const struct_unnamed_1 = //
|
||||
,
|
||||
\\warning: unsupported type: 'Atomic'
|
||||
\\ opaque {}; //
|
||||
,
|
||||
\\source.h:1:9: warning: struct demoted to opaque type - unable to translate type of field foo
|
||||
\\const struct_unnamed_1 = opaque {};
|
||||
\\pub const Foo = struct_unnamed_1;
|
||||
\\const struct_unnamed_2 = extern struct {
|
||||
\\ bar: ?*Foo,
|
||||
@@ -43,8 +48,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
,
|
||||
\\pub const VALUE = ((((1 + (2 * 3)) + (4 * 5)) + 6) << 7) | @boolToInt(8 == 9);
|
||||
,
|
||||
\\pub fn _AL_READ3BYTES(p: anytype) callconv(.Inline) @TypeOf(((@import("std").meta.cast([*c]u8, p)).* | (((@import("std").meta.cast([*c]u8, p)) + 1).* << 8)) | (((@import("std").meta.cast([*c]u8, p)) + 2).* << 16)) {
|
||||
\\ return ((@import("std").meta.cast([*c]u8, p)).* | (((@import("std").meta.cast([*c]u8, p)) + 1).* << 8)) | (((@import("std").meta.cast([*c]u8, p)) + 2).* << 16);
|
||||
\\pub fn _AL_READ3BYTES(p: anytype) callconv(.Inline) @TypeOf((@import("std").meta.cast([*c]u8, p).* | ((@import("std").meta.cast([*c]u8, p) + 1).* << 8)) | ((@import("std").meta.cast([*c]u8, p) + 2).* << 16)) {
|
||||
\\ return (@import("std").meta.cast([*c]u8, p).* | ((@import("std").meta.cast([*c]u8, p) + 1).* << 8)) | ((@import("std").meta.cast([*c]u8, p) + 2).* << 16);
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -107,7 +112,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ int i1;
|
||||
\\} boom_t;
|
||||
\\#define FOO ((boom_t){1})
|
||||
, &[_][]const u8{ // TODO properly translate this
|
||||
, &[_][]const u8{
|
||||
\\pub const struct_Color = extern struct {
|
||||
\\ r: u8,
|
||||
\\ g: u8,
|
||||
@@ -127,7 +132,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
\\pub const boom_t = struct_boom_t;
|
||||
,
|
||||
\\pub const FOO = @import("std").mem.zeroInit(boom_t, .{ 1 });
|
||||
\\pub const FOO = @import("std").mem.zeroInit(boom_t, .{1});
|
||||
});
|
||||
|
||||
cases.add("complex switch",
|
||||
@@ -142,14 +147,34 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ }
|
||||
\\}
|
||||
, &[_][]const u8{ // TODO properly translate this
|
||||
\\pub const main = @compileError("unable to translate function");
|
||||
\\pub export fn main() c_int {
|
||||
\\ var i: c_int = 2;
|
||||
\\ @"switch": {
|
||||
\\ case_1: {
|
||||
\\ case: {
|
||||
\\ switch (i) {
|
||||
\\ @as(c_int, 0) => break :case,
|
||||
\\ @as(c_int, 2) => break :case_1,
|
||||
\\ else => break :@"switch",
|
||||
\\ }
|
||||
\\ }
|
||||
\\ }
|
||||
\\ {
|
||||
\\ {
|
||||
\\ i += @as(c_int, 2);
|
||||
\\ }
|
||||
\\ i += @as(c_int, 1);
|
||||
\\ }
|
||||
\\ }
|
||||
\\ return 0;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("correct semicolon after infixop",
|
||||
\\#define __ferror_unlocked_body(_fp) (((_fp)->_flags & _IO_ERR_SEEN) != 0)
|
||||
, &[_][]const u8{
|
||||
\\pub fn __ferror_unlocked_body(_fp: anytype) callconv(.Inline) @TypeOf(((_fp.*._flags) & _IO_ERR_SEEN) != 0) {
|
||||
\\ return ((_fp.*._flags) & _IO_ERR_SEEN) != 0;
|
||||
\\pub fn __ferror_unlocked_body(_fp: anytype) callconv(.Inline) @TypeOf((_fp.*._flags & _IO_ERR_SEEN) != 0) {
|
||||
\\ return (_fp.*._flags & _IO_ERR_SEEN) != 0;
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -194,7 +219,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ while (false) while (false) {};
|
||||
\\ while (true) while (false) {};
|
||||
\\ while (true) while (true) {
|
||||
\\ if (!false) break;
|
||||
\\ break;
|
||||
\\ };
|
||||
\\}
|
||||
});
|
||||
@@ -245,15 +270,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ volatile _Atomic int abufused[12];
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const struct_arcan_shmif_page = //
|
||||
,
|
||||
\\warning: unsupported type: 'Atomic'
|
||||
\\ opaque {}; //
|
||||
,
|
||||
\\ warning: struct demoted to opaque type - unable to translate type of field abufused
|
||||
, // TODO should be `addr: *struct_arcan_shmif_page`
|
||||
\\source.h:4:8: warning: struct demoted to opaque type - unable to translate type of field abufused
|
||||
\\pub const struct_arcan_shmif_page = opaque {};
|
||||
\\pub const struct_arcan_shmif_cont = extern struct {
|
||||
\\ addr: [*c]struct_arcan_shmif_page,
|
||||
\\ addr: ?*struct_arcan_shmif_page,
|
||||
\\};
|
||||
});
|
||||
|
||||
@@ -514,8 +534,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var a: c_int = undefined;
|
||||
\\ _ = @as(c_int, 1);
|
||||
\\ _ = "hey";
|
||||
\\ _ = (@as(c_int, 1) + @as(c_int, 1));
|
||||
\\ _ = (@as(c_int, 1) - @as(c_int, 1));
|
||||
\\ _ = @as(c_int, 1) + @as(c_int, 1);
|
||||
\\ _ = @as(c_int, 1) - @as(c_int, 1);
|
||||
\\ a = 1;
|
||||
\\}
|
||||
});
|
||||
@@ -634,9 +654,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var a: c_int = undefined;
|
||||
\\ var b: c_int = undefined;
|
||||
\\ var c: c_int = undefined;
|
||||
\\ c = (a + b);
|
||||
\\ c = (a - b);
|
||||
\\ c = (a * b);
|
||||
\\ c = a + b;
|
||||
\\ c = a - b;
|
||||
\\ c = a * b;
|
||||
\\ c = @divTrunc(a, b);
|
||||
\\ c = @rem(a, b);
|
||||
\\ return 0;
|
||||
@@ -645,11 +665,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var a: c_uint = undefined;
|
||||
\\ var b: c_uint = undefined;
|
||||
\\ var c: c_uint = undefined;
|
||||
\\ c = (a +% b);
|
||||
\\ c = (a -% b);
|
||||
\\ c = (a *% b);
|
||||
\\ c = (a / b);
|
||||
\\ c = (a % b);
|
||||
\\ c = a +% b;
|
||||
\\ c = a -% b;
|
||||
\\ c = a *% b;
|
||||
\\ c = a / b;
|
||||
\\ c = a % b;
|
||||
\\ return 0;
|
||||
\\}
|
||||
});
|
||||
@@ -1639,7 +1659,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
cases.add("macro pointer cast",
|
||||
\\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
|
||||
, &[_][]const u8{
|
||||
\\pub const NRF_GPIO = (@import("std").meta.cast([*c]NRF_GPIO_Type, NRF_GPIO_BASE));
|
||||
\\pub const NRF_GPIO = @import("std").meta.cast([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
|
||||
});
|
||||
|
||||
cases.add("basic macro function",
|
||||
@@ -1723,17 +1743,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() c_int {
|
||||
\\ _ = (blk: {
|
||||
\\ _ = blk: {
|
||||
\\ _ = @as(c_int, 2);
|
||||
\\ break :blk @as(c_int, 4);
|
||||
\\ });
|
||||
\\ return (blk: {
|
||||
\\ _ = (blk_1: {
|
||||
\\ };
|
||||
\\ return blk: {
|
||||
\\ _ = blk_1: {
|
||||
\\ _ = @as(c_int, 2);
|
||||
\\ break :blk_1 @as(c_int, 4);
|
||||
\\ });
|
||||
\\ };
|
||||
\\ break :blk @as(c_int, 6);
|
||||
\\ });
|
||||
\\ };
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -1780,20 +1800,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ while (true) {
|
||||
\\ var a_1: c_int = 4;
|
||||
\\ a_1 = 9;
|
||||
\\ return (blk: {
|
||||
\\ return blk: {
|
||||
\\ _ = @as(c_int, 6);
|
||||
\\ break :blk a_1;
|
||||
\\ });
|
||||
\\ };
|
||||
\\ }
|
||||
\\ while (true) {
|
||||
\\ var a_1: c_int = 2;
|
||||
\\ a_1 = 12;
|
||||
\\ if (!true) break;
|
||||
\\ }
|
||||
\\ while (true) {
|
||||
\\ a = 7;
|
||||
\\ if (!true) break;
|
||||
\\ }
|
||||
\\ while (true) a = 7;
|
||||
\\ return 0;
|
||||
\\}
|
||||
});
|
||||
@@ -1813,13 +1829,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var b: c_int = 4;
|
||||
\\ while ((i + @as(c_int, 2)) != 0) : (i = 2) {
|
||||
\\ var a: c_int = 2;
|
||||
\\ _ = (blk: {
|
||||
\\ _ = (blk_1: {
|
||||
\\ _ = blk: {
|
||||
\\ _ = blk_1: {
|
||||
\\ a = 6;
|
||||
\\ break :blk_1 @as(c_int, 5);
|
||||
\\ });
|
||||
\\ };
|
||||
\\ break :blk @as(c_int, 7);
|
||||
\\ });
|
||||
\\ };
|
||||
\\ }
|
||||
\\ }
|
||||
\\ var i: u8 = @bitCast(u8, @truncate(i8, @as(c_int, 2)));
|
||||
@@ -1854,7 +1870,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn bar() c_int {
|
||||
\\ if ((if (true) @as(c_int, 5) else (if (true) @as(c_int, 4) else @as(c_int, 6))) != 0) _ = @as(c_int, 2);
|
||||
\\ if ((if (true) @as(c_int, 5) else if (true) @as(c_int, 4) else @as(c_int, 6)) != 0) _ = @as(c_int, 2);
|
||||
\\ return if (true) @as(c_int, 5) else if (true) @as(c_int, 4) else @as(c_int, 6);
|
||||
\\}
|
||||
});
|
||||
@@ -1894,7 +1910,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ }
|
||||
\\ res = 2;
|
||||
\\ }
|
||||
\\ res = (@as(c_int, 3) * i);
|
||||
\\ res = @as(c_int, 3) * i;
|
||||
\\ break :@"switch";
|
||||
\\ }
|
||||
\\ res = 5;
|
||||
@@ -2043,12 +2059,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: c_int = 2;
|
||||
\\ while (true) {
|
||||
\\ a = (a - @as(c_int, 1));
|
||||
\\ a = a - @as(c_int, 1);
|
||||
\\ if (!(a != 0)) break;
|
||||
\\ }
|
||||
\\ var b: c_int = 2;
|
||||
\\ while (true) {
|
||||
\\ b = (b - @as(c_int, 1));
|
||||
\\ b = b - @as(c_int, 1);
|
||||
\\ if (!(b != 0)) break;
|
||||
\\ }
|
||||
\\}
|
||||
@@ -2078,6 +2094,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub const FooA = @enumToInt(enum_Foo.A);
|
||||
\\pub const FooB = @enumToInt(enum_Foo.B);
|
||||
\\pub const FooC = @enumToInt(enum_Foo.C);
|
||||
\\pub const enum_Foo = extern enum(c_int) {
|
||||
\\ A,
|
||||
\\ B,
|
||||
@@ -2090,19 +2109,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var b = arg_b;
|
||||
\\ var c = arg_c;
|
||||
\\ var d: enum_Foo = @intToEnum(enum_Foo, FooA);
|
||||
\\ var e: c_int = @boolToInt(((a != 0) and (b != 0)));
|
||||
\\ var f: c_int = @boolToInt(((b != 0) and (c != null)));
|
||||
\\ var g: c_int = @boolToInt(((a != 0) and (c != null)));
|
||||
\\ var h: c_int = @boolToInt(((a != 0) or (b != 0)));
|
||||
\\ var i: c_int = @boolToInt(((b != 0) or (c != null)));
|
||||
\\ var j: c_int = @boolToInt(((a != 0) or (c != null)));
|
||||
\\ var k: c_int = @boolToInt(((a != 0) or (@bitCast(c_int, @enumToInt(d)) != 0)));
|
||||
\\ var l: c_int = @boolToInt(((@bitCast(c_int, @enumToInt(d)) != 0) and (b != 0)));
|
||||
\\ var m: c_int = @boolToInt(((c != null) or (@bitCast(c_uint, @enumToInt(d)) != 0)));
|
||||
\\ var e: c_int = @boolToInt((a != 0) and (b != 0));
|
||||
\\ var f: c_int = @boolToInt((b != 0) and (c != null));
|
||||
\\ var g: c_int = @boolToInt((a != 0) and (c != null));
|
||||
\\ var h: c_int = @boolToInt((a != 0) or (b != 0));
|
||||
\\ var i: c_int = @boolToInt((b != 0) or (c != null));
|
||||
\\ var j: c_int = @boolToInt((a != 0) or (c != null));
|
||||
\\ var k: c_int = @boolToInt((a != 0) or (@bitCast(c_int, @enumToInt(d)) != 0));
|
||||
\\ var l: c_int = @boolToInt((@bitCast(c_int, @enumToInt(d)) != 0) and (b != 0));
|
||||
\\ var m: c_int = @boolToInt((c != null) or (@bitCast(c_uint, @enumToInt(d)) != 0));
|
||||
\\ var td: SomeTypedef = 44;
|
||||
\\ var o: c_int = @boolToInt(((td != 0) or (b != 0)));
|
||||
\\ var p: c_int = @boolToInt(((c != null) and (td != 0)));
|
||||
\\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
|
||||
\\ var o: c_int = @boolToInt((td != 0) or (b != 0));
|
||||
\\ var p: c_int = @boolToInt((c != null) and (td != 0));
|
||||
\\ return (((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p;
|
||||
\\}
|
||||
,
|
||||
\\pub const Foo = enum_Foo;
|
||||
@@ -2143,7 +2162,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub export fn max(arg_a: c_int, arg_b: c_int) c_int {
|
||||
\\ var a = arg_a;
|
||||
\\ var b = arg_b;
|
||||
\\ return ((a & b) ^ (a | b));
|
||||
\\ return (a & b) ^ (a | b);
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -2162,13 +2181,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub export fn test_comparisons(arg_a: c_int, arg_b: c_int) c_int {
|
||||
\\ var a = arg_a;
|
||||
\\ var b = arg_b;
|
||||
\\ var c: c_int = @boolToInt((a < b));
|
||||
\\ var d: c_int = @boolToInt((a > b));
|
||||
\\ var e: c_int = @boolToInt((a <= b));
|
||||
\\ var f: c_int = @boolToInt((a >= b));
|
||||
\\ var g: c_int = @boolToInt((c < d));
|
||||
\\ var h: c_int = @boolToInt((e < f));
|
||||
\\ var i: c_int = @boolToInt((g < h));
|
||||
\\ var c: c_int = @boolToInt(a < b);
|
||||
\\ var d: c_int = @boolToInt(a > b);
|
||||
\\ var e: c_int = @boolToInt(a <= b);
|
||||
\\ var f: c_int = @boolToInt(a >= b);
|
||||
\\ var g: c_int = @boolToInt(c < d);
|
||||
\\ var h: c_int = @boolToInt(e < f);
|
||||
\\ var i: c_int = @boolToInt(g < h);
|
||||
\\ return i;
|
||||
\\}
|
||||
});
|
||||
@@ -2215,11 +2234,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() c_int {
|
||||
\\ return (blk: {
|
||||
\\ return blk: {
|
||||
\\ var a: c_int = 1;
|
||||
\\ _ = a;
|
||||
\\ break :blk a;
|
||||
\\ });
|
||||
\\ };
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -2371,9 +2390,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var a: c_int = 2;
|
||||
\\ }
|
||||
\\ if ((blk: {
|
||||
\\ _ = @as(c_int, 2);
|
||||
\\ break :blk @as(c_int, 5);
|
||||
\\ }) != 0) {
|
||||
\\ _ = @as(c_int, 2);
|
||||
\\ break :blk @as(c_int, 5);
|
||||
\\ }) != 0) {
|
||||
\\ var a: c_int = 2;
|
||||
\\ }
|
||||
\\}
|
||||
@@ -2484,10 +2503,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ var f: ?fn () callconv(.C) void = foo;
|
||||
\\ var b: ?fn () callconv(.C) c_int = baz;
|
||||
\\ f.?();
|
||||
\\ (f).?();
|
||||
\\ f.?();
|
||||
\\ foo();
|
||||
\\ _ = b.?();
|
||||
\\ _ = (b).?();
|
||||
\\ _ = b.?();
|
||||
\\ _ = baz();
|
||||
\\}
|
||||
});
|
||||
@@ -2513,26 +2532,26 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ i -= 1;
|
||||
\\ u +%= 1;
|
||||
\\ u -%= 1;
|
||||
\\ i = (blk: {
|
||||
\\ i = blk: {
|
||||
\\ const ref = &i;
|
||||
\\ ref.* += 1;
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ i = (blk: {
|
||||
\\ };
|
||||
\\ i = blk: {
|
||||
\\ const ref = &i;
|
||||
\\ ref.* -= 1;
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ u = (blk: {
|
||||
\\ };
|
||||
\\ u = blk: {
|
||||
\\ const ref = &u;
|
||||
\\ ref.* +%= 1;
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ u = (blk: {
|
||||
\\ };
|
||||
\\ u = blk: {
|
||||
\\ const ref = &u;
|
||||
\\ ref.* -%= 1;
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ };
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -2596,66 +2615,66 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: c_int = 0;
|
||||
\\ var b: c_uint = @bitCast(c_uint, @as(c_int, 0));
|
||||
\\ a += (blk: {
|
||||
\\ a += blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* + @as(c_int, 1);
|
||||
\\ ref.* += @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a -= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* -= @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a *= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* *= @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a &= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* &= @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a |= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* |= @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a ^= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* ^= @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a >>= @intCast(@import("std").math.Log2Int(c_int), blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* >>= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a -= (blk: {
|
||||
\\ a <<= @intCast(@import("std").math.Log2Int(c_int), blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* - @as(c_int, 1);
|
||||
\\ ref.* <<= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a *= (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* * @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a &= (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* & @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a |= (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* | @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a ^= (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* ^ @as(c_int, 1);
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a >>= @intCast(@import("std").math.Log2Int(c_int), (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* >> @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ }));
|
||||
\\ a <<= @intCast(@import("std").math.Log2Int(c_int), (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* << @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ }));
|
||||
\\ a = @divTrunc(a, (blk: {
|
||||
\\ a = @divTrunc(a, blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = @divTrunc(ref.*, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ }));
|
||||
\\ a = @rem(a, (blk: {
|
||||
\\ });
|
||||
\\ a = @rem(a, blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = @rem(ref.*, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ }));
|
||||
\\ b /= (blk: {
|
||||
\\ const ref = &b;
|
||||
\\ ref.* = ref.* / @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ b %= (blk: {
|
||||
\\ b /= blk: {
|
||||
\\ const ref = &b;
|
||||
\\ ref.* = ref.* % @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ ref.* /= @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ };
|
||||
\\ b %= blk: {
|
||||
\\ const ref = &b;
|
||||
\\ ref.* %= @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -2674,46 +2693,46 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo() void {
|
||||
\\ var a: c_uint = @bitCast(c_uint, @as(c_int, 0));
|
||||
\\ a +%= (blk: {
|
||||
\\ a +%= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* +% @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ ref.* +%= @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a -%= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* -%= @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a *%= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* *%= @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a &= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* &= @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a |= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* |= @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a ^= blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* ^= @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ };
|
||||
\\ a >>= @intCast(@import("std").math.Log2Int(c_uint), blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* >>= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a -%= (blk: {
|
||||
\\ a <<= @intCast(@import("std").math.Log2Int(c_uint), blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* -% @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ ref.* <<= @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a *%= (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* *% @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a &= (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* & @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a |= (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* | @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a ^= (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* ^ @bitCast(c_uint, @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ });
|
||||
\\ a >>= @intCast(@import("std").math.Log2Int(c_uint), (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* >> @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ }));
|
||||
\\ a <<= @intCast(@import("std").math.Log2Int(c_uint), (blk: {
|
||||
\\ const ref = &a;
|
||||
\\ ref.* = ref.* << @intCast(@import("std").math.Log2Int(c_int), @as(c_int, 1));
|
||||
\\ break :blk ref.*;
|
||||
\\ }));
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -2738,30 +2757,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ i -= 1;
|
||||
\\ u +%= 1;
|
||||
\\ u -%= 1;
|
||||
\\ i = (blk: {
|
||||
\\ i = blk: {
|
||||
\\ const ref = &i;
|
||||
\\ const tmp = ref.*;
|
||||
\\ ref.* += 1;
|
||||
\\ break :blk tmp;
|
||||
\\ });
|
||||
\\ i = (blk: {
|
||||
\\ };
|
||||
\\ i = blk: {
|
||||
\\ const ref = &i;
|
||||
\\ const tmp = ref.*;
|
||||
\\ ref.* -= 1;
|
||||
\\ break :blk tmp;
|
||||
\\ });
|
||||
\\ u = (blk: {
|
||||
\\ };
|
||||
\\ u = blk: {
|
||||
\\ const ref = &u;
|
||||
\\ const tmp = ref.*;
|
||||
\\ ref.* +%= 1;
|
||||
\\ break :blk tmp;
|
||||
\\ });
|
||||
\\ u = (blk: {
|
||||
\\ };
|
||||
\\ u = blk: {
|
||||
\\ const ref = &u;
|
||||
\\ const tmp = ref.*;
|
||||
\\ ref.* -%= 1;
|
||||
\\ break :blk tmp;
|
||||
\\ });
|
||||
\\ };
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -2872,13 +2891,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define BAR (void*) a
|
||||
\\#define BAZ (uint32_t)(2)
|
||||
, &[_][]const u8{
|
||||
\\pub fn FOO(bar: anytype) callconv(.Inline) @TypeOf(baz((@import("std").meta.cast(?*c_void, baz)))) {
|
||||
\\ return baz((@import("std").meta.cast(?*c_void, baz)));
|
||||
\\pub fn FOO(bar: anytype) callconv(.Inline) @TypeOf(baz(@import("std").meta.cast(?*c_void, baz))) {
|
||||
\\ return baz(@import("std").meta.cast(?*c_void, baz));
|
||||
\\}
|
||||
,
|
||||
\\pub const BAR = (@import("std").meta.cast(?*c_void, a));
|
||||
\\pub const BAR = @import("std").meta.cast(?*c_void, a);
|
||||
,
|
||||
\\pub const BAZ = (@import("std").meta.cast(u32, 2));
|
||||
\\pub const BAZ = @import("std").meta.cast(u32, 2);
|
||||
});
|
||||
|
||||
cases.add("macro with cast to unsigned short, long, and long long",
|
||||
@@ -2886,9 +2905,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define CURLAUTH_BASIC ((unsigned long) 1)
|
||||
\\#define CURLAUTH_BASIC_BUT_ULONGLONG ((unsigned long long) 1)
|
||||
, &[_][]const u8{
|
||||
\\pub const CURLAUTH_BASIC_BUT_USHORT = (@import("std").meta.cast(c_ushort, 1));
|
||||
\\pub const CURLAUTH_BASIC = (@import("std").meta.cast(c_ulong, 1));
|
||||
\\pub const CURLAUTH_BASIC_BUT_ULONGLONG = (@import("std").meta.cast(c_ulonglong, 1));
|
||||
\\pub const CURLAUTH_BASIC_BUT_USHORT = @import("std").meta.cast(c_ushort, 1);
|
||||
\\pub const CURLAUTH_BASIC = @import("std").meta.cast(c_ulong, 1);
|
||||
\\pub const CURLAUTH_BASIC_BUT_ULONGLONG = @import("std").meta.cast(c_ulonglong, 1);
|
||||
});
|
||||
|
||||
cases.add("macro conditional operator",
|
||||
@@ -2905,7 +2924,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub fn foo() callconv(.C) void {
|
||||
\\ if (true) while (true) {
|
||||
\\ if (!false) break;
|
||||
\\ break;
|
||||
\\ };
|
||||
\\}
|
||||
});
|
||||
@@ -2923,27 +2942,27 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
// TODO: detect to use different block labels here
|
||||
cases.add("nested assignment",
|
||||
\\int foo(int *p, int x) {
|
||||
\\ return *p++ = x;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo(arg_p: [*c]c_int, arg_x: c_int) c_int {
|
||||
\\ var p = arg_p;
|
||||
\\ var x = arg_x;
|
||||
\\ return blk: {
|
||||
\\ const tmp = x;
|
||||
\\ (blk_1: {
|
||||
\\ const ref = &p;
|
||||
\\ const tmp_2 = ref.*;
|
||||
\\ ref.* += 1;
|
||||
\\ break :blk_1 tmp_2;
|
||||
\\ }).?.* = tmp;
|
||||
\\ break :blk tmp;
|
||||
\\ };
|
||||
\\}
|
||||
});
|
||||
// TODO fix zig fmt here
|
||||
// cases.add("nested assignment",
|
||||
// \\int foo(int *p, int x) {
|
||||
// \\ return *p++ = x;
|
||||
// \\}
|
||||
// , &[_][]const u8{
|
||||
// \\pub export fn foo(arg_p: [*c]c_int, arg_x: c_int) c_int {
|
||||
// \\ var p = arg_p;
|
||||
// \\ var x = arg_x;
|
||||
// \\ return blk: {
|
||||
// \\ const tmp = x;
|
||||
// \\ (blk_1: {
|
||||
// \\ const ref = &p;
|
||||
// \\ const tmp_2 = ref.*;
|
||||
// \\ ref.* += 1;
|
||||
// \\ break :blk_1 tmp_2;
|
||||
// \\ }).?.* = tmp;
|
||||
// \\ break :blk tmp;
|
||||
// \\ };
|
||||
// \\}
|
||||
// });
|
||||
|
||||
cases.add("widening and truncating integer casting to different signedness",
|
||||
\\unsigned long foo(void) {
|
||||
@@ -3033,10 +3052,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo(arg_x: bool) bool {
|
||||
\\ var x = arg_x;
|
||||
\\ var a: bool = (@as(c_int, @boolToInt(x)) != @as(c_int, 1));
|
||||
\\ var b: bool = (@as(c_int, @boolToInt(a)) != @as(c_int, 0));
|
||||
\\ var a: bool = @as(c_int, @boolToInt(x)) != @as(c_int, 1);
|
||||
\\ var b: bool = @as(c_int, @boolToInt(a)) != @as(c_int, 0);
|
||||
\\ var c: bool = @ptrToInt(foo) != 0;
|
||||
\\ return foo((@as(c_int, @boolToInt(c)) != @as(c_int, @boolToInt(b))));
|
||||
\\ return foo(@as(c_int, @boolToInt(c)) != @as(c_int, @boolToInt(b)));
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -3106,8 +3125,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define DefaultScreen(dpy) (((_XPrivDisplay)(dpy))->default_screen)
|
||||
\\
|
||||
, &[_][]const u8{
|
||||
\\pub fn DefaultScreen(dpy: anytype) callconv(.Inline) @TypeOf((@import("std").meta.cast(_XPrivDisplay, dpy)).*.default_screen) {
|
||||
\\ return (@import("std").meta.cast(_XPrivDisplay, dpy)).*.default_screen;
|
||||
\\pub fn DefaultScreen(dpy: anytype) callconv(.Inline) @TypeOf(@import("std").meta.cast(_XPrivDisplay, dpy).*.default_screen) {
|
||||
\\ return @import("std").meta.cast(_XPrivDisplay, dpy).*.default_screen;
|
||||
\\}
|
||||
});
|
||||
|
||||
@@ -3115,9 +3134,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\#define NULL ((void*)0)
|
||||
\\#define FOO ((int)0x8000)
|
||||
, &[_][]const u8{
|
||||
\\pub const NULL = (@import("std").meta.cast(?*c_void, 0));
|
||||
\\pub const NULL = @import("std").meta.cast(?*c_void, 0);
|
||||
,
|
||||
\\pub const FOO = (@import("std").meta.cast(c_int, 0x8000));
|
||||
\\pub const FOO = @import("std").meta.cast(c_int, 0x8000);
|
||||
});
|
||||
|
||||
if (std.Target.current.abi == .msvc) {
|
||||
|
||||
Reference in New Issue
Block a user