Commit 62bfff5e87
Changed files (3)
lib/std/zig/render.zig
@@ -1629,7 +1629,7 @@ fn renderExpression(
.If => {
const if_node = @fieldParentPtr(ast.Node.If, "base", base);
- const lparen = tree.prevToken(if_node.condition.firstToken());
+ const lparen = tree.nextToken(if_node.if_token);
const rparen = tree.nextToken(if_node.condition.lastToken());
try renderToken(tree, stream, if_node.if_token, indent, start_col, Space.Space); // if
src-self-hosted/translate_c.zig
@@ -954,13 +954,6 @@ fn transBinaryOperator(
}
const lhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
switch (op) {
- .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn(
- rp,
- error.UnsupportedTranslation,
- ZigClangBinaryOperator_getBeginLoc(stmt),
- "TODO: handle more C binary operators: {}",
- .{op},
- ),
.Add => {
if (cIsUnsignedInteger(qt)) {
op_token = try appendToken(rp.c, .PlusPercent, "+%");
@@ -1205,6 +1198,26 @@ fn transBoolExpr(
undefined;
var res = try transExpr(rp, scope, expr, used, lrvalue);
+ if (isBoolRes(res))
+ return res;
+ const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr));
+ const node = try finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used);
+
+ if (grouped) {
+ const rparen = try appendToken(rp.c, .RParen, ")");
+ const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ grouped_expr.* = .{
+ .lparen = lparen,
+ .expr = node,
+ .rparen = rparen,
+ };
+ return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
+ } else {
+ return maybeSuppressResult(rp, scope, used, node);
+ }
+}
+
+fn isBoolRes(res: *ast.Node) bool {
switch (res.id) {
.InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {
.BoolOr,
@@ -1215,23 +1228,20 @@ fn transBoolExpr(
.GreaterThan,
.LessOrEqual,
.GreaterOrEqual,
- => return res,
+ => return true,
else => {},
},
-
.PrefixOp => switch (@fieldParentPtr(ast.Node.PrefixOp, "base", res).op) {
- .BoolNot => return res,
+ .BoolNot => return true,
else => {},
},
-
- .BoolLiteral => return res,
-
+ .BoolLiteral => return true,
+ .GroupedExpression => return isBoolRes(@fieldParentPtr(ast.Node.GroupedExpression, "base", res).expr),
else => {},
}
- const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr));
- return finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used, grouped);
+ return false;
}
fn finishBoolExpr(
@@ -1241,14 +1251,13 @@ fn finishBoolExpr(
ty: *const ZigClangType,
node: *ast.Node,
used: ResultUsed,
- grouped: bool,
) TransError!*ast.Node {
switch (ZigClangType_getTypeClass(ty)) {
.Builtin => {
const builtin_ty = @ptrCast(*const ZigClangBuiltinType, ty);
switch (ZigClangBuiltinType_getKind(builtin_ty)) {
- .Bool,
+ .Bool => return node,
.Char_U,
.UChar,
.Char_S,
@@ -1276,12 +1285,12 @@ fn finishBoolExpr(
=> {
const op_token = try appendToken(rp.c, .BangEqual, "!=");
const rhs_node = try transCreateNodeInt(rp.c, 0);
- return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, grouped);
+ return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, false);
},
.NullPtr => {
const op_token = try appendToken(rp.c, .EqualEqual, "==");
const rhs_node = try transCreateNodeNullLiteral(rp.c);
- return transCreateNodeInfixOp(rp, scope, node, .EqualEqual, op_token, rhs_node, used, grouped);
+ return transCreateNodeInfixOp(rp, scope, node, .EqualEqual, op_token, rhs_node, used, false);
},
else => {},
}
@@ -1289,13 +1298,13 @@ fn finishBoolExpr(
.Pointer => {
const op_token = try appendToken(rp.c, .BangEqual, "!=");
const rhs_node = try transCreateNodeNullLiteral(rp.c);
- return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, grouped);
+ return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, used, false);
},
.Typedef => {
const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
const underlying_type = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
- return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(underlying_type), node, used, grouped);
+ return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(underlying_type), node, used);
},
.Enum => {
const enum_ty = @ptrCast(*const ZigClangEnumType, ty);
@@ -1305,12 +1314,12 @@ fn finishBoolExpr(
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, grouped);
+ return transCreateNodeInfixOp(rp, scope, &builtin_node.base, .BangEqual, op_token, rhs_node, used, false);
},
.Elaborated => {
const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty);
const named_type = ZigClangElaboratedType_getNamedType(elaborated_ty);
- return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(named_type), node, used, grouped);
+ return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(named_type), node, used);
},
else => {},
}
@@ -2009,8 +2018,8 @@ fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFl
}
fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangConditionalOperator, used: ResultUsed) TransError!*ast.Node {
- const gropued = scope.id == .Condition;
- const lparen = if (gropued) try appendToken(rp.c, .LParen, "(") else undefined;
+ const grouped = scope.id == .Condition;
+ const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined;
const if_node = try transCreateNodeIf(rp.c);
var cond_scope = Scope{
.parent = scope,
@@ -2029,7 +2038,7 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla
if_node.@"else" = try transCreateNodeElse(rp.c);
if_node.@"else".?.body = try transExpr(rp, scope, false_expr, .used, .r_value);
- if (gropued) {
+ if (grouped) {
const rparen = try appendToken(rp.c, .RParen, ")");
const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
grouped_expr.* = .{
test/translate_c.zig
@@ -1400,17 +1400,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const Bar = enum_Bar;
});
- cases.add_2("bitwise binary operators, simpler parens", // TODO can combine with "bitwise binary operators" when parens are correctly preserved/not added in translate-c-2
+ cases.add_2("bitwise binary operators, simpler parens",
\\int max(int a, int b) {
- \\ int c = (a & b);
- \\ int d = (a | b);
- \\ return (c ^ d);
+ \\ return (a & b) ^ (a | b);
\\}
, &[_][]const u8{
\\pub export fn max(a: c_int, b: c_int) c_int {
- \\ var c: c_int = (a & b);
- \\ var d: c_int = (a | b);
- \\ return (c ^ d);
+ \\ return ((a & b) ^ (a | b));
\\}
});
@@ -1438,17 +1434,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("==, !=, no if", // TODO remove this test after `if` conversion supported, and switch "==, !=" to addC_both
+ cases.add_2("==, !=",
\\int max(int a, int b) {
- \\ int c = (a == b);
- \\ int d = (a != b);
- \\ return (c != d);
+ \\ if (a == b)
+ \\ return a;
+ \\ if (a != b)
+ \\ return b;
+ \\ return a;
\\}
, &[_][]const u8{
\\pub export fn max(a: c_int, b: c_int) c_int {
- \\ var c: c_int = (a == b);
- \\ var d: c_int = (a != b);
- \\ return (c != d);
+ \\ if ((a == b)) return a;
+ \\ if ((a != b)) return b;
+ \\ return a;
\\}
});
@@ -1464,6 +1462,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
+ cases.add_2("typedeffed bool expression",
+ \\typedef char* yes;
+ \\void foo(void) {
+ \\ yes a;
+ \\ if (a) 2;
+ \\}
+ , &[_][]const u8{
+ \\pub const yes = [*c]u8;
+ \\pub export fn foo() void {
+ \\ var a: yes = undefined;
+ \\ if (a != null) _ = 2;
+ \\}
+ });
+
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
cases.addAllowWarnings("simple data types",
@@ -1575,31 +1587,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC("==, !=",
- \\int max(int a, int b) {
- \\ if (a == b)
- \\ return a;
- \\ if (a != b)
- \\ return b;
- \\ return a;
- \\}
- , &[_][]const u8{
- \\pub export fn max(a: c_int, b: c_int) c_int {
- \\ if (a == b) return a;
- \\ if (a != b) return b;
- \\ return a;
- \\}
- });
- cases.addC("bitwise binary operators",
- \\int max(int a, int b) {
- \\ return (a & b) ^ (a | b);
- \\}
- , &[_][]const u8{
- \\pub export fn max(a: c_int, b: c_int) c_int {
- \\ return (a & b) ^ (a | b);
- \\}
- });
-
cases.addC("logical and, logical or",
\\int max(int a, int b) {
\\ if (a < b || a == b)
@@ -2596,4 +2583,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ }
\\}
});
+
+ cases.addC("==, !=",
+ \\int max(int a, int b) {
+ \\ if (a == b)
+ \\ return a;
+ \\ if (a != b)
+ \\ return b;
+ \\ return a;
+ \\}
+ , &[_][]const u8{
+ \\pub export fn max(a: c_int, b: c_int) c_int {
+ \\ if (a == b) return a;
+ \\ if (a != b) return b;
+ \\ return a;
+ \\}
+ });
+
+ cases.addC("bitwise binary operators",
+ \\int max(int a, int b) {
+ \\ return (a & b) ^ (a | b);
+ \\}
+ , &[_][]const u8{
+ \\pub export fn max(a: c_int, b: c_int) c_int {
+ \\ return (a & b) ^ (a | b);
+ \\}
+ });
}