mirror of
https://github.com/ziglang/zig.git
synced 2026-01-02 03:25:01 +00:00
translate-c-2 fix some casts
This commit is contained in:
parent
d54c288bd3
commit
122a9bad39
@ -761,6 +761,8 @@ pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumTyp
|
||||
pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl;
|
||||
pub extern fn ZigClangEnumDecl_getCanonicalDecl(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;
|
||||
pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(self: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
|
||||
pub extern fn ZigClangFunctionDecl_getCanonicalDecl(self: ?*const struct_ZigClangFunctionDecl) ?*const struct_ZigClangFunctionDecl;
|
||||
pub extern fn ZigClangVarDecl_getCanonicalDecl(self: ?*const struct_ZigClangVarDecl) ?*const struct_ZigClangVarDecl;
|
||||
pub extern fn ZigClangRecordDecl_getDefinition(self: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl;
|
||||
pub extern fn ZigClangEnumDecl_getDefinition(self: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl;
|
||||
pub extern fn ZigClangRecordDecl_getLocation(self: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation;
|
||||
|
||||
@ -375,7 +375,8 @@ fn declVisitor(c: *Context, decl: *const ZigClangDecl) Error!void {
|
||||
}
|
||||
|
||||
fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
|
||||
if (c.decl_table.contains(@ptrToInt(fn_decl))) return; // Avoid processing this decl twice
|
||||
if (c.decl_table.contains(@ptrToInt(ZigClangFunctionDecl_getCanonicalDecl(fn_decl))))
|
||||
return; // Avoid processing this decl twice
|
||||
const rp = makeRestorePoint(c);
|
||||
const fn_name = try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, fn_decl)));
|
||||
_ = try c.decl_table.put(@ptrToInt(fn_decl), fn_name);
|
||||
@ -442,7 +443,8 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void {
|
||||
}
|
||||
|
||||
fn visitVarDecl(c: *Context, var_decl: *const ZigClangVarDecl) Error!void {
|
||||
if (c.decl_table.contains(@ptrToInt(var_decl))) return; // Avoid processing this decl twice
|
||||
if (c.decl_table.contains(@ptrToInt(ZigClangVarDecl_getCanonicalDecl(var_decl))))
|
||||
return; // Avoid processing this decl twice
|
||||
const rp = makeRestorePoint(c);
|
||||
const visib_tok = try appendToken(c, .Keyword_pub, "pub");
|
||||
|
||||
@ -1115,10 +1117,17 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
|
||||
node.type_node = try transQualType(rp, qual_type, loc);
|
||||
|
||||
node.eq_token = try appendToken(c, .Equal, "=");
|
||||
node.init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|
|
||||
var init_node = if (ZigClangVarDecl_getInit(var_decl)) |expr|
|
||||
try transExpr(rp, scope, expr, .used, .r_value)
|
||||
else
|
||||
try transCreateNodeUndefinedLiteral(c);
|
||||
if (isBoolRes(init_node)) {
|
||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
||||
try builtin_node.params.push(init_node);
|
||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
init_node = &builtin_node.base;
|
||||
}
|
||||
node.init_node = init_node;
|
||||
node.semicolon_token = try appendToken(c, .Semicolon, ";");
|
||||
try block_scope.block_node.statements.push(&node.base);
|
||||
},
|
||||
@ -1300,14 +1309,9 @@ fn finishBoolExpr(
|
||||
return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(underlying_type), node, used);
|
||||
},
|
||||
.Enum => {
|
||||
const enum_ty = @ptrCast(*const ZigClangEnumType, ty);
|
||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt");
|
||||
try builtin_node.params.push(node);
|
||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
|
||||
const op_token = try appendToken(rp.c, .BangEqual, "!=");
|
||||
const rhs_node = try transCreateNodeInt(rp.c, 0);
|
||||
return transCreateNodeInfixOp(rp, scope, &builtin_node.base, .BangEqual, op_token, rhs_node, used, false);
|
||||
return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, false);
|
||||
},
|
||||
.Elaborated => {
|
||||
const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty);
|
||||
@ -1472,6 +1476,31 @@ fn transCCast(
|
||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
return &builtin_node.base;
|
||||
}
|
||||
if (ZigClangQualType_getTypeClass(src_type) == .Elaborated) {
|
||||
const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(src_type));
|
||||
return transCCast(rp, scope, loc, dst_type, ZigClangElaboratedType_getNamedType(elaborated_ty), expr);
|
||||
}
|
||||
if (ZigClangQualType_getTypeClass(dst_type) == .Elaborated) {
|
||||
const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(dst_type));
|
||||
return transCCast(rp, scope, loc, ZigClangElaboratedType_getNamedType(elaborated_ty), src_type, expr);
|
||||
}
|
||||
if (ZigClangQualType_getTypeClass(src_type) == .Enum and
|
||||
ZigClangQualType_getTypeClass(dst_type) != .Enum) {
|
||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt");
|
||||
try builtin_node.params.push(expr);
|
||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
return &builtin_node.base;
|
||||
}
|
||||
// TODO
|
||||
// if (ZigClangQualType_getTypeClass(dst_type) == .Enum and
|
||||
// ZigClangQualType_getTypeClass(src_type) != .Enum) {
|
||||
// const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
|
||||
// try builtin_node.params.push(try transQualType(rp, dst_type, loc));
|
||||
// _ = try appendToken(rp.c, .Comma, ",");
|
||||
// try builtin_node.params.push(expr);
|
||||
// builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
// return &builtin_node.base;
|
||||
// }
|
||||
// TODO: maybe widen to increase size
|
||||
// TODO: maybe bitcast to change sign
|
||||
// TODO: maybe truncate to reduce size
|
||||
@ -2443,7 +2472,13 @@ fn transCreateNodeAssign(
|
||||
if (result_used == .unused) {
|
||||
const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
|
||||
const eq_token = try appendToken(rp.c, .Equal, "=");
|
||||
const rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
|
||||
var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
|
||||
if (isBoolRes(rhs_node)) {
|
||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
||||
try builtin_node.params.push(rhs_node);
|
||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
rhs_node = &builtin_node.base;
|
||||
}
|
||||
if (scope.id != .Condition)
|
||||
_ = try appendToken(rp.c, .Semicolon, ";");
|
||||
|
||||
@ -2471,7 +2506,14 @@ fn transCreateNodeAssign(
|
||||
|
||||
const node = try transCreateNodeVarDecl(rp.c, false, true, tmp);
|
||||
node.eq_token = try appendToken(rp.c, .Equal, "=");
|
||||
node.init_node = try transExpr(rp, scope, rhs, .used, .r_value);
|
||||
var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
|
||||
if (isBoolRes(rhs_node)) {
|
||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
||||
try builtin_node.params.push(rhs_node);
|
||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
rhs_node = &builtin_node.base;
|
||||
}
|
||||
node.init_node = rhs_node;
|
||||
node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
|
||||
try block_scope.block_node.statements.push(&node.base);
|
||||
|
||||
|
||||
@ -1571,6 +1571,16 @@ const ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const Zi
|
||||
return reinterpret_cast<const ZigClangTypedefNameDecl *>(decl);
|
||||
}
|
||||
|
||||
const ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self) {
|
||||
const clang::FunctionDecl *decl = reinterpret_cast<const clang::FunctionDecl*>(self)->getCanonicalDecl();
|
||||
return reinterpret_cast<const ZigClangFunctionDecl *>(decl);
|
||||
}
|
||||
|
||||
const ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self) {
|
||||
const clang::VarDecl *decl = reinterpret_cast<const clang::VarDecl*>(self)->getCanonicalDecl();
|
||||
return reinterpret_cast<const ZigClangVarDecl *>(decl);
|
||||
}
|
||||
|
||||
const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *zig_record_decl) {
|
||||
const clang::RecordDecl *record_decl = reinterpret_cast<const clang::RecordDecl *>(zig_record_decl);
|
||||
const clang::RecordDecl *definition = record_decl->getDefinition();
|
||||
|
||||
@ -856,6 +856,8 @@ ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumType_getDecl(const struc
|
||||
ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const struct ZigClangRecordDecl *record_decl);
|
||||
ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const struct ZigClangEnumDecl *);
|
||||
ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *);
|
||||
ZIG_EXTERN_C const struct ZigClangFunctionDecl *ZigClangFunctionDecl_getCanonicalDecl(const ZigClangFunctionDecl *self);
|
||||
ZIG_EXTERN_C const struct ZigClangVarDecl *ZigClangVarDecl_getCanonicalDecl(const ZigClangVarDecl *self);
|
||||
|
||||
ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);
|
||||
ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);
|
||||
|
||||
@ -716,6 +716,38 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC_both("while on non-bool",
|
||||
\\int while_none_bool(int a, float b, void *c) {
|
||||
\\ while (a) return 0;
|
||||
\\ while (b) return 1;
|
||||
\\ while (c) return 2;
|
||||
\\ return 3;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\ while (a != 0) return 0;
|
||||
\\ while (b != 0) return 1;
|
||||
\\ while (c != null) return 2;
|
||||
\\ return 3;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC_both("for on non-bool",
|
||||
\\int for_none_bool(int a, float b, void *c) {
|
||||
\\ for (;a;) return 0;
|
||||
\\ for (;b;) return 1;
|
||||
\\ for (;c;) return 2;
|
||||
\\ return 3;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\ while (a != 0) return 0;
|
||||
\\ while (b != 0) return 1;
|
||||
\\ while (c != null) return 2;
|
||||
\\ return 3;
|
||||
\\}
|
||||
});
|
||||
|
||||
/////////////// Cases that pass for only stage2 ////////////////
|
||||
|
||||
cases.add_2("Parameterless function prototypes",
|
||||
@ -1369,18 +1401,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\pub const SomeTypedef = c_int;
|
||||
\\pub export fn and_or_non_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\ var d: enum_Foo = @as(enum_Foo, FooA);
|
||||
\\ var e: c_int = ((a != 0) and (b != 0));
|
||||
\\ var f: c_int = ((b != 0) and (c != null));
|
||||
\\ var g: c_int = ((a != 0) and (c != null));
|
||||
\\ var h: c_int = ((a != 0) or (b != 0));
|
||||
\\ var i: c_int = ((b != 0) or (c != null));
|
||||
\\ var j: c_int = ((a != 0) or (c != null));
|
||||
\\ var k: c_int = ((a != 0) or (@enumToInt(@as(c_uint, d)) != 0));
|
||||
\\ var l: c_int = ((@enumToInt(@as(c_uint, d)) != 0) and (b != 0));
|
||||
\\ var m: c_int = ((c != null) or (@enumToInt(@as(c_uint, 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 (@enumToInt(d) != 0)));
|
||||
\\ var l: c_int = @boolToInt(((@enumToInt(d) != 0) and (b != 0)));
|
||||
\\ var m: c_int = @boolToInt(((c != null) or (@enumToInt(d) != 0)));
|
||||
\\ var td: SomeTypedef = 44;
|
||||
\\ var o: c_int = ((td != 0) or (b != 0));
|
||||
\\ var p: c_int = ((c != null) and (td != 0));
|
||||
\\ 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);
|
||||
\\}
|
||||
,
|
||||
@ -1437,13 +1469,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn test_comparisons(a: c_int, b: c_int) c_int {
|
||||
\\ var c: c_int = (a < b);
|
||||
\\ var d: c_int = (a > b);
|
||||
\\ var e: c_int = (a <= b);
|
||||
\\ var f: c_int = (a >= b);
|
||||
\\ var g: c_int = (c < d);
|
||||
\\ var h: c_int = (e < f);
|
||||
\\ var i: c_int = (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;
|
||||
\\}
|
||||
});
|
||||
@ -1560,6 +1592,69 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add_2("logical and, logical or",
|
||||
\\int max(int a, int b) {
|
||||
\\ if (a < b || a == b)
|
||||
\\ return b;
|
||||
\\ if (a >= b && a == b)
|
||||
\\ return a;
|
||||
\\ return a;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn max(a: c_int, b: c_int) c_int {
|
||||
\\ if (((a < b) or (a == b))) return b;
|
||||
\\ if (((a >= b) and (a == b))) return a;
|
||||
\\ return a;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add_2("if statement",
|
||||
\\int max(int a, int b) {
|
||||
\\ if (a < b)
|
||||
\\ return b;
|
||||
\\
|
||||
\\ if (a < b)
|
||||
\\ return b;
|
||||
\\ else
|
||||
\\ return a;
|
||||
\\
|
||||
\\ if (a < b) ; else ;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn max(a: c_int, b: c_int) c_int {
|
||||
\\ if ((a < b)) return b;
|
||||
\\ if ((a < b)) return b else return a;
|
||||
\\ if ((a < b)) {} else {}
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add_2("if on non-bool",
|
||||
\\enum SomeEnum { A, B, C };
|
||||
\\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
|
||||
\\ if (a) return 0;
|
||||
\\ if (b) return 1;
|
||||
\\ if (c) return 2;
|
||||
\\ if (d) return 3;
|
||||
\\ return 4;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub const A = enum_SomeEnum.A;
|
||||
\\pub const B = enum_SomeEnum.B;
|
||||
\\pub const C = enum_SomeEnum.C;
|
||||
\\pub const enum_SomeEnum = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
\\ C,
|
||||
\\};
|
||||
\\pub export fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
|
||||
\\ if (a != 0) return 0;
|
||||
\\ if (b != 0) return 1;
|
||||
\\ if (c != null) return 2;
|
||||
\\ if (d != 0) return 3;
|
||||
\\ return 4;
|
||||
\\}
|
||||
});
|
||||
|
||||
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
|
||||
|
||||
cases.addAllowWarnings("simple data types",
|
||||
@ -1651,85 +1746,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("if statement",
|
||||
\\int max(int a, int b) {
|
||||
\\ if (a < b)
|
||||
\\ return b;
|
||||
\\
|
||||
\\ if (a < b)
|
||||
\\ return b;
|
||||
\\ else
|
||||
\\ return a;
|
||||
\\
|
||||
\\ if (a < b) ; else ;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn max(a: c_int, b: c_int) c_int {
|
||||
\\ if (a < b) return b;
|
||||
\\ if (a < b) return b else return a;
|
||||
\\ if (a < b) {} else {}
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("logical and, logical or",
|
||||
\\int max(int a, int b) {
|
||||
\\ if (a < b || a == b)
|
||||
\\ return b;
|
||||
\\ if (a >= b && a == b)
|
||||
\\ return a;
|
||||
\\ return a;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn max(a: c_int, b: c_int) c_int {
|
||||
\\ if ((a < b) or (a == b)) return b;
|
||||
\\ if ((a >= b) and (a == b)) return a;
|
||||
\\ return a;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("logical and, logical or, on non-bool values", // Note this gets cut off by extra C symbols being injected in middle: `pub const Foo = enum_Foo;`
|
||||
\\enum Foo {
|
||||
\\ FooA,
|
||||
\\ FooB,
|
||||
\\ FooC,
|
||||
\\};
|
||||
\\int and_or_non_bool(int a, float b, void *c) {
|
||||
\\ enum Foo d = FooA;
|
||||
\\ int e = (a && b);
|
||||
\\ int f = (b && c);
|
||||
\\ int g = (a && c);
|
||||
\\ int h = (a || b);
|
||||
\\ int i = (b || c);
|
||||
\\ int j = (a || c);
|
||||
\\ int k = (a || d);
|
||||
\\ int l = (d && b);
|
||||
\\ int m = (c || d);
|
||||
\\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub const FooA = enum_Foo.A;
|
||||
\\pub const FooB = enum_Foo.B;
|
||||
\\pub const FooC = enum_Foo.C;
|
||||
\\pub const enum_Foo = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
\\ C,
|
||||
\\};
|
||||
\\pub export fn and_or_non_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\ var d: enum_Foo = @as(enum_Foo, FooA);
|
||||
\\ var e: c_int = (a != 0) and (b != 0);
|
||||
\\ var f: c_int = (b != 0) and (c != null);
|
||||
\\ var g: c_int = (a != 0) and (c != null);
|
||||
\\ var h: c_int = (a != 0) or (b != 0);
|
||||
\\ var i: c_int = (b != 0) or (c != null);
|
||||
\\ var j: c_int = (a != 0) or (c != null);
|
||||
\\ var k: c_int = (a != 0) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
|
||||
\\ var l: c_int = (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))) and (b != 0);
|
||||
\\ var m: c_int = (c != null) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
|
||||
\\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("shift right assign with a fixed size type",
|
||||
\\#include <stdint.h>
|
||||
\\int log2(uint32_t a) {
|
||||
@ -2043,26 +2059,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("variable name shadowing",
|
||||
\\int foo(void) {
|
||||
\\ int x = 1;
|
||||
\\ {
|
||||
\\ int x = 2;
|
||||
\\ x += 1;
|
||||
\\ }
|
||||
\\ return x;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub fn foo() c_int {
|
||||
\\ var x: c_int = 1;
|
||||
\\ {
|
||||
\\ var x_0: c_int = 2;
|
||||
\\ x_0 += 1;
|
||||
\\ }
|
||||
\\ return x;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("bin not",
|
||||
\\int foo(int x) {
|
||||
\\ return ~x;
|
||||
@ -2099,65 +2095,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("if on non-bool",
|
||||
\\enum SomeEnum { A, B, C };
|
||||
\\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
|
||||
\\ if (a) return 0;
|
||||
\\ if (b) return 1;
|
||||
\\ if (c) return 2;
|
||||
\\ if (d) return 3;
|
||||
\\ return 4;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub const A = enum_SomeEnum.A;
|
||||
\\pub const B = enum_SomeEnum.B;
|
||||
\\pub const C = enum_SomeEnum.C;
|
||||
\\pub const enum_SomeEnum = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
\\ C,
|
||||
\\};
|
||||
\\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
|
||||
\\ if (a != 0) return 0;
|
||||
\\ if (b != 0) return 1;
|
||||
\\ if (c != null) return 2;
|
||||
\\ if (d != @bitCast(enum_SomeEnum, @as(@TagType(enum_SomeEnum), 0))) return 3;
|
||||
\\ return 4;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("while on non-bool",
|
||||
\\int while_none_bool(int a, float b, void *c) {
|
||||
\\ while (a) return 0;
|
||||
\\ while (b) return 1;
|
||||
\\ while (c) return 2;
|
||||
\\ return 3;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\ while (a != 0) return 0;
|
||||
\\ while (b != 0) return 1;
|
||||
\\ while (c != null) return 2;
|
||||
\\ return 3;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("for on non-bool",
|
||||
\\int for_none_bool(int a, float b, void *c) {
|
||||
\\ for (;a;) return 0;
|
||||
\\ for (;b;) return 1;
|
||||
\\ for (;c;) return 2;
|
||||
\\ return 3;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\ while (a != 0) return 0;
|
||||
\\ while (b != 0) return 1;
|
||||
\\ while (c != null) return 2;
|
||||
\\ return 3;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("implicit casts",
|
||||
\\#include <stdbool.h>
|
||||
\\
|
||||
@ -2675,4 +2612,130 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\ return array[index];
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("logical and, logical or",
|
||||
\\int max(int a, int b) {
|
||||
\\ if (a < b || a == b)
|
||||
\\ return b;
|
||||
\\ if (a >= b && a == b)
|
||||
\\ return a;
|
||||
\\ return a;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn max(a: c_int, b: c_int) c_int {
|
||||
\\ if ((a < b) or (a == b)) return b;
|
||||
\\ if ((a >= b) and (a == b)) return a;
|
||||
\\ return a;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("if statement",
|
||||
\\int max(int a, int b) {
|
||||
\\ if (a < b)
|
||||
\\ return b;
|
||||
\\
|
||||
\\ if (a < b)
|
||||
\\ return b;
|
||||
\\ else
|
||||
\\ return a;
|
||||
\\
|
||||
\\ if (a < b) ; else ;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub export fn max(a: c_int, b: c_int) c_int {
|
||||
\\ if (a < b) return b;
|
||||
\\ if (a < b) return b else return a;
|
||||
\\ if (a < b) {} else {}
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.addC("logical and, logical or, on non-bool values", // Note this gets cut off by extra C symbols being injected in middle: `pub const Foo = enum_Foo;`
|
||||
\\enum Foo {
|
||||
\\ FooA,
|
||||
\\ FooB,
|
||||
\\ FooC,
|
||||
\\};
|
||||
\\int and_or_non_bool(int a, float b, void *c) {
|
||||
\\ enum Foo d = FooA;
|
||||
\\ int e = (a && b);
|
||||
\\ int f = (b && c);
|
||||
\\ int g = (a && c);
|
||||
\\ int h = (a || b);
|
||||
\\ int i = (b || c);
|
||||
\\ int j = (a || c);
|
||||
\\ int k = (a || d);
|
||||
\\ int l = (d && b);
|
||||
\\ int m = (c || d);
|
||||
\\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub const FooA = enum_Foo.A;
|
||||
\\pub const FooB = enum_Foo.B;
|
||||
\\pub const FooC = enum_Foo.C;
|
||||
\\pub const enum_Foo = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
\\ C,
|
||||
\\};
|
||||
\\pub export fn and_or_non_bool(a: c_int, b: f32, c: ?*c_void) c_int {
|
||||
\\ var d: enum_Foo = @as(enum_Foo, FooA);
|
||||
\\ var e: c_int = (a != 0) and (b != 0);
|
||||
\\ var f: c_int = (b != 0) and (c != null);
|
||||
\\ var g: c_int = (a != 0) and (c != null);
|
||||
\\ var h: c_int = (a != 0) or (b != 0);
|
||||
\\ var i: c_int = (b != 0) or (c != null);
|
||||
\\ var j: c_int = (a != 0) or (c != null);
|
||||
\\ var k: c_int = (a != 0) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
|
||||
\\ var l: c_int = (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))) and (b != 0);
|
||||
\\ var m: c_int = (c != null) or (@as(c_uint, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
|
||||
\\ return (((((((e + f) + g) + h) + i) + j) + k) + l) + m;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("variable name shadowing",
|
||||
\\int foo(void) {
|
||||
\\ int x = 1;
|
||||
\\ {
|
||||
\\ int x = 2;
|
||||
\\ x += 1;
|
||||
\\ }
|
||||
\\ return x;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub fn foo() c_int {
|
||||
\\ var x: c_int = 1;
|
||||
\\ {
|
||||
\\ var x_0: c_int = 2;
|
||||
\\ x_0 += 1;
|
||||
\\ }
|
||||
\\ return x;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("if on non-bool",
|
||||
\\enum SomeEnum { A, B, C };
|
||||
\\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
|
||||
\\ if (a) return 0;
|
||||
\\ if (b) return 1;
|
||||
\\ if (c) return 2;
|
||||
\\ if (d) return 3;
|
||||
\\ return 4;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub const A = enum_SomeEnum.A;
|
||||
\\pub const B = enum_SomeEnum.B;
|
||||
\\pub const C = enum_SomeEnum.C;
|
||||
\\pub const enum_SomeEnum = extern enum {
|
||||
\\ A,
|
||||
\\ B,
|
||||
\\ C,
|
||||
\\};
|
||||
\\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
|
||||
\\ if (a != 0) return 0;
|
||||
\\ if (b != 0) return 1;
|
||||
\\ if (c != null) return 2;
|
||||
\\ if (d != @bitCast(enum_SomeEnum, @as(@TagType(enum_SomeEnum), 0))) return 3;
|
||||
\\ return 4;
|
||||
\\}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user