Commit f837c7c9cd
Changed files (5)
lib/std/zig/ast.zig
@@ -1431,13 +1431,13 @@ pub const Node = struct {
AssignBitShiftRight,
AssignBitXor,
AssignDiv,
- AssignMinus,
- AssignMinusWrap,
+ AssignSub,
+ AssignSubWrap,
AssignMod,
- AssignPlus,
- AssignPlusWrap,
- AssignTimes,
- AssignTimesWarp,
+ AssignAdd,
+ AssignAddWrap,
+ AssignMult,
+ AssignMultWrap,
BangEqual,
BitAnd,
BitOr,
@@ -1490,13 +1490,13 @@ pub const Node = struct {
Op.AssignBitShiftRight,
Op.AssignBitXor,
Op.AssignDiv,
- Op.AssignMinus,
- Op.AssignMinusWrap,
+ Op.AssignSub,
+ Op.AssignSubWrap,
Op.AssignMod,
- Op.AssignPlus,
- Op.AssignPlusWrap,
- Op.AssignTimes,
- Op.AssignTimesWarp,
+ Op.AssignAdd,
+ Op.AssignAddWrap,
+ Op.AssignMult,
+ Op.AssignMultWrap,
Op.BangEqual,
Op.BitAnd,
Op.BitOr,
lib/std/zig/parse.zig
@@ -1981,19 +1981,19 @@ fn parseAssignOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const token = nextToken(it);
const op = switch (token.ptr.id) {
- .AsteriskEqual => Op{ .AssignTimes = {} },
+ .AsteriskEqual => Op{ .AssignMult = {} },
.SlashEqual => Op{ .AssignDiv = {} },
.PercentEqual => Op{ .AssignMod = {} },
- .PlusEqual => Op{ .AssignPlus = {} },
- .MinusEqual => Op{ .AssignMinus = {} },
+ .PlusEqual => Op{ .AssignAdd = {} },
+ .MinusEqual => Op{ .AssignSub = {} },
.AngleBracketAngleBracketLeftEqual => Op{ .AssignBitShiftLeft = {} },
.AngleBracketAngleBracketRightEqual => Op{ .AssignBitShiftRight = {} },
.AmpersandEqual => Op{ .AssignBitAnd = {} },
.CaretEqual => Op{ .AssignBitXor = {} },
.PipeEqual => Op{ .AssignBitOr = {} },
- .AsteriskPercentEqual => Op{ .AssignTimesWarp = {} },
- .PlusPercentEqual => Op{ .AssignPlusWrap = {} },
- .MinusPercentEqual => Op{ .AssignMinusWrap = {} },
+ .AsteriskPercentEqual => Op{ .AssignMultWrap = {} },
+ .PlusPercentEqual => Op{ .AssignAddWrap = {} },
+ .MinusPercentEqual => Op{ .AssignSubWrap = {} },
.Equal => Op{ .Assign = {} },
else => {
putBackToken(it, token.index);
src-self-hosted/clang.zig
@@ -1120,3 +1120,11 @@ pub extern fn ZigClangUnaryOperator_getOpcode(*const ZigClangUnaryOperator) ZigC
pub extern fn ZigClangUnaryOperator_getType(*const ZigClangUnaryOperator) ZigClangQualType;
pub extern fn ZigClangUnaryOperator_getSubExpr(*const ZigClangUnaryOperator) *const ZigClangExpr;
pub extern fn ZigClangUnaryOperator_getBeginLoc(*const ZigClangUnaryOperator) ZigClangSourceLocation;
+
+pub extern fn ZigClangCompoundAssignOperator_getType(*const ZigClangCompoundAssignOperator) ZigClangQualType;
+pub extern fn ZigClangCompoundAssignOperator_getComputationLHSType(*const ZigClangCompoundAssignOperator) ZigClangQualType;
+pub extern fn ZigClangCompoundAssignOperator_getComputationResultType(*const ZigClangCompoundAssignOperator) ZigClangQualType;
+pub extern fn ZigClangCompoundAssignOperator_getBeginLoc(*const ZigClangCompoundAssignOperator) ZigClangSourceLocation;
+pub extern fn ZigClangCompoundAssignOperator_getOpcode(*const ZigClangCompoundAssignOperator) ZigClangBO;
+pub extern fn ZigClangCompoundAssignOperator_getLHS(*const ZigClangCompoundAssignOperator) *const ZigClangExpr;
+pub extern fn ZigClangCompoundAssignOperator_getRHS(*const ZigClangCompoundAssignOperator) *const ZigClangExpr;
src-self-hosted/translate_c.zig
@@ -898,6 +898,7 @@ fn transStmt(
.CallExprClass => return transCallExpr(rp, scope, @ptrCast(*const ZigClangCallExpr, stmt), result_used),
.UnaryExprOrTypeTraitExprClass => return transUnaryExprOrTypeTraitExpr(rp, scope, @ptrCast(*const ZigClangUnaryExprOrTypeTraitExpr, stmt), result_used),
.UnaryOperatorClass => return transUnaryOperator(rp, scope, @ptrCast(*const ZigClangUnaryOperator, stmt), result_used),
+ .CompoundAssignOperatorClass => return transCompoundAssignOperator(rp, scope, @ptrCast(*const ZigClangCompoundAssignOperator, stmt), result_used),
else => {
return revertAndWarn(
rp,
@@ -2178,21 +2179,21 @@ fn transUnaryOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangUnar
const op_expr = ZigClangUnaryOperator_getSubExpr(stmt);
switch (ZigClangUnaryOperator_getOpcode(stmt)) {
.PostInc => if (qualTypeHaswrappingOverflow(ZigClangUnaryOperator_getType(stmt)))
- return transCreatePostCrement(rp, scope, stmt, .AssignPlusWrap, .PlusPercentEqual, "+%=", used)
+ return transCreatePostCrement(rp, scope, stmt, .AssignAddWrap, .PlusPercentEqual, "+%=", used)
else
- return transCreatePostCrement(rp, scope, stmt, .AssignPlus, .PlusEqual, "+=", used),
+ return transCreatePostCrement(rp, scope, stmt, .AssignAdd, .PlusEqual, "+=", used),
.PostDec => if (qualTypeHaswrappingOverflow(ZigClangUnaryOperator_getType(stmt)))
- return transCreatePostCrement(rp, scope, stmt, .AssignMinusWrap, .MinusPercentEqual, "-%=", used)
+ return transCreatePostCrement(rp, scope, stmt, .AssignSubWrap, .MinusPercentEqual, "-%=", used)
else
- return transCreatePostCrement(rp, scope, stmt, .AssignMinus, .MinusEqual, "-=", used),
+ return transCreatePostCrement(rp, scope, stmt, .AssignSub, .MinusEqual, "-=", used),
.PreInc => if (qualTypeHaswrappingOverflow(ZigClangUnaryOperator_getType(stmt)))
- return transCreatePreCrement(rp, scope, stmt, .AssignPlusWrap, .PlusPercentEqual, "+%=", used)
+ return transCreatePreCrement(rp, scope, stmt, .AssignAddWrap, .PlusPercentEqual, "+%=", used)
else
- return transCreatePreCrement(rp, scope, stmt, .AssignPlus, .PlusEqual, "+=", used),
+ return transCreatePreCrement(rp, scope, stmt, .AssignAdd, .PlusEqual, "+=", used),
.PreDec => if (qualTypeHaswrappingOverflow(ZigClangUnaryOperator_getType(stmt)))
- return transCreatePreCrement(rp, scope, stmt, .AssignMinusWrap, .MinusPercentEqual, "-%=", used)
+ return transCreatePreCrement(rp, scope, stmt, .AssignSubWrap, .MinusPercentEqual, "-%=", used)
else
- return transCreatePreCrement(rp, scope, stmt, .AssignMinus, .MinusEqual, "-=", used),
+ return transCreatePreCrement(rp, scope, stmt, .AssignSub, .MinusEqual, "-=", used),
.AddrOf => {
const op_node = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&");
op_node.rhs = try transExpr(rp, scope, op_expr, used, .r_value);
@@ -2232,7 +2233,7 @@ fn transUnaryOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangUnar
op_node.rhs = try transBoolExpr(rp, scope, op_expr, .used, .r_value, true);
return &op_node.base;
},
- else => return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangUnaryOperator_getBeginLoc(stmt), "TODO handle C translation UO_Real", .{}),
+ else => return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangUnaryOperator_getBeginLoc(stmt), "unsupported C translation {}", .{ZigClangUnaryOperator_getOpcode(stmt)}),
}
}
@@ -2353,13 +2354,129 @@ fn transCreatePostCrement(
try block_scope.block_node.statements.push(assign);
const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
- break_node.rhs = try transCreateNodeIdentifier(rp.c,tmp);
+ break_node.rhs = try transCreateNodeIdentifier(rp.c, tmp);
try block_scope.block_node.statements.push(&break_node.base);
_ = try appendToken(rp.c, .Semicolon, ";");
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
return &block_scope.block_node.base;
}
+fn transCompoundAssignOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangCompoundAssignOperator, used: ResultUsed) TransError!*ast.Node {
+ switch (ZigClangCompoundAssignOperator_getOpcode(stmt)) {
+ .MulAssign => if (qualTypeHaswrappingOverflow(ZigClangCompoundAssignOperator_getType(stmt)))
+ return transCreateCompoundAssign(rp, scope, stmt, .AssignMultWrap, .AsteriskPercentEqual, "*%=", .MultWrap, .AsteriskPercent, "*%", used)
+ else
+ return transCreateCompoundAssign(rp, scope, stmt, .AssignMult, .AsteriskEqual, "*=", .Mult, .Asterisk, "*", used),
+ .AddAssign => if (qualTypeHaswrappingOverflow(ZigClangCompoundAssignOperator_getType(stmt)))
+ return transCreateCompoundAssign(rp, scope, stmt, .AssignAddWrap, .PlusPercentEqual, "+%=", .AddWrap, .PlusPercent, "+%", used)
+ else
+ return transCreateCompoundAssign(rp, scope, stmt, .AssignAdd, .PlusEqual, "+=", .Add, .Plus, "+", used),
+ .SubAssign => if (qualTypeHaswrappingOverflow(ZigClangCompoundAssignOperator_getType(stmt)))
+ return transCreateCompoundAssign(rp, scope, stmt, .AssignSubWrap, .MinusPercentEqual, "-%=", .SubWrap, .MinusPercent, "-%", used)
+ else
+ return transCreateCompoundAssign(rp, scope, stmt, .AssignSub, .MinusPercentEqual, "-=", .Sub, .Minus, "-", used),
+ .ShlAssign => return transCreateCompoundAssign(rp, scope, stmt, .AssignBitShiftLeft, .AngleBracketAngleBracketLeftEqual, "<<=", .BitShiftLeft, .AngleBracketAngleBracketLeft, "<<", used),
+ .ShrAssign => return transCreateCompoundAssign(rp, scope, stmt, .AssignBitShiftRight, .AngleBracketAngleBracketRightEqual, ">>=", .BitShiftRight, .AngleBracketAngleBracketRight, ">>", used),
+ .AndAssign => return transCreateCompoundAssign(rp, scope, stmt, .AssignBitAnd, .AmpersandEqual, "&=", .BitAnd, .Ampersand, "&", used),
+ .XorAssign => return transCreateCompoundAssign(rp, scope, stmt, .AssignBitXor, .CaretEqual, "^=", .BitXor, .Caret, "^", used),
+ .OrAssign => return transCreateCompoundAssign(rp, scope, stmt, .AssignBitOr, .PipeEqual, "|=", .BitOr, .Pipe, "|", used),
+ else => return revertAndWarn(
+ rp,
+ error.UnsupportedTranslation,
+ ZigClangCompoundAssignOperator_getBeginLoc(stmt),
+ "unsupported C translation {}",
+ .{ZigClangCompoundAssignOperator_getOpcode(stmt)},
+ ),
+ }
+}
+
+fn transCreateCompoundAssign(
+ rp: RestorePoint,
+ scope: *Scope,
+ stmt: *const ZigClangCompoundAssignOperator,
+ assign_op: ast.Node.InfixOp.Op,
+ assign_tok_id: std.zig.Token.Id,
+ assign_bytes: []const u8,
+ bin_op: ast.Node.InfixOp.Op,
+ bin_tok_id: std.zig.Token.Id,
+ bin_bytes: []const u8,
+ used: ResultUsed,
+) TransError!*ast.Node {
+ const is_shift = bin_op == .BitShiftLeft or bin_op == .BitShiftRight;
+ const lhs = ZigClangCompoundAssignOperator_getLHS(stmt);
+ const rhs = ZigClangCompoundAssignOperator_getRHS(stmt);
+ const loc = ZigClangCompoundAssignOperator_getBeginLoc(stmt);
+ if (used == .unused) {
+ // common case
+ // c: lhs += rhs
+ // zig: lhs += rhs
+ const lhs_node = try transExpr(rp, scope, lhs, .used, .l_value);
+ const eq_token = try appendToken(rp.c, assign_tok_id, assign_bytes);
+ var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
+
+ if (is_shift) {
+ const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
+ const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);
+ try as_node.params.push(rhs_type);
+ _ = try appendToken(rp.c, .Comma, ",");
+ try as_node.params.push(rhs_node);
+ as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
+ rhs_node = &as_node.base;
+ }
+ if (scope.id != .Condition)
+ _ = try appendToken(rp.c, .Semicolon, ";");
+ return transCreateNodeInfixOp(rp, scope, lhs_node, assign_op, eq_token, rhs_node, .used, false);
+ }
+ // worst case
+ // c: lhs += rhs
+ // zig: (blk: {
+ // zig: const _ref = &lhs;
+ // zig: _ref.* = _ref.* + rhs;
+ // zig: break :blk _ref.*
+ // zig: })
+ const block_scope = try Scope.Block.init(rp.c, scope, "blk");
+ block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
+ const ref = try std.fmt.allocPrint(rp.c.a(), "_ref_{}", .{rp.c.getMangle()});
+
+ const node = try transCreateNodeVarDecl(rp.c, false, true, ref);
+ node.eq_token = try appendToken(rp.c, .Equal, "=");
+ const addr_node = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&");
+ addr_node.rhs = try transExpr(rp, scope, lhs, .used, .l_value);
+ node.init_node = &addr_node.base;
+ node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
+ try block_scope.block_node.statements.push(&node.base);
+
+ const lhs_node = try transCreateNodeIdentifier(rp.c, ref);
+ const ref_node = try transCreateNodePtrDeref(rp.c, lhs_node);
+ _ = try appendToken(rp.c, .Semicolon, ";");
+ const bin_token = try appendToken(rp.c, bin_tok_id, bin_bytes);
+ var rhs_node = try transExpr(rp, scope, rhs, .used, .r_value);
+ if (is_shift) {
+ const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
+ const rhs_type = try qualTypeToLog2IntRef(rp, getExprQualType(rp.c, rhs), loc);
+ try as_node.params.push(rhs_type);
+ _ = try appendToken(rp.c, .Comma, ",");
+ try as_node.params.push(rhs_node);
+ as_node.rparen_token = try appendToken(rp.c, .RParen, ")");
+ rhs_node = &as_node.base;
+ }
+ const rhs_bin = try transCreateNodeInfixOp(rp, scope, ref_node, bin_op, bin_token, rhs_node, .used, false);
+
+ _ = try appendToken(rp.c, .Semicolon, ";");
+
+ const eq_token = try appendToken(rp.c, .Equal, "=");
+ const assign = try transCreateNodeInfixOp(rp, scope, ref_node, .Assign, eq_token, rhs_bin, .used, false);
+ try block_scope.block_node.statements.push(assign);
+
+ const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
+ break_node.rhs = ref_node;
+ try block_scope.block_node.statements.push(&break_node.base);
+ block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
+ // semicolon must immediately follow rbrace because it is the last token in a block
+ _ = try appendToken(rp.c, .Semicolon, ";");
+ return &block_scope.block_node.base;
+}
+
fn transCPtrCast(
rp: RestorePoint,
loc: ZigClangSourceLocation,
@@ -2585,7 +2702,7 @@ fn qualTypeToLog2IntRef(rp: RestorePoint, qt: ZigClangQualType, source_loc: ZigC
const inner_field_access = try transCreateNodeFieldAccess(rp.c, &import_fn_call.base, "math");
const outer_field_access = try transCreateNodeFieldAccess(rp.c, inner_field_access, "Log2Int");
const log2int_fn_call = try transCreateNodeFnCall(rp.c, outer_field_access);
- try @ptrCast(*ast.Node.SuffixOp.Op.Call, &log2int_fn_call.op).params.push(zig_type_node);
+ try @fieldParentPtr(ast.Node.SuffixOp, "base", &log2int_fn_call.base).op.Call.params.push(zig_type_node);
log2int_fn_call.rtoken = try appendToken(rp.c, .RParen, ")");
return &log2int_fn_call.base;
@@ -3317,7 +3434,7 @@ fn transCreateNodeShiftOp(
const lhs_expr = ZigClangBinaryOperator_getLHS(stmt);
const rhs_expr = ZigClangBinaryOperator_getRHS(stmt);
const rhs_location = ZigClangExpr_getBeginLoc(rhs_expr);
- // lhs >> u5(rh)
+ // lhs >> @as(u5, rh)
const lhs = try transExpr(rp, scope, lhs_expr, .used, .l_value);
const op_token = try appendToken(rp.c, op_tok_id, bytes);
test/translate_c.zig
@@ -1830,33 +1830,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
-
- cases.add("macro defines string literal with hex",
- \\#define FOO "aoeu\xab derp"
- \\#define FOO2 "aoeu\x0007a derp"
- \\#define FOO_CHAR '\xfF'
- , &[_][]const u8{
- \\pub const FOO = "aoeu\xab derp";
- ,
- \\pub const FOO2 = "aoeuz derp";
- ,
- \\pub const FOO_CHAR = 255;
- });
-
- cases.add("macro defines string literal with octal",
- \\#define FOO "aoeu\023 derp"
- \\#define FOO2 "aoeu\0234 derp"
- \\#define FOO_CHAR '\077'
- , &[_][]const u8{
- \\pub const FOO = "aoeu\x13 derp";
- ,
- \\pub const FOO2 = "aoeu\x134 derp";
- ,
- \\pub const FOO_CHAR = 63;
- });
-
- cases.addC("shift right assign",
+ cases.add_2("shift right assign",
\\int log2(unsigned a) {
\\ int i = 0;
\\ while (a > 0) {
@@ -1864,18 +1838,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ }
\\ return i;
\\}
- , &[_][]const u8{
- \\pub export fn log2(_arg_a: c_uint) c_int {
- \\ var a = _arg_a;
+ , &[_][]const u8{// TODO function arguments should be copied
+ \\pub export fn log2(a: c_uint) c_int {
\\ var i: c_int = 0;
- \\ while (a > @as(c_uint, 0)) {
- \\ a >>= @as(@import("std").math.Log2Int(c_uint), 1);
+ \\ while ((a > @as(c_uint, 0))) {
+ \\ a >>= @as(@import("std").math.Log2Int(c_int), 1);
\\ }
\\ return i;
\\}
});
- cases.addC("shift right assign with a fixed size type",
+ cases.add_2("shift right assign with a fixed size type",
\\#include <stdint.h>
\\int log2(uint32_t a) {
\\ int i = 0;
@@ -1885,27 +1858,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return i;
\\}
, &[_][]const u8{
- \\pub export fn log2(_arg_a: u32) c_int {
- \\ var a = _arg_a;
+ \\pub export fn log2(a: u32) c_int {
\\ var i: c_int = 0;
- \\ while (a > @as(c_uint, 0)) {
- \\ a >>= @as(u5, 1);
+ \\ while ((a > @as(c_uint, 0))) {
+ \\ a >>= @as(@import("std").math.Log2Int(c_int), 1);
\\ }
\\ return i;
\\}
});
- cases.addC("__extension__ cast",
- \\int foo(void) {
- \\ return __extension__ 1;
- \\}
- , &[_][]const u8{
- \\pub export fn foo() c_int {
- \\ return 1;
- \\}
- });
-
- cases.addC("compound assignment operators",
+ cases.add_2("compound assignment operators",
\\void foo(void) {
\\ int a = 0;
\\ a += (a += 1);
@@ -1920,50 +1882,50 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var a: c_int = 0;
- \\ a += (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* + 1);
- \\ break :x _ref.*;
+ \\ a += (blk: {
+ \\ const _ref_1 = &a;
+ \\ _ref_1.* = _ref_1.* + 1;
+ \\ break :blk _ref_1.*;
\\ });
- \\ a -= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* - 1);
- \\ break :x _ref.*;
+ \\ a -= (blk: {
+ \\ const _ref_2 = &a;
+ \\ _ref_2.* = _ref_2.* - 1;
+ \\ break :blk _ref_2.*;
\\ });
- \\ a *= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* * 1);
- \\ break :x _ref.*;
+ \\ a *= (blk: {
+ \\ const _ref_3 = &a;
+ \\ _ref_3.* = _ref_3.* * 1;
+ \\ break :blk _ref_3.*;
\\ });
- \\ a &= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* & 1);
- \\ break :x _ref.*;
+ \\ a &= (blk: {
+ \\ const _ref_4 = &a;
+ \\ _ref_4.* = _ref_4.* & 1;
+ \\ break :blk _ref_4.*;
\\ });
- \\ a |= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* | 1);
- \\ break :x _ref.*;
+ \\ a |= (blk: {
+ \\ const _ref_5 = &a;
+ \\ _ref_5.* = _ref_5.* | 1;
+ \\ break :blk _ref_5.*;
\\ });
- \\ a ^= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* ^ 1);
- \\ break :x _ref.*;
+ \\ a ^= (blk: {
+ \\ const _ref_6 = &a;
+ \\ _ref_6.* = _ref_6.* ^ 1;
+ \\ break :blk _ref_6.*;
\\ });
- \\ a >>= @as(@import("std").math.Log2Int(c_int), (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_int), 1));
- \\ break :x _ref.*;
+ \\ a >>= @as(@import("std").math.Log2Int(c_int), (blk: {
+ \\ const _ref_7 = &a;
+ \\ _ref_7.* = _ref_7.* >> @as(@import("std").math.Log2Int(c_int), 1);
+ \\ break :blk _ref_7.*;
\\ }));
- \\ a <<= @as(@import("std").math.Log2Int(c_int), (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_int), 1));
- \\ break :x _ref.*;
+ \\ a <<= @as(@import("std").math.Log2Int(c_int), (blk: {
+ \\ const _ref_8 = &a;
+ \\ _ref_8.* = _ref_8.* << @as(@import("std").math.Log2Int(c_int), 1);
+ \\ break :blk _ref_8.*;
\\ }));
\\}
});
- cases.addC("compound assignment operators unsigned",
+ cases.add_2("compound assignment operators unsigned",
\\void foo(void) {
\\ unsigned a = 0;
\\ a += (a += 1);
@@ -1978,50 +1940,50 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
, &[_][]const u8{
\\pub export fn foo() void {
\\ var a: c_uint = @as(c_uint, 0);
- \\ a +%= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* +% @as(c_uint, 1));
- \\ break :x _ref.*;
+ \\ a +%= (blk: {
+ \\ const _ref_1 = &a;
+ \\ _ref_1.* = _ref_1.* +% @as(c_uint, 1);
+ \\ break :blk _ref_1.*;
\\ });
- \\ a -%= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* -% @as(c_uint, 1));
- \\ break :x _ref.*;
+ \\ a -%= (blk: {
+ \\ const _ref_2 = &a;
+ \\ _ref_2.* = _ref_2.* -% @as(c_uint, 1);
+ \\ break :blk _ref_2.*;
\\ });
- \\ a *%= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* *% @as(c_uint, 1));
- \\ break :x _ref.*;
+ \\ a *%= (blk: {
+ \\ const _ref_3 = &a;
+ \\ _ref_3.* = _ref_3.* *% @as(c_uint, 1);
+ \\ break :blk _ref_3.*;
\\ });
- \\ a &= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* & @as(c_uint, 1));
- \\ break :x _ref.*;
+ \\ a &= (blk: {
+ \\ const _ref_4 = &a;
+ \\ _ref_4.* = _ref_4.* & @as(c_uint, 1);
+ \\ break :blk _ref_4.*;
\\ });
- \\ a |= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* | @as(c_uint, 1));
- \\ break :x _ref.*;
+ \\ a |= (blk: {
+ \\ const _ref_5 = &a;
+ \\ _ref_5.* = _ref_5.* | @as(c_uint, 1);
+ \\ break :blk _ref_5.*;
\\ });
- \\ a ^= (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* ^ @as(c_uint, 1));
- \\ break :x _ref.*;
+ \\ a ^= (blk: {
+ \\ const _ref_6 = &a;
+ \\ _ref_6.* = _ref_6.* ^ @as(c_uint, 1);
+ \\ break :blk _ref_6.*;
\\ });
- \\ a >>= @as(@import("std").math.Log2Int(c_uint), (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_uint), 1));
- \\ break :x _ref.*;
+ \\ a >>= @as(@import("std").math.Log2Int(c_uint), (blk: {
+ \\ const _ref_7 = &a;
+ \\ _ref_7.* = _ref_7.* >> @as(@import("std").math.Log2Int(c_int), 1);
+ \\ break :blk _ref_7.*;
\\ }));
- \\ a <<= @as(@import("std").math.Log2Int(c_uint), (x: {
- \\ const _ref = &a;
- \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_uint), 1));
- \\ break :x _ref.*;
+ \\ a <<= @as(@import("std").math.Log2Int(c_uint), (blk: {
+ \\ const _ref_8 = &a;
+ \\ _ref_8.* = _ref_8.* << @as(@import("std").math.Log2Int(c_int), 1);
+ \\ break :blk _ref_8.*;
\\ }));
\\}
});
- cases.addC("post increment/decrement",
+ cases.add_2("post increment/decrement",
\\void foo(void) {
\\ int i = 0;
\\ unsigned u = 0;
@@ -2042,30 +2004,66 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ i -= 1;
\\ u +%= 1;
\\ u -%= 1;
- \\ i = (x: {
- \\ const _ref = &i;
- \\ const _tmp = _ref.*;
- \\ _ref.* += 1;
- \\ break :x _tmp;
- \\ });
- \\ i = (x: {
- \\ const _ref = &i;
- \\ const _tmp = _ref.*;
- \\ _ref.* -= 1;
- \\ break :x _tmp;
- \\ });
- \\ u = (x: {
- \\ const _ref = &u;
- \\ const _tmp = _ref.*;
- \\ _ref.* +%= 1;
- \\ break :x _tmp;
- \\ });
- \\ u = (x: {
- \\ const _ref = &u;
- \\ const _tmp = _ref.*;
- \\ _ref.* -%= 1;
- \\ break :x _tmp;
- \\ });
+ \\ i = blk: {
+ \\ const _ref_1 = &i;
+ \\ const _tmp_2 = _ref_1.*;
+ \\ _ref_1.* += 1;
+ \\ break :blk _tmp_2;
+ \\ };
+ \\ i = blk: {
+ \\ const _ref_3 = &i;
+ \\ const _tmp_4 = _ref_3.*;
+ \\ _ref_3.* -= 1;
+ \\ break :blk _tmp_4;
+ \\ };
+ \\ u = blk: {
+ \\ const _ref_5 = &u;
+ \\ const _tmp_6 = _ref_5.*;
+ \\ _ref_5.* +%= 1;
+ \\ break :blk _tmp_6;
+ \\ };
+ \\ u = blk: {
+ \\ const _ref_7 = &u;
+ \\ const _tmp_8 = _ref_7.*;
+ \\ _ref_7.* -%= 1;
+ \\ break :blk _tmp_8;
+ \\ };
+ \\}
+ });
+
+ /////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
+
+ cases.add("macro defines string literal with hex",
+ \\#define FOO "aoeu\xab derp"
+ \\#define FOO2 "aoeu\x0007a derp"
+ \\#define FOO_CHAR '\xfF'
+ , &[_][]const u8{
+ \\pub const FOO = "aoeu\xab derp";
+ ,
+ \\pub const FOO2 = "aoeuz derp";
+ ,
+ \\pub const FOO_CHAR = 255;
+ });
+
+ cases.add("macro defines string literal with octal",
+ \\#define FOO "aoeu\023 derp"
+ \\#define FOO2 "aoeu\0234 derp"
+ \\#define FOO_CHAR '\077'
+ , &[_][]const u8{
+ \\pub const FOO = "aoeu\x13 derp";
+ ,
+ \\pub const FOO2 = "aoeu\x134 derp";
+ ,
+ \\pub const FOO_CHAR = 63;
+ });
+
+ cases.addC("__extension__ cast",
+ \\int foo(void) {
+ \\ return __extension__ 1;
+ \\}
+ , &[_][]const u8{
+ \\pub export fn foo() c_int {
+ \\ return 1;
\\}
});
@@ -2789,4 +2787,207 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ });
\\}
});
+
+ cases.addC("shift right assign",
+ \\int log2(unsigned a) {
+ \\ int i = 0;
+ \\ while (a > 0) {
+ \\ a >>= 1;
+ \\ }
+ \\ return i;
+ \\}
+ , &[_][]const u8{
+ \\pub export fn log2(_arg_a: c_uint) c_int {
+ \\ var a = _arg_a;
+ \\ var i: c_int = 0;
+ \\ while (a > @as(c_uint, 0)) {
+ \\ a >>= @as(@import("std").math.Log2Int(c_uint), 1);
+ \\ }
+ \\ return i;
+ \\}
+ });
+
+ cases.addC("shift right assign with a fixed size type",
+ \\#include <stdint.h>
+ \\int log2(uint32_t a) {
+ \\ int i = 0;
+ \\ while (a > 0) {
+ \\ a >>= 1;
+ \\ }
+ \\ return i;
+ \\}
+ , &[_][]const u8{
+ \\pub export fn log2(_arg_a: u32) c_int {
+ \\ var a = _arg_a;
+ \\ var i: c_int = 0;
+ \\ while (a > @as(c_uint, 0)) {
+ \\ a >>= @as(u5, 1);
+ \\ }
+ \\ return i;
+ \\}
+ });
+
+ cases.addC("compound assignment operators",
+ \\void foo(void) {
+ \\ int a = 0;
+ \\ a += (a += 1);
+ \\ a -= (a -= 1);
+ \\ a *= (a *= 1);
+ \\ a &= (a &= 1);
+ \\ a |= (a |= 1);
+ \\ a ^= (a ^= 1);
+ \\ a >>= (a >>= 1);
+ \\ a <<= (a <<= 1);
+ \\}
+ , &[_][]const u8{
+ \\pub export fn foo() void {
+ \\ var a: c_int = 0;
+ \\ a += (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* + 1);
+ \\ break :x _ref.*;
+ \\ });
+ \\ a -= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* - 1);
+ \\ break :x _ref.*;
+ \\ });
+ \\ a *= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* * 1);
+ \\ break :x _ref.*;
+ \\ });
+ \\ a &= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* & 1);
+ \\ break :x _ref.*;
+ \\ });
+ \\ a |= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* | 1);
+ \\ break :x _ref.*;
+ \\ });
+ \\ a ^= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* ^ 1);
+ \\ break :x _ref.*;
+ \\ });
+ \\ a >>= @as(@import("std").math.Log2Int(c_int), (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_int), 1));
+ \\ break :x _ref.*;
+ \\ }));
+ \\ a <<= @as(@import("std").math.Log2Int(c_int), (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_int), 1));
+ \\ break :x _ref.*;
+ \\ }));
+ \\}
+ });
+
+ cases.addC("compound assignment operators unsigned",
+ \\void foo(void) {
+ \\ unsigned a = 0;
+ \\ a += (a += 1);
+ \\ a -= (a -= 1);
+ \\ a *= (a *= 1);
+ \\ a &= (a &= 1);
+ \\ a |= (a |= 1);
+ \\ a ^= (a ^= 1);
+ \\ a >>= (a >>= 1);
+ \\ a <<= (a <<= 1);
+ \\}
+ , &[_][]const u8{
+ \\pub export fn foo() void {
+ \\ var a: c_uint = @as(c_uint, 0);
+ \\ a +%= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* +% @as(c_uint, 1));
+ \\ break :x _ref.*;
+ \\ });
+ \\ a -%= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* -% @as(c_uint, 1));
+ \\ break :x _ref.*;
+ \\ });
+ \\ a *%= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* *% @as(c_uint, 1));
+ \\ break :x _ref.*;
+ \\ });
+ \\ a &= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* & @as(c_uint, 1));
+ \\ break :x _ref.*;
+ \\ });
+ \\ a |= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* | @as(c_uint, 1));
+ \\ break :x _ref.*;
+ \\ });
+ \\ a ^= (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* ^ @as(c_uint, 1));
+ \\ break :x _ref.*;
+ \\ });
+ \\ a >>= @as(@import("std").math.Log2Int(c_uint), (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_uint), 1));
+ \\ break :x _ref.*;
+ \\ }));
+ \\ a <<= @as(@import("std").math.Log2Int(c_uint), (x: {
+ \\ const _ref = &a;
+ \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_uint), 1));
+ \\ break :x _ref.*;
+ \\ }));
+ \\}
+ });
+
+ cases.addC("post increment/decrement",
+ \\void foo(void) {
+ \\ int i = 0;
+ \\ unsigned u = 0;
+ \\ i++;
+ \\ i--;
+ \\ u++;
+ \\ u--;
+ \\ i = i++;
+ \\ i = i--;
+ \\ u = u++;
+ \\ u = u--;
+ \\}
+ , &[_][]const u8{
+ \\pub export fn foo() void {
+ \\ var i: c_int = 0;
+ \\ var u: c_uint = @as(c_uint, 0);
+ \\ i += 1;
+ \\ i -= 1;
+ \\ u +%= 1;
+ \\ u -%= 1;
+ \\ i = (x: {
+ \\ const _ref = &i;
+ \\ const _tmp = _ref.*;
+ \\ _ref.* += 1;
+ \\ break :x _tmp;
+ \\ });
+ \\ i = (x: {
+ \\ const _ref = &i;
+ \\ const _tmp = _ref.*;
+ \\ _ref.* -= 1;
+ \\ break :x _tmp;
+ \\ });
+ \\ u = (x: {
+ \\ const _ref = &u;
+ \\ const _tmp = _ref.*;
+ \\ _ref.* +%= 1;
+ \\ break :x _tmp;
+ \\ });
+ \\ u = (x: {
+ \\ const _ref = &u;
+ \\ const _tmp = _ref.*;
+ \\ _ref.* -%= 1;
+ \\ break :x _tmp;
+ \\ });
+ \\}
+ });
}