Commit f54e7d6c99
Changed files (3)
src-self-hosted
test
src-self-hosted/clang.zig
@@ -741,6 +741,11 @@ pub const ZigClangPreprocessedEntity_EntityKind = extern enum {
InclusionDirectiveKind,
};
+pub const ZigClangExpr_ConstExprUsage = extern enum {
+ EvaluateForCodeGen,
+ EvaluateForMangling,
+};
+
pub extern fn ZigClangSourceManager_getSpellingLoc(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation;
pub extern fn ZigClangSourceManager_getFilename(self: *const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) ?[*:0]const u8;
pub extern fn ZigClangSourceManager_getSpellingLineNumber(self: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint;
src-self-hosted/translate_c.zig
@@ -184,9 +184,7 @@ const Scope = struct {
.Ref => null,
.FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name),
.Block => @fieldParentPtr(Block, "base", scope).getAlias(name),
- .Switch,
- .Loop,
- .Condition => scope.parent.?.getAlias(name),
+ .Switch, .Loop, .Condition => scope.parent.?.getAlias(name),
};
}
@@ -196,9 +194,7 @@ const Scope = struct {
.Root => @fieldParentPtr(Root, "base", scope).contains(name),
.FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name),
.Block => @fieldParentPtr(Block, "base", scope).contains(name),
- .Switch,
- .Loop,
- .Condition => scope.parent.?.contains(name),
+ .Switch, .Loop, .Condition => scope.parent.?.contains(name),
};
}
@@ -594,7 +590,7 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
const node = try transCreateNodeVarDecl(c, true, true, name);
node.eq_token = try appendToken(c, .Equal, "=");
-
+
var semicolon: ast.TokenIndex = undefined;
node.init_node = blk: {
const rp = makeRestorePoint(c);
@@ -634,12 +630,12 @@ fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*
const field_name = try appendIdentifier(c, try c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, field_decl))));
_ = try appendToken(c, .Colon, ":");
const field_type = transQualType(rp, ZigClangFieldDecl_getType(field_decl), field_loc) catch |err| switch (err) {
- error.UnsupportedType => {
- try failDecl(c, record_loc, name, "unable to translate {} member type", .{container_kind_name});
- return null;
- },
- else => |e| return e,
- };
+ error.UnsupportedType => {
+ try failDecl(c, record_loc, name, "unable to translate {} member type", .{container_kind_name});
+ return null;
+ },
+ else => |e| return e,
+ };
const field_node = try c.a().create(ast.Node.ContainerField);
field_node.* = .{
@@ -879,205 +875,166 @@ fn transBinaryOperator(
) TransError!*ast.Node {
const op = ZigClangBinaryOperator_getOpcode(stmt);
const qt = ZigClangBinaryOperator_getType(stmt);
+ var op_token: ast.TokenIndex = undefined;
+ var op_id: ast.Node.InfixOp.Op = undefined;
switch (op) {
- .PtrMemD, .PtrMemI, .Cmp => return revertAndWarn(
- rp,
- error.UnsupportedTranslation,
- ZigClangBinaryOperator_getBeginLoc(stmt),
- "TODO: handle more C binary operators: {}",
- .{op},
- ),
- .Assign => return try transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt)),
- .Add => {
- const node = if (cIsUnsignedInteger(qt))
- try transCreateNodeInfixOp(rp, scope, stmt, .AddWrap, .PlusPercent, "+%", true)
- else
- try transCreateNodeInfixOp(rp, scope, stmt, .Add, .Plus, "+", true);
- return maybeSuppressResult(rp, scope, result_used, node);
- },
- .Sub => {
- const node = if (cIsUnsignedInteger(qt))
- try transCreateNodeInfixOp(rp, scope, stmt, .SubWrap, .MinusPercent, "-%", true)
- else
- try transCreateNodeInfixOp(rp, scope, stmt, .Sub, .Minus, "-", true);
- return maybeSuppressResult(rp, scope, result_used, node);
- },
- .Mul => {
- const node = if (cIsUnsignedInteger(qt))
- try transCreateNodeInfixOp(rp, scope, stmt, .MultWrap, .AsteriskPercent, "*%", true)
- else
- try transCreateNodeInfixOp(rp, scope, stmt, .Mult, .Asterisk, "*", true);
- return maybeSuppressResult(rp, scope, result_used, node);
+ .Assign => return transCreateNodeAssign(rp, scope, result_used, ZigClangBinaryOperator_getLHS(stmt), ZigClangBinaryOperator_getRHS(stmt)),
+ .Comma => {
+ const block_scope = try scope.findBlockScope(rp.c);
+ const expr = block_scope.base.parent == scope;
+ const lparen = if (expr) blk: {
+ const l = try appendToken(rp.c, .LParen, "(");
+ block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
+ break :blk l;
+ } else undefined;
+
+ const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value);
+ try block_scope.block_node.statements.push(lhs);
+
+ const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
+ if (expr) {
+ _ = try appendToken(rp.c, .Semicolon, ";");
+ const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
+ break_node.rhs = rhs;
+ try block_scope.block_node.statements.push(&break_node.base);
+ block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
+ const rparen = try appendToken(rp.c, .RParen, ")");
+ const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ grouped_expr.* = .{
+ .lparen = lparen,
+ .expr = &block_scope.block_node.base,
+ .rparen = rparen,
+ };
+ return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base);
+ } else {
+ return maybeSuppressResult(rp, scope, result_used, rhs);
+ }
},
.Div => {
if (!cIsUnsignedInteger(qt)) {
// signed integer division uses @divTrunc
const div_trunc_node = try transCreateNodeBuiltinFnCall(rp.c, "@divTrunc");
- const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
- try div_trunc_node.params.push(lhs);
+ try div_trunc_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value));
_ = try appendToken(rp.c, .Comma, ",");
const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
try div_trunc_node.params.push(rhs);
div_trunc_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return maybeSuppressResult(rp, scope, result_used, &div_trunc_node.base);
- } else {
- // unsigned/float division uses the operator
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .Div, .Slash, "/", true);
- return maybeSuppressResult(rp, scope, result_used, node);
}
},
.Rem => {
if (!cIsUnsignedInteger(qt)) {
// signed integer division uses @rem
const rem_node = try transCreateNodeBuiltinFnCall(rp.c, "@rem");
- const lhs = try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value);
- try rem_node.params.push(lhs);
+ try rem_node.params.push(try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value));
_ = try appendToken(rp.c, .Comma, ",");
const rhs = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
try rem_node.params.push(rhs);
rem_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return maybeSuppressResult(rp, scope, result_used, &rem_node.base);
- } else {
- // unsigned/float division uses the operator
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .Mod, .Percent, "%", true);
- return maybeSuppressResult(rp, scope, result_used, node);
}
},
.Shl => {
const node = try transCreateNodeShiftOp(rp, scope, stmt, .BitShiftLeft, .AngleBracketAngleBracketLeft, "<<");
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ return maybeSuppressResult(rp, scope, result_used, node);
},
.Shr => {
const node = try transCreateNodeShiftOp(rp, scope, stmt, .BitShiftRight, .AngleBracketAngleBracketRight, ">>");
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ return maybeSuppressResult(rp, scope, result_used, node);
+ },
+ .LAnd => {
+ const node = try transCreateNodeBoolInfixOp(rp, scope, stmt, .BoolAnd, result_used, true);
+ return maybeSuppressResult(rp, scope, result_used, node);
+ },
+ .LOr => {
+ const node = try transCreateNodeBoolInfixOp(rp, scope, stmt, .BoolOr, result_used, true);
+ return maybeSuppressResult(rp, scope, result_used, node);
+ },
+ else => {},
+ }
+ 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, "+%");
+ op_id = .AddWrap;
+ } else {
+ op_token = try appendToken(rp.c, .Plus, "+");
+ op_id = .Add;
+ }
+ },
+ .Sub => {
+ if (cIsUnsignedInteger(qt)) {
+ op_token = try appendToken(rp.c, .MinusPercent, "-%");
+ op_id = .SubWrap;
+ } else {
+ op_token = try appendToken(rp.c, .Minus, "-");
+ op_id = .Sub;
+ }
+ },
+ .Mul => {
+ if (cIsUnsignedInteger(qt)) {
+ op_token = try appendToken(rp.c, .AsteriskPercent, "*%");
+ op_id = .MultWrap;
+ } else {
+ op_token = try appendToken(rp.c, .Asterisk, "*");
+ op_id = .Mult;
+ }
+ },
+ .Div => {
+ // unsigned/float division uses the operator
+ op_id = .Div;
+ op_token = try appendToken(rp.c, .Slash, "/");
+ },
+ .Rem => {
+ // unsigned/float division uses the operator
+ op_id = .Mod;
+ op_token = try appendToken(rp.c, .Percent, "%");
},
.LT => {
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .LessThan, .AngleBracketLeft, "<", true);
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ op_id = .LessThan;
+ op_token = try appendToken(rp.c, .AngleBracketLeft, "<");
},
.GT => {
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .GreaterThan, .AngleBracketRight, ">", true);
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ op_id = .GreaterThan;
+ op_token = try appendToken(rp.c, .AngleBracketRight, ">");
},
.LE => {
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .LessOrEqual, .AngleBracketLeftEqual, "<=", true);
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ op_id = .LessOrEqual;
+ op_token = try appendToken(rp.c, .AngleBracketLeftEqual, "<=");
},
.GE => {
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .GreaterOrEqual, .AngleBracketRightEqual, ">=", true);
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ op_id = .GreaterOrEqual;
+ op_token = try appendToken(rp.c, .AngleBracketRightEqual, ">=");
},
.EQ => {
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .EqualEqual, .EqualEqual, "==", true);
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ op_id = .EqualEqual;
+ op_token = try appendToken(rp.c, .EqualEqual, "==");
},
.NE => {
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .BangEqual, .BangEqual, "!=", true);
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ op_id = .BangEqual;
+ op_token = try appendToken(rp.c, .BangEqual, "!=");
},
.And => {
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitAnd, .Ampersand, "&", true);
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ op_id = .BitAnd;
+ op_token = try appendToken(rp.c, .Ampersand, "&");
},
.Xor => {
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitXor, .Caret, "^", true);
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
+ op_id = .BitXor;
+ op_token = try appendToken(rp.c, .Caret, "^");
},
.Or => {
- const node = try transCreateNodeInfixOp(rp, scope, stmt, .BitOr, .Pipe, "|", true);
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
- },
- .LAnd => {
- const node = try transCreateNodeBoolInfixOp(rp, scope, stmt, .BoolAnd, .Keyword_and, "and");
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
- },
- .LOr => {
- const node = try transCreateNodeBoolInfixOp(rp, scope, stmt, .BoolOr, .Keyword_or, "or");
- return maybeSuppressResult(rp, scope, result_used, TransResult{
- .node = node,
- .child_scope = scope,
- .node_scope = scope,
- });
- },
- .Comma => {
- const block_scope = try scope.findBlockScope(rp.c);
- const expr = block_scope.base.parent == scope;
- const lparen = if (expr) blk: {
- const l = try appendToken(rp.c, .LParen, "(");
- block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
- break :blk l;
- } else undefined;
-
- const lhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getLHS(stmt), .unused, .r_value);
- try block_scope.block_node.statements.push(lhs);
-
- const rhs = try transExpr(rp, &block_scope.base, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
- if (expr) {
- _ = try appendToken(rp.c, .Semicolon, ";");
- const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
- break_node.rhs = rhs;
- try block_scope.block_node.statements.push(&break_node.base);
- block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
- const rparen = try appendToken(rp.c, .RParen, ")");
- const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
- grouped_expr.* = .{
- .lparen = lparen,
- .expr = &block_scope.block_node.base,
- .rparen = rparen,
- };
- return maybeSuppressResult(rp, scope, result_used, &grouped_expr.base);
- } else {
- return maybeSuppressResult(rp, scope, result_used, rhs);
- }
+ op_id = .BitOr;
+ op_token = try appendToken(rp.c, .Pipe, "|");
},
+ .Assign,
.MulAssign,
.DivAssign,
.RemAssign,
@@ -1091,6 +1048,9 @@ fn transBinaryOperator(
=> unreachable,
else => unreachable,
}
+
+ const rhs_node = try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value);
+ return transCreateNodeInfixOp(rp, scope, lhs_node, op_id, op_token, rhs_node, result_used, true);
}
fn transCompoundStmtInline(
@@ -1231,56 +1191,22 @@ fn transImplicitCastExpr(
}
}
-fn toEnumZeroCmp(
- rp: RestorePoint,
- scope: *Scope,
- expr: *ast.Node,
- generate_enum_node: fn (RestorePoint, *const struct_ZigClangType, source_loc: ZigClangSourceLocation) TransError!*ast.Node,
- enum_ty: *const struct_ZigClangType,
- enum_source_loc: ZigClangSourceLocation,
-) !*ast.Node {
- // expr != @bitCast(EnumType, @as(@TagType(EnumType), 0))
-
- // @bitCast(Enum,
- const bitcast = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast");
- const bitcast_enum_identifier = try generate_enum_node(rp, enum_ty, enum_source_loc);
- try bitcast.params.push(bitcast_enum_identifier);
- _ = try appendToken(rp.c, .Comma, ",");
-
- // @as(
- const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
-
- // @TagType(Enum),
- const tag_type = try transCreateNodeBuiltinFnCall(rp.c, "@TagType");
- const tag_type_enum_identifier = try generate_enum_node(rp, enum_ty, enum_source_loc);
- try tag_type.params.push(tag_type_enum_identifier);
- tag_type.rparen_token = try appendToken(rp.c, .RParen, ")");
- try cast_node.params.push(&tag_type.base);
- _ = try appendToken(rp.c, .Comma, ",");
-
- // 0)
- const zero = try transCreateNodeInt(rp.c, 0);
- try cast_node.params.push(zero);
- cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
-
- try bitcast.params.push(&cast_node.base);
- bitcast.rparen_token = try appendToken(rp.c, .RParen, ")");
-
- // expr != @bitCast(EnumType, @as(@TagType(EnumType), 0))
- return transCreateNodeNotEqual(rp, scope, expr, &bitcast.base);
-}
-
fn transBoolExpr(
rp: RestorePoint,
scope: *Scope,
expr: *const ZigClangExpr,
used: ResultUsed,
lrvalue: LRValue,
-) !*ast.Node {
+ grouped: bool,
+) TransError!*ast.Node {
+ const lparen = if (grouped)
+ try appendToken(rp.c, .LParen, "(")
+ else
+ undefined;
var res = try transExpr(rp, scope, expr, used, lrvalue);
- switch (res.node.id) {
- .InfixOp => switch (@ptrCast(*const ast.Node.InfixOp, &res.node).op) {
+ switch (res.id) {
+ .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {
.BoolOr,
.BoolAnd,
.EqualEqual,
@@ -1289,24 +1215,34 @@ fn transBoolExpr(
.GreaterThan,
.LessOrEqual,
.GreaterOrEqual,
- => return res.node,
+ => return res,
else => {},
},
- .PrefixOp => switch (@ptrCast(*const ast.Node.PrefixOp, &res.node).op) {
- .BoolNot => return res.node,
+ .PrefixOp => switch (@fieldParentPtr(ast.Node.PrefixOp, "base", res).op) {
+ .BoolNot => return res,
else => {},
},
- .BoolLiteral => return res.node,
+ .BoolLiteral => return res,
else => {},
}
-
const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr));
+ return finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used, grouped);
+}
+fn finishBoolExpr(
+ rp: RestorePoint,
+ scope: *Scope,
+ loc: ZigClangSourceLocation,
+ 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);
@@ -1337,219 +1273,48 @@ fn transBoolExpr(
.Char32,
.WChar_S,
.Float16,
- => return transCreateNodeNotEqual(rp, scope, res.node, try transCreateNodeInt(rp.c, 0)),
-
- .NullPtr => return transCreateNodeNotEqual(rp, scope, res.node, try transCreateNodeNullLiteral(rp.c)),
-
- .Void,
- .Half,
- .ObjCId,
- .ObjCClass,
- .ObjCSel,
- .OMPArraySection,
- .Dependent,
- .Overload,
- .BoundMember,
- .PseudoObject,
- .UnknownAny,
- .BuiltinFn,
- .ARCUnbridgedCast,
- .OCLImage1dRO,
- .OCLImage1dArrayRO,
- .OCLImage1dBufferRO,
- .OCLImage2dRO,
- .OCLImage2dArrayRO,
- .OCLImage2dDepthRO,
- .OCLImage2dArrayDepthRO,
- .OCLImage2dMSAARO,
- .OCLImage2dArrayMSAARO,
- .OCLImage2dMSAADepthRO,
- .OCLImage2dArrayMSAADepthRO,
- .OCLImage3dRO,
- .OCLImage1dWO,
- .OCLImage1dArrayWO,
- .OCLImage1dBufferWO,
- .OCLImage2dWO,
- .OCLImage2dArrayWO,
- .OCLImage2dDepthWO,
- .OCLImage2dArrayDepthWO,
- .OCLImage2dMSAAWO,
- .OCLImage2dArrayMSAAWO,
- .OCLImage2dMSAADepthWO,
- .OCLImage2dArrayMSAADepthWO,
- .OCLImage3dWO,
- .OCLImage1dRW,
- .OCLImage1dArrayRW,
- .OCLImage1dBufferRW,
- .OCLImage2dRW,
- .OCLImage2dArrayRW,
- .OCLImage2dDepthRW,
- .OCLImage2dArrayDepthRW,
- .OCLImage2dMSAARW,
- .OCLImage2dArrayMSAARW,
- .OCLImage2dMSAADepthRW,
- .OCLImage2dArrayMSAADepthRW,
- .OCLImage3dRW,
- .OCLSampler,
- .OCLEvent,
- .OCLClkEvent,
- .OCLQueue,
- .OCLReserveID,
- .ShortAccum,
- .Accum,
- .LongAccum,
- .UShortAccum,
- .UAccum,
- .ULongAccum,
- .ShortFract,
- .Fract,
- .LongFract,
- .UShortFract,
- .UFract,
- .ULongFract,
- .SatShortAccum,
- .SatAccum,
- .SatLongAccum,
- .SatUShortAccum,
- .SatUAccum,
- .SatULongAccum,
- .SatShortFract,
- .SatFract,
- .SatLongFract,
- .SatUShortFract,
- .SatUFract,
- .SatULongFract,
- .OCLIntelSubgroupAVCMcePayload,
- .OCLIntelSubgroupAVCImePayload,
- .OCLIntelSubgroupAVCRefPayload,
- .OCLIntelSubgroupAVCSicPayload,
- .OCLIntelSubgroupAVCMceResult,
- .OCLIntelSubgroupAVCImeResult,
- .OCLIntelSubgroupAVCRefResult,
- .OCLIntelSubgroupAVCSicResult,
- .OCLIntelSubgroupAVCImeResultSingleRefStreamout,
- .OCLIntelSubgroupAVCImeResultDualRefStreamout,
- .OCLIntelSubgroupAVCImeSingleRefStreamin,
- .OCLIntelSubgroupAVCImeDualRefStreamin,
- => return res.node,
-
+ => {
+ 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);
+ },
+ .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);
+ },
else => {},
}
},
- .Pointer => return transCreateNodeNotEqual(rp, scope, res.node, try transCreateNodeNullLiteral(rp.c)),
-
+ .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);
+ },
.Typedef => {
- return transCreateNodeNotEqual(rp, scope, res.node, try transCreateNodeInt(rp.c, 0)); // TODO currently assuming it is like an int/char/bool builtin type. Coerce the type and recurse? Add a toTypedefZeroCmp function?
-
- // TODO This is the code that was in translate-c, but it seems like it is giving wrong results! It just prints the typedef name instead of the value
- // const typedef_ty = @ptrCast(*const ZigClangTypedefType, ty);
- // const typedef_decl = ZigClangTypedefType_getDecl(typedef_ty);
- // const typedef_name_decl = ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl);
-
- // const typedef_name = if (rp.c.decl_table.get(@ptrToInt(typedef_name_decl))) |existing_entry|
- // existing_entry.value
- // else
- // try rp.c.str(ZigClangDecl_getName_bytes_begin(@ptrCast(*const ZigClangDecl, typedef_name_decl)));
-
- // return transCreateNodeIdentifier(rp.c, typedef_name);
+ 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);
},
-
.Enum => {
- const gen_enum_decl_node = struct {
- // Have to use a callback because node must be generated inline in order to avoid weird AST printing behavior,
- // and the code to generate the nodes is a little different for each case
- fn generate_node(inner_rp: RestorePoint, enum_ty: *const struct_ZigClangType, source_loc: ZigClangSourceLocation) TransError!*ast.Node {
- const actual_enum_ty = @ptrCast(*const ZigClangEnumType, enum_ty);
- const enum_decl = ZigClangEnumType_getDecl(actual_enum_ty);
- const enum_type = (try transEnumDecl(inner_rp.c, enum_decl)) orelse {
- return revertAndWarn(inner_rp, error.UnsupportedType, source_loc, "unable to translate enum declaration", .{});
- };
- return enum_type;
- }
- };
+ 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, ")");
- return toEnumZeroCmp(rp, scope, res.node, gen_enum_decl_node.generate_node, ty, ZigClangExpr_getBeginLoc(expr));
+ 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);
},
-
.Elaborated => {
const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ty);
-
- switch (ZigClangElaboratedType_getKeyword(elaborated_ty)) {
- .Enum => {
- // Have to use a callback because node must be generated inline in order to avoid weird AST printing behavior,
- // and the code to generate the nodes is a little different for each case
- const gen_enum_type_node = struct {
- fn generate_node(inner_rp: RestorePoint, enum_ty: *const struct_ZigClangType, source_loc: ZigClangSourceLocation) TransError!*ast.Node {
- const inner_elaborated_ty = @ptrCast(*const ZigClangElaboratedType, enum_ty);
- const enum_type = try transQualType(inner_rp, ZigClangElaboratedType_getNamedType(inner_elaborated_ty), source_loc);
- return enum_type;
- }
- };
-
- return toEnumZeroCmp(rp, scope, res.node, gen_enum_type_node.generate_node, ty, ZigClangExpr_getBeginLoc(expr));
- },
-
- .Struct,
- .Union,
- .Interface,
- .Class,
- .Typename,
- .None,
- => return res.node,
-
- else => {},
- }
+ const named_type = ZigClangElaboratedType_getNamedType(elaborated_ty);
+ return finishBoolExpr(rp, scope, loc, ZigClangQualType_getTypePtr(named_type), node, used, grouped);
},
-
- .FunctionProto,
- .Record,
- .ConstantArray,
- .Paren,
- .Decayed,
- .Attributed,
- .IncompleteArray,
- .BlockPointer,
- .LValueReference,
- .RValueReference,
- .MemberPointer,
- .VariableArray,
- .DependentSizedArray,
- .DependentSizedExtVector,
- .Vector,
- .ExtVector,
- .FunctionNoProto,
- .UnresolvedUsing,
- .Adjusted,
- .TypeOfExpr,
- .TypeOf,
- .Decltype,
- .UnaryTransform,
- .TemplateTypeParm,
- .SubstTemplateTypeParm,
- .SubstTemplateTypeParmPack,
- .TemplateSpecialization,
- .Auto,
- .InjectedClassName,
- .DependentName,
- .DependentTemplateSpecialization,
- .PackExpansion,
- .ObjCObject,
- .ObjCInterface,
- .Complex,
- .ObjCObjectPointer,
- .Atomic,
- .Pipe,
- .ObjCTypeParam,
- .DeducedTemplateSpecialization,
- .DependentAddressSpace,
- .DependentVector,
- .MacroQualified,
- => return res.node,
-
- else => unreachable,
+ else => {},
}
-
- unreachable;
+ return revertAndWarn(rp, error.UnsupportedType, loc, "unsupported bool expression type", .{});
}
fn transIntegerLiteral(
@@ -2036,7 +1801,6 @@ fn transSwitch(
const switch_block = try transCreateNodeBlock(rp.c, null);
try switch_block.statements.push(&switch_node.base);
switch_scope.pending_block = switch_block;
-
const last = try transStmt(rp, &block_scope.base, ZigClangSwitchStmt_getBody(stmt), .unused, .r_value);
_ = try appendToken(rp.c, .Semicolon, ";");
@@ -2085,7 +1849,6 @@ fn transCase(
} else
try transExpr(rp, scope, ZigClangCaseStmt_getLHS(stmt), .used, .r_value);
-
const switch_prong = try transCreateNodeSwitchCase(rp.c, expr);
switch_prong.expr = &(try transCreateNodeBreak(rp.c, label)).base;
_ = try appendToken(rp.c, .Comma, ",");
@@ -2271,7 +2034,7 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla
const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
grouped_expr.* = .{
.lparen = lparen,
- .expr = &if_node.base,
+ .expr = &if_node.base,
.rparen = rparen,
};
return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
@@ -2670,87 +2433,64 @@ fn transCreateNodePrefixOp(
return node;
}
-fn transCreateNodeInfixOpImpl(
+fn transCreateNodeInfixOp(
rp: RestorePoint,
scope: *Scope,
lhs_node: *ast.Node,
- rhs_node: *ast.Node,
op: ast.Node.InfixOp.Op,
- op_tok_id: std.zig.Token.Id,
- bytes: []const u8,
+ op_token: ast.TokenIndex,
+ rhs_node: *ast.Node,
+ used: ResultUsed,
grouped: bool,
) !*ast.Node {
- const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined;
- const op_token = try appendToken(rp.c, op_tok_id, bytes);
+ var lparen = if (grouped)
+ try appendToken(rp.c, .LParen, "(")
+ else
+ null;
const node = try rp.c.a().create(ast.Node.InfixOp);
- node.* = ast.Node.InfixOp{
+ node.* = .{
.op_token = op_token,
.lhs = lhs_node,
.op = op,
.rhs = rhs_node,
};
- if (!grouped) return &node.base;
+ if (!grouped) return maybeSuppressResult(rp, scope, used, &node.base);
const rparen = try appendToken(rp.c, .RParen, ")");
const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
grouped_expr.* = .{
- .lparen = lparen,
+ .lparen = lparen.?,
.expr = &node.base,
.rparen = rparen,
};
- return &grouped_expr.base;
+ return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
}
-fn transCreateNodeInfixOp(
+fn transCreateNodeBoolInfixOp(
rp: RestorePoint,
scope: *Scope,
stmt: *const ZigClangBinaryOperator,
op: ast.Node.InfixOp.Op,
- op_tok_id: std.zig.Token.Id,
- bytes: []const u8,
+ used: ResultUsed,
grouped: bool,
) !*ast.Node {
- return transCreateNodeInfixOpImpl(
- rp,
- scope,
- (try transExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .r_value)).node,
- (try transExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value)).node,
- op,
- op_tok_id,
- bytes,
- grouped,
- );
-}
-
-fn transCreateNodeNotEqual(
- rp: RestorePoint,
- scope: *Scope,
- lhs_node: *ast.Node,
- rhs_node: *ast.Node,
-) !*ast.Node {
- return transCreateNodeInfixOpImpl(rp, scope, lhs_node, rhs_node, .BangEqual, .BangEqual, "!=", true);
-}
+ std.debug.assert(op == .BoolAnd or op == .BoolOr);
-fn transCreateNodeBoolInfixOp(
- rp: RestorePoint,
- scope: *Scope,
- stmt: *const ZigClangBinaryOperator,
- comptime op: ast.Node.InfixOp.Op,
- comptime op_tok_id: std.zig.Token.Id,
- comptime bytes: []const u8,
-) !*ast.Node {
- if (!(op == .BoolAnd or op == .BoolOr)) {
- @compileError("op must be either .BoolAnd or .BoolOr");
- }
+ const lhs_hode = try transBoolExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .l_value, true);
+ const op_token = if (op == .BoolAnd)
+ try appendToken(rp.c, .Keyword_and, "and")
+ else
+ try appendToken(rp.c, .Keyword_or, "or");
+ const rhs = try transBoolExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value, true);
- return transCreateNodeInfixOpImpl(
+ return transCreateNodeInfixOp(
rp,
scope,
- try transBoolExpr(rp, scope, ZigClangBinaryOperator_getLHS(stmt), .used, .r_value),
- try transBoolExpr(rp, scope, ZigClangBinaryOperator_getRHS(stmt), .used, .r_value),
+ lhs_hode,
op,
- op_tok_id,
- bytes,
- true,
+ op_token,
+ rhs,
+ used,
+ grouped,
);
}
@@ -3149,16 +2889,14 @@ fn transCreateNodeShiftOp(
comptime op_tok_id: std.zig.Token.Id,
comptime bytes: []const u8,
) !*ast.Node {
- if (!(op == .BitShiftLeft or op == .BitShiftRight)) {
- @compileError("op must be either .BitShiftLeft or .BitShiftRight");
- }
+ std.debug.assert(op == .BitShiftLeft or op == .BitShiftRight);
const lhs_expr = ZigClangBinaryOperator_getLHS(stmt);
const rhs_expr = ZigClangBinaryOperator_getRHS(stmt);
const rhs_location = ZigClangExpr_getBeginLoc(rhs_expr);
// lhs >> u5(rh)
- const lhs = try transExpr(rp, scope, lhs_expr, .used, .r_value);
+ const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value);
const op_token = try appendToken(rp.c, op_tok_id, bytes);
const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
@@ -3166,13 +2904,13 @@ fn transCreateNodeShiftOp(
try as_node.params.push(rhs_type);
_ = try appendToken(rp.c, .Comma, ",");
const rhs = try transExpr(rp, scope, rhs_expr, .used, .r_value);
- try as_node.params.push(rhs.node);
+ try as_node.params.push(rhs);
as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
const node = try rp.c.a().create(ast.Node.InfixOp);
node.* = ast.Node.InfixOp{
.op_token = op_token,
- .lhs = lhs.node,
+ .lhs = lhs,
.op = op,
.rhs = &as_node.base,
};
@@ -3648,26 +3386,26 @@ fn isZigPrimitiveType(name: []const u8) bool {
}
// void is invalid in c so it doesn't need to be checked.
return std.mem.eql(u8, name, "comptime_float") or
- std.mem.eql(u8, name, "comptime_int") or
- std.mem.eql(u8, name, "bool") or
- std.mem.eql(u8, name, "isize") or
- std.mem.eql(u8, name, "usize") or
- std.mem.eql(u8, name, "f16") or
- std.mem.eql(u8, name, "f32") or
- std.mem.eql(u8, name, "f64") or
- std.mem.eql(u8, name, "f128") or
- std.mem.eql(u8, name, "c_longdouble") or
- std.mem.eql(u8, name, "noreturn") or
- std.mem.eql(u8, name, "type") or
- std.mem.eql(u8, name, "anyerror") or
- std.mem.eql(u8, name, "c_short") or
- std.mem.eql(u8, name, "c_ushort") or
- std.mem.eql(u8, name, "c_int") or
- std.mem.eql(u8, name, "c_uint") or
- std.mem.eql(u8, name, "c_long") or
- std.mem.eql(u8, name, "c_ulong") or
- std.mem.eql(u8, name, "c_longlong") or
- std.mem.eql(u8, name, "c_ulonglong");
+ std.mem.eql(u8, name, "comptime_int") or
+ std.mem.eql(u8, name, "bool") or
+ std.mem.eql(u8, name, "isize") or
+ std.mem.eql(u8, name, "usize") or
+ std.mem.eql(u8, name, "f16") or
+ std.mem.eql(u8, name, "f32") or
+ std.mem.eql(u8, name, "f64") or
+ std.mem.eql(u8, name, "f128") or
+ std.mem.eql(u8, name, "c_longdouble") or
+ std.mem.eql(u8, name, "noreturn") or
+ std.mem.eql(u8, name, "type") or
+ std.mem.eql(u8, name, "anyerror") or
+ std.mem.eql(u8, name, "c_short") or
+ std.mem.eql(u8, name, "c_ushort") or
+ std.mem.eql(u8, name, "c_int") or
+ std.mem.eql(u8, name, "c_uint") or
+ std.mem.eql(u8, name, "c_long") or
+ std.mem.eql(u8, name, "c_ulong") or
+ std.mem.eql(u8, name, "c_longlong") or
+ std.mem.eql(u8, name, "c_ulonglong");
}
fn isValidZigIdentifier(name: []const u8) bool {
test/translate_c.zig
@@ -531,33 +531,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("qualified struct and enum",
- \\struct Foo {
- \\ int x;
- \\ int y;
- \\};
- \\enum Bar {
- \\ BarA,
- \\ BarB,
- \\};
- \\void func(struct Foo *a, enum Bar **b);
- , &[_][]const u8{
- \\pub const struct_Foo = extern struct {
- \\ x: c_int,
- \\ y: c_int,
- \\};
- \\pub const BarA = enum_Bar.A;
- \\pub const BarB = enum_Bar.B;
- \\pub const enum_Bar = extern enum {
- \\ A,
- \\ B,
- \\};
- \\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;
- ,
- \\pub const Foo = struct_Foo;
- \\pub const Bar = enum_Bar;
- });
-
cases.add_both("constant size array",
\\void func(int array[20]);
, &[_][]const u8{
@@ -1388,17 +1361,109 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ 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_int, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))));
- \\ var l: c_int = ((@as(c_int, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))) and (b != 0));
- \\ var m: c_int = ((c != null) or (@as(c_int, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))));
+ \\ 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 td: SomeTypedef = 44;
\\ var o: c_int = ((td != 0) or (b != 0));
\\ var p: c_int = ((c != null) and (td != 0));
\\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
\\}
+ ,
\\pub const Foo = enum_Foo;
});
+ cases.add_2("qualified struct and enum",
+ \\struct Foo {
+ \\ int x;
+ \\ int y;
+ \\};
+ \\enum Bar {
+ \\ BarA,
+ \\ BarB,
+ \\};
+ \\void func(struct Foo *a, enum Bar **b);
+ , &[_][]const u8{
+ \\pub const struct_Foo = extern struct {
+ \\ x: c_int,
+ \\ y: c_int,
+ \\};
+ \\pub const BarA = enum_Bar.A;
+ \\pub const BarB = enum_Bar.B;
+ \\pub const enum_Bar = extern enum {
+ \\ A,
+ \\ B,
+ \\};
+ \\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;
+ ,
+ \\pub const Foo = struct_Foo;
+ \\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
+ \\int max(int a, int b) {
+ \\ int c = (a & b);
+ \\ int d = (a | b);
+ \\ return (c ^ d);
+ \\}
+ , &[_][]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);
+ \\}
+ });
+
+ cases.add_2("comparison operators (no if)", // TODO Come up with less contrived tests? Make sure to cover all these comparisons. Can use `if` after it is added to translate-c-2
+ \\int test_comparisons(int a, int b) {
+ \\ int c = (a < b);
+ \\ int d = (a > b);
+ \\ int e = (a <= b);
+ \\ int f = (a >= b);
+ \\ int g = (c < d);
+ \\ int h = (e < f);
+ \\ int i = (g < h);
+ \\ return i;
+ \\}
+ , &[_][]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);
+ \\ return i;
+ \\}
+ });
+
+ cases.add_2("==, !=, no if", // TODO remove this test after `if` conversion supported, and switch "==, !=" to addC_both
+ \\int max(int a, int b) {
+ \\ int c = (a == b);
+ \\ int d = (a != b);
+ \\ return (c != d);
+ \\}
+ , &[_][]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);
+ \\}
+ });
+
+ cases.add_2("bitshift, no parens", // TODO can fold this into "bitshift" once parens are preserved correctly in translate-c-2
+ \\int foo(void) {
+ \\ int a = (1 << 2);
+ \\ return a >> 1;
+ \\}
+ , &[_][]const u8{
+ \\pub export fn foo() c_int {
+ \\ var a: c_int = 1 << @as(@import("std").math.Log2Int(c_int), 2);
+ \\ return a >> @as(@import("std").math.Log2Int(c_int), 1);
+ \\}
+ });
+
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
cases.addAllowWarnings("simple data types",
@@ -1525,21 +1590,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return a;
\\}
});
-
- cases.add_2("==, !=, no if", // TODO remove this test after `if` conversion supported, and switch "==, !=" to addC_both
- \\int max(int a, int b) {
- \\ int c = (a == b);
- \\ int d = (a != b);
- \\ return (c != d);
- \\}
- , &[_][]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);
- \\}
- });
-
cases.addC("bitwise binary operators",
\\int max(int a, int b) {
\\ return (a & b) ^ (a | b);
@@ -1550,20 +1600,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- 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
- \\int max(int a, int b) {
- \\ int c = (a & b);
- \\ int d = (a | b);
- \\ return (c ^ d);
- \\}
- , &[_][]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);
- \\}
- });
-
cases.addC("logical and, logical or",
\\int max(int a, int b) {
\\ if (a < b || a == b)
@@ -1580,30 +1616,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("comparison operators (no if)", // TODO Come up with less contrived tests? Make sure to cover all these comparisons. Can use `if` after it is added to translate-c-2
- \\int test_comparisons(int a, int b) {
- \\ int c = (a < b);
- \\ int d = (a > b);
- \\ int e = (a <= b);
- \\ int f = (a >= b);
- \\ int g = (c < d);
- \\ int h = (e < f);
- \\ int i = (g < h);
- \\ return i;
- \\}
- , &[_][]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);
- \\ return i;
- \\}
- });
-
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,
@@ -1640,9 +1652,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ 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_int, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
- \\ var l: c_int = (@as(c_int, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0))) and (b != 0);
- \\ var m: c_int = (c != null) or (@as(c_int, d) != @bitCast(enum_Foo, @as(@TagType(enum_Foo), 0)));
+ \\ 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;
\\}
});
@@ -1760,18 +1772,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.add_2("bitshift, no parens", // TODO can fold this into "bitshift" once parens are preserved correctly in translate-c-2
- \\int foo(void) {
- \\ int a = (1 << 2);
- \\ return a >> 1;
- \\}
- , &[_][]const u8{
- \\pub export fn foo() c_int {
- \\ var a: c_int = 1 << @as(@import("std").math.Log2Int(c_int), 2);
- \\ return a >> @as(@import("std").math.Log2Int(c_int), 1);
- \\}
- });
-
cases.addC("compound assignment operators",
\\void foo(void) {
\\ int a = 0;