| author | |
| committer | |
| log | 21bc3353b8812ea097afb52fef411a4fb32bfea9 |
| tree | 579c88b542ca6bb61948caf211f776cc25f355b9 |
| parent | 6d7025d0c5c619773f0f5cc49edbd30713a7328d |
| signature | Commit is signed but in an unrecognized format. |
4 files changed, 365 insertions(+), 261 deletions(-)
lib/std/fmt.zig+3-1| ... | ... | @@ -582,7 +582,9 @@ pub fn formatAsciiChar( |
| 582 | 582 | comptime Errors: type, |
| 583 | 583 | output: fn (@TypeOf(context), []const u8) Errors!void, |
| 584 | 584 | ) Errors!void { |
| 585 | return output(context, @as(*const [1]u8, &c)[0..]); | |
| 585 | if (std.ascii.isPrint(c)) | |
| 586 | return output(context, @as(*const [1]u8, &c)[0..]); | |
| 587 | return format(context, Errors, output, "\\x{x:0<2}", .{c}); | |
| 586 | 588 | } |
| 587 | 589 | |
| 588 | 590 | pub fn formatBuf( |
src-self-hosted/clang.zig+13| ... | ... | @@ -78,6 +78,7 @@ pub const struct_ZigClangInitListExpr = @OpaqueType(); |
| 78 | 78 | pub const ZigClangPreprocessingRecord = @OpaqueType(); |
| 79 | 79 | pub const ZigClangFloatingLiteral = @OpaqueType(); |
| 80 | 80 | pub const ZigClangConstantExpr = @OpaqueType(); |
| 81 | pub const ZigClangCharacterLiteral = @OpaqueType(); | |
| 81 | 82 | |
| 82 | 83 | pub const ZigClangBO = extern enum { |
| 83 | 84 | PtrMemD, |
| ... | ... | @@ -712,6 +713,14 @@ pub const ZigClangStringLiteral_StringKind = extern enum { |
| 712 | 713 | UTF32, |
| 713 | 714 | }; |
| 714 | 715 | |
| 716 | pub const ZigClangCharacterLiteral_CharacterKind = extern enum { | |
| 717 | Ascii, | |
| 718 | Wide, | |
| 719 | UTF8, | |
| 720 | UTF16, | |
| 721 | UTF32, | |
| 722 | }; | |
| 723 | ||
| 715 | 724 | pub const ZigClangRecordDecl_field_iterator = extern struct { |
| 716 | 725 | opaque: *c_void, |
| 717 | 726 | }; |
| ... | ... | @@ -1077,3 +1086,7 @@ pub extern fn ZigClangExpr_EvaluateAsConstantExpr(*const ZigClangExpr, *ZigClang |
| 1077 | 1086 | |
| 1078 | 1087 | pub extern fn ZigClangPredefinedExpr_getFunctionName(*const ZigClangPredefinedExpr) *const ZigClangStringLiteral; |
| 1079 | 1088 | |
| 1089 | pub extern fn ZigClangCharacterLiteral_getBeginLoc(*const ZigClangCharacterLiteral) ZigClangSourceLocation; | |
| 1090 | pub extern fn ZigClangCharacterLiteral_getKind(*const ZigClangCharacterLiteral) ZigClangCharacterLiteral_CharacterKind; | |
| 1091 | pub extern fn ZigClangCharacterLiteral_getValue(*const ZigClangCharacterLiteral) c_uint; | |
| 1092 |
src-self-hosted/translate_c.zig+97-68| ... | ... | @@ -49,7 +49,10 @@ const Scope = struct { |
| 49 | 49 | Root, |
| 50 | 50 | Condition, |
| 51 | 51 | FnDef, |
| 52 | ||
| 53 | /// used when getting a member `a.b` | |
| 52 | 54 | Ref, |
| 55 | Loop, | |
| 53 | 56 | }; |
| 54 | 57 | |
| 55 | 58 | const Switch = struct { |
| ... | ... | @@ -59,11 +62,6 @@ const Scope = struct { |
| 59 | 62 | has_default: bool = false, |
| 60 | 63 | }; |
| 61 | 64 | |
| 62 | /// used when getting a member `a.b` | |
| 63 | const Ref = struct { | |
| 64 | base: Scope, | |
| 65 | }; | |
| 66 | ||
| 67 | 65 | const Block = struct { |
| 68 | 66 | base: Scope, |
| 69 | 67 | block_node: *ast.Node.Block, |
| ... | ... | @@ -125,10 +123,6 @@ const Scope = struct { |
| 125 | 123 | } |
| 126 | 124 | }; |
| 127 | 125 | |
| 128 | const Condition = struct { | |
| 129 | base: Scope, | |
| 130 | }; | |
| 131 | ||
| 132 | 126 | const FnDef = struct { |
| 133 | 127 | base: Scope, |
| 134 | 128 | params: AliasList, |
| ... | ... | @@ -169,7 +163,6 @@ const Scope = struct { |
| 169 | 163 | .Root => unreachable, |
| 170 | 164 | .Block => return @fieldParentPtr(Block, "base", scope), |
| 171 | 165 | .Condition => { |
| 172 | const cond = @fieldParentPtr(Condition, "base", scope); | |
| 173 | 166 | // comma operator used |
| 174 | 167 | return try Block.init(c, scope, "blk"); |
| 175 | 168 | }, |
| ... | ... | @@ -192,6 +185,7 @@ const Scope = struct { |
| 192 | 185 | .FnDef => @fieldParentPtr(FnDef, "base", scope).getAlias(name), |
| 193 | 186 | .Block => @fieldParentPtr(Block, "base", scope).getAlias(name), |
| 194 | 187 | .Switch, |
| 188 | .Loop, | |
| 195 | 189 | .Condition => scope.parent.?.getAlias(name), |
| 196 | 190 | }; |
| 197 | 191 | } |
| ... | ... | @@ -203,6 +197,7 @@ const Scope = struct { |
| 203 | 197 | .FnDef => @fieldParentPtr(FnDef, "base", scope).contains(name), |
| 204 | 198 | .Block => @fieldParentPtr(Block, "base", scope).contains(name), |
| 205 | 199 | .Switch, |
| 200 | .Loop, | |
| 206 | 201 | .Condition => scope.parent.?.contains(name), |
| 207 | 202 | }; |
| 208 | 203 | } |
| ... | ... | @@ -213,6 +208,7 @@ const Scope = struct { |
| 213 | 208 | switch (scope.id) { |
| 214 | 209 | .FnDef => unreachable, |
| 215 | 210 | .Switch => return scope, |
| 211 | .Loop => return scope, | |
| 216 | 212 | else => scope = scope.parent.?, |
| 217 | 213 | } |
| 218 | 214 | } |
| ... | ... | @@ -434,7 +430,7 @@ fn visitFnDecl(c: *Context, fn_decl: *const ZigClangFunctionDecl) Error!void { |
| 434 | 430 | error.OutOfMemory => |e| return e, |
| 435 | 431 | }; |
| 436 | 432 | }, |
| 437 | else => unreachable, | |
| 433 | else => return failDecl(c, fn_decl_loc, fn_name, "unable to resolve function type {}", .{ZigClangType_getTypeClass(fn_type)}), | |
| 438 | 434 | }; |
| 439 | 435 | |
| 440 | 436 | if (!decl_ctx.has_body) { |
| ... | ... | @@ -862,6 +858,7 @@ fn transStmt( |
| 862 | 858 | .DefaultStmtClass => return transDefault(rp, scope, @ptrCast(*const ZigClangDefaultStmt, stmt)), |
| 863 | 859 | .ConstantExprClass => return transConstantExpr(rp, scope, @ptrCast(*const ZigClangExpr, stmt), result_used), |
| 864 | 860 | .PredefinedExprClass => return transPredefinedExpr(rp, scope, @ptrCast(*const ZigClangPredefinedExpr, stmt), result_used), |
| 861 | .CharacterLiteralClass => return transCharLiteral(rp, scope, @ptrCast(*const ZigClangCharacterLiteral, stmt), result_used), | |
| 865 | 862 | else => { |
| 866 | 863 | return revertAndWarn( |
| 867 | 864 | rp, |
| ... | ... | @@ -1202,7 +1199,7 @@ fn transStringLiteral( |
| 1202 | 1199 | |
| 1203 | 1200 | const token = try appendToken(rp.c, .StringLiteral, buf); |
| 1204 | 1201 | const node = try rp.c.a().create(ast.Node.StringLiteral); |
| 1205 | node.* = ast.Node.StringLiteral{ | |
| 1202 | node.* = .{ | |
| 1206 | 1203 | .token = token, |
| 1207 | 1204 | }; |
| 1208 | 1205 | return maybeSuppressResult(rp, scope, result_used, &node.base); |
| ... | ... | @@ -1237,18 +1234,15 @@ fn writeEscapedString(buf: []u8, s: []const u8) void { |
| 1237 | 1234 | |
| 1238 | 1235 | // Returns either a string literal or a slice of `buf`. |
| 1239 | 1236 | fn escapeChar(c: u8, char_buf: *[4]u8) []const u8 { |
| 1240 | // TODO: https://github.com/ziglang/zig/issues/2749 | |
| 1241 | const escaped = switch (c) { | |
| 1242 | // Printable ASCII except for ' " \ | |
| 1243 | ' ', '!', '#'...'&', '('...'[', ']'...'~' => ([_]u8{c})[0..], | |
| 1244 | '\'', '\"', '\\' => ([_]u8{ '\\', c })[0..], | |
| 1245 | '\n' => return "\\n"[0..], | |
| 1246 | '\r' => return "\\r"[0..], | |
| 1247 | '\t' => return "\\t"[0..], | |
| 1248 | else => return std.fmt.bufPrint(char_buf[0..], "\\x{x:2}", .{c}) catch unreachable, | |
| 1237 | return switch (c) { | |
| 1238 | '\"' => "\\\""[0..], | |
| 1239 | '\'' => "\\'"[0..], | |
| 1240 | '\\' => "\\\\"[0..], | |
| 1241 | '\n' => "\\n"[0..], | |
| 1242 | '\r' => "\\r"[0..], | |
| 1243 | '\t' => "\\t"[0..], | |
| 1244 | else => std.fmt.bufPrint(char_buf[0..], "{c}", .{c}) catch unreachable, | |
| 1249 | 1245 | }; |
| 1250 | std.mem.copy(u8, char_buf, escaped); | |
| 1251 | return char_buf[0..escaped.len]; | |
| 1252 | 1246 | } |
| 1253 | 1247 | |
| 1254 | 1248 | fn transCCast( |
| ... | ... | @@ -1459,13 +1453,11 @@ fn transIfStmt( |
| 1459 | 1453 | // if (c) t else e |
| 1460 | 1454 | const if_node = try transCreateNodeIf(rp.c); |
| 1461 | 1455 | |
| 1462 | var cond_scope = Scope.Condition{ | |
| 1463 | .base = .{ | |
| 1464 | .parent = scope, | |
| 1465 | .id = .Condition, | |
| 1466 | }, | |
| 1456 | var cond_scope = Scope{ | |
| 1457 | .parent = scope, | |
| 1458 | .id = .Condition, | |
| 1467 | 1459 | }; |
| 1468 | if_node.condition = try transBoolExpr(rp, &cond_scope.base, @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt)), .used, .r_value, false); | |
| 1460 | if_node.condition = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangIfStmt_getCond(stmt)), .used, .r_value, false); | |
| 1469 | 1461 | _ = try appendToken(rp.c, .RParen, ")"); |
| 1470 | 1462 | |
| 1471 | 1463 | if_node.body = try transStmt(rp, scope, ZigClangIfStmt_getThen(stmt), .unused, .r_value); |
| ... | ... | @@ -1485,16 +1477,18 @@ fn transWhileLoop( |
| 1485 | 1477 | ) TransError!*ast.Node { |
| 1486 | 1478 | const while_node = try transCreateNodeWhile(rp.c); |
| 1487 | 1479 | |
| 1488 | var cond_scope = Scope.Condition{ | |
| 1489 | .base = .{ | |
| 1490 | .parent = scope, | |
| 1491 | .id = .Condition, | |
| 1492 | }, | |
| 1480 | var cond_scope = Scope{ | |
| 1481 | .parent = scope, | |
| 1482 | .id = .Condition, | |
| 1493 | 1483 | }; |
| 1494 | while_node.condition = try transBoolExpr(rp, &cond_scope.base, @ptrCast(*const ZigClangExpr, ZigClangWhileStmt_getCond(stmt)), .used, .r_value, false); | |
| 1484 | while_node.condition = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangWhileStmt_getCond(stmt)), .used, .r_value, false); | |
| 1495 | 1485 | _ = try appendToken(rp.c, .RParen, ")"); |
| 1496 | 1486 | |
| 1497 | while_node.body = try transStmt(rp, scope, ZigClangWhileStmt_getBody(stmt), .unused, .r_value); | |
| 1487 | var loop_scope = Scope{ | |
| 1488 | .parent = scope, | |
| 1489 | .id = .Loop, | |
| 1490 | }; | |
| 1491 | while_node.body = try transStmt(rp, &loop_scope, ZigClangWhileStmt_getBody(stmt), .unused, .r_value); | |
| 1498 | 1492 | return &while_node.base; |
| 1499 | 1493 | } |
| 1500 | 1494 | |
| ... | ... | @@ -1508,6 +1502,10 @@ fn transDoWhileLoop( |
| 1508 | 1502 | while_node.condition = try transCreateNodeBoolLiteral(rp.c, true); |
| 1509 | 1503 | _ = try appendToken(rp.c, .RParen, ")"); |
| 1510 | 1504 | var new = false; |
| 1505 | var loop_scope = Scope{ | |
| 1506 | .parent = scope, | |
| 1507 | .id = .Loop, | |
| 1508 | }; | |
| 1511 | 1509 | |
| 1512 | 1510 | const body_node = if (ZigClangStmt_getStmtClass(ZigClangDoStmt_getBody(stmt)) == .CompoundStmtClass) blk: { |
| 1513 | 1511 | // there's already a block in C, so we'll append our condition to it. |
| ... | ... | @@ -1520,7 +1518,7 @@ fn transDoWhileLoop( |
| 1520 | 1518 | // zig: b; |
| 1521 | 1519 | // zig: if (!cond) break; |
| 1522 | 1520 | // zig: } |
| 1523 | break :blk (try transStmt(rp, scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value)).cast(ast.Node.Block).?; | |
| 1521 | break :blk (try transStmt(rp, &loop_scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value)).cast(ast.Node.Block).?; | |
| 1524 | 1522 | } else blk: { |
| 1525 | 1523 | // the C statement is without a block, so we need to create a block to contain it. |
| 1526 | 1524 | // c: do |
| ... | ... | @@ -1532,20 +1530,18 @@ fn transDoWhileLoop( |
| 1532 | 1530 | // zig: } |
| 1533 | 1531 | new = true; |
| 1534 | 1532 | const block = try transCreateNodeBlock(rp.c, null); |
| 1535 | try block.statements.push(try transStmt(rp, scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value)); | |
| 1533 | try block.statements.push(try transStmt(rp, &loop_scope, ZigClangDoStmt_getBody(stmt), .unused, .r_value)); | |
| 1536 | 1534 | break :blk block; |
| 1537 | 1535 | }; |
| 1538 | 1536 | |
| 1539 | 1537 | // if (!cond) break; |
| 1540 | 1538 | const if_node = try transCreateNodeIf(rp.c); |
| 1541 | var cond_scope = Scope.Condition{ | |
| 1542 | .base = .{ | |
| 1543 | .parent = scope, | |
| 1544 | .id = .Condition, | |
| 1545 | }, | |
| 1539 | var cond_scope = Scope{ | |
| 1540 | .parent = scope, | |
| 1541 | .id = .Condition, | |
| 1546 | 1542 | }; |
| 1547 | 1543 | const prefix_op = try transCreateNodePrefixOp(rp.c, .BoolNot, .Bang, "!"); |
| 1548 | prefix_op.rhs = try transBoolExpr(rp, &cond_scope.base, @ptrCast(*const ZigClangExpr, ZigClangDoStmt_getCond(stmt)), .used, .r_value, false); | |
| 1544 | prefix_op.rhs = try transBoolExpr(rp, &cond_scope, @ptrCast(*const ZigClangExpr, ZigClangDoStmt_getCond(stmt)), .used, .r_value, true); | |
| 1549 | 1545 | _ = try appendToken(rp.c, .RParen, ")"); |
| 1550 | 1546 | if_node.condition = &prefix_op.base; |
| 1551 | 1547 | if_node.body = &(try transCreateNodeBreak(rp.c, null)).base; |
| ... | ... | @@ -1563,25 +1559,26 @@ fn transForLoop( |
| 1563 | 1559 | scope: *Scope, |
| 1564 | 1560 | stmt: *const ZigClangForStmt, |
| 1565 | 1561 | ) TransError!*ast.Node { |
| 1566 | var inner = scope; | |
| 1562 | var loop_scope = Scope{ | |
| 1563 | .parent = scope, | |
| 1564 | .id = .Loop, | |
| 1565 | }; | |
| 1567 | 1566 | var block = false; |
| 1568 | 1567 | var block_scope: ?*Scope.Block = null; |
| 1569 | 1568 | if (ZigClangForStmt_getInit(stmt)) |init| { |
| 1570 | 1569 | block_scope = try Scope.Block.init(rp.c, scope, null); |
| 1571 | 1570 | block_scope.?.block_node = try transCreateNodeBlock(rp.c, null); |
| 1572 | inner = &block_scope.?.base; | |
| 1573 | _ = try transStmt(rp, inner, init, .unused, .r_value); | |
| 1571 | loop_scope.parent = &block_scope.?.base; | |
| 1572 | _ = try transStmt(rp, &loop_scope, init, .unused, .r_value); | |
| 1574 | 1573 | } |
| 1575 | var cond_scope = Scope.Condition{ | |
| 1576 | .base = .{ | |
| 1577 | .parent = inner, | |
| 1578 | .id = .Condition, | |
| 1579 | }, | |
| 1574 | var cond_scope = Scope{ | |
| 1575 | .parent = scope, | |
| 1576 | .id = .Condition, | |
| 1580 | 1577 | }; |
| 1581 | 1578 | |
| 1582 | 1579 | const while_node = try transCreateNodeWhile(rp.c); |
| 1583 | 1580 | while_node.condition = if (ZigClangForStmt_getCond(stmt)) |cond| |
| 1584 | try transBoolExpr(rp, &cond_scope.base, cond, .used, .r_value, false) | |
| 1581 | try transBoolExpr(rp, &cond_scope, cond, .used, .r_value, false) | |
| 1585 | 1582 | else |
| 1586 | 1583 | try transCreateNodeBoolLiteral(rp.c, true); |
| 1587 | 1584 | _ = try appendToken(rp.c, .RParen, ")"); |
| ... | ... | @@ -1589,11 +1586,11 @@ fn transForLoop( |
| 1589 | 1586 | if (ZigClangForStmt_getInc(stmt)) |incr| { |
| 1590 | 1587 | _ = try appendToken(rp.c, .Colon, ":"); |
| 1591 | 1588 | _ = try appendToken(rp.c, .LParen, "("); |
| 1592 | while_node.continue_expr = try transExpr(rp, &cond_scope.base, incr, .unused, .r_value); | |
| 1589 | while_node.continue_expr = try transExpr(rp, &cond_scope, incr, .unused, .r_value); | |
| 1593 | 1590 | _ = try appendToken(rp.c, .RParen, ")"); |
| 1594 | 1591 | } |
| 1595 | 1592 | |
| 1596 | while_node.body = try transStmt(rp, inner, ZigClangForStmt_getBody(stmt), .unused, .r_value); | |
| 1593 | while_node.body = try transStmt(rp, &loop_scope, ZigClangForStmt_getBody(stmt), .unused, .r_value); | |
| 1597 | 1594 | if (block_scope != null) { |
| 1598 | 1595 | try block_scope.?.block_node.statements.push(&while_node.base); |
| 1599 | 1596 | block_scope.?.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| ... | ... | @@ -1617,13 +1614,11 @@ fn transSwitch( |
| 1617 | 1614 | .pending_block = undefined, |
| 1618 | 1615 | }; |
| 1619 | 1616 | |
| 1620 | var cond_scope = Scope.Condition{ | |
| 1621 | .base = .{ | |
| 1622 | .parent = scope, | |
| 1623 | .id = .Condition, | |
| 1624 | }, | |
| 1617 | var cond_scope = Scope{ | |
| 1618 | .parent = scope, | |
| 1619 | .id = .Condition, | |
| 1625 | 1620 | }; |
| 1626 | switch_node.expr = try transExpr(rp, &cond_scope.base, ZigClangSwitchStmt_getCond(stmt), .used, .r_value); | |
| 1621 | switch_node.expr = try transExpr(rp, &cond_scope, ZigClangSwitchStmt_getCond(stmt), .used, .r_value); | |
| 1627 | 1622 | _ = try appendToken(rp.c, .RParen, ")"); |
| 1628 | 1623 | _ = try appendToken(rp.c, .LBrace, "{"); |
| 1629 | 1624 | switch_node.rbrace = try appendToken(rp.c, .RBrace, "}"); |
| ... | ... | @@ -1753,6 +1748,41 @@ fn transPredefinedExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangPre |
| 1753 | 1748 | return transStringLiteral(rp, scope, ZigClangPredefinedExpr_getFunctionName(expr), used); |
| 1754 | 1749 | } |
| 1755 | 1750 | |
| 1751 | fn transCharLiteral( | |
| 1752 | rp: RestorePoint, | |
| 1753 | scope: *Scope, | |
| 1754 | stmt: *const ZigClangCharacterLiteral, | |
| 1755 | result_used: ResultUsed, | |
| 1756 | ) TransError!*ast.Node { | |
| 1757 | const kind = ZigClangCharacterLiteral_getKind(stmt); | |
| 1758 | switch (kind) { | |
| 1759 | .Ascii, .UTF8 => { | |
| 1760 | const val = ZigClangCharacterLiteral_getValue(stmt); | |
| 1761 | if (kind == .Ascii) { | |
| 1762 | // C has a somewhat obscure feature called multi-character character | |
| 1763 | // constant | |
| 1764 | if (val > 255) | |
| 1765 | return transCreateNodeInt(rp.c, val); | |
| 1766 | } | |
| 1767 | var char_buf: [4]u8 = undefined; | |
| 1768 | const token = try appendTokenFmt(rp.c, .CharLiteral, "'{}'", .{escapeChar(@intCast(u8, val), &char_buf)}); | |
| 1769 | const node = try rp.c.a().create(ast.Node.CharLiteral); | |
| 1770 | node.* = .{ | |
| 1771 | .token = token, | |
| 1772 | }; | |
| 1773 | return maybeSuppressResult(rp, scope, result_used, &node.base); | |
| 1774 | }, | |
| 1775 | .UTF16, .UTF32, .Wide => return revertAndWarn( | |
| 1776 | rp, | |
| 1777 | error.UnsupportedTranslation, | |
| 1778 | ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt)), | |
| 1779 | "TODO: support character literal kind {}", | |
| 1780 | .{kind}, | |
| 1781 | ), | |
| 1782 | else => unreachable, | |
| 1783 | } | |
| 1784 | } | |
| 1785 | ||
| 1756 | 1786 | fn transCPtrCast( |
| 1757 | 1787 | rp: RestorePoint, |
| 1758 | 1788 | loc: ZigClangSourceLocation, |
| ... | ... | @@ -1796,6 +1826,7 @@ fn transBreak(rp: RestorePoint, scope: *Scope) TransError!*ast.Node { |
| 1796 | 1826 | "__switch" |
| 1797 | 1827 | else |
| 1798 | 1828 | null); |
| 1829 | _ = try appendToken(rp.c, .Semicolon, ";"); | |
| 1799 | 1830 | return &br.base; |
| 1800 | 1831 | } |
| 1801 | 1832 | |
| ... | ... | @@ -1813,18 +1844,16 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla |
| 1813 | 1844 | const gropued = scope.id == .Condition; |
| 1814 | 1845 | const lparen = if (gropued) try appendToken(rp.c, .LParen, "(") else undefined; |
| 1815 | 1846 | const if_node = try transCreateNodeIf(rp.c); |
| 1816 | var cond_scope = Scope.Condition{ | |
| 1817 | .base = .{ | |
| 1818 | .parent = scope, | |
| 1819 | .id = .Condition, | |
| 1820 | }, | |
| 1847 | var cond_scope = Scope{ | |
| 1848 | .parent = scope, | |
| 1849 | .id = .Condition, | |
| 1821 | 1850 | }; |
| 1822 | 1851 | |
| 1823 | 1852 | const cond_expr = ZigClangConditionalOperator_getCond(stmt); |
| 1824 | 1853 | const true_expr = ZigClangConditionalOperator_getTrueExpr(stmt); |
| 1825 | 1854 | const false_expr = ZigClangConditionalOperator_getFalseExpr(stmt); |
| 1826 | 1855 | |
| 1827 | if_node.condition = try transBoolExpr(rp, &cond_scope.base, cond_expr, .used, .r_value, false); | |
| 1856 | if_node.condition = try transBoolExpr(rp, &cond_scope, cond_expr, .used, .r_value, false); | |
| 1828 | 1857 | _ = try appendToken(rp.c, .RParen, ")"); |
| 1829 | 1858 | |
| 1830 | 1859 | if_node.body = try transExpr(rp, scope, true_expr, .used, .r_value); |
| ... | ... | @@ -3104,7 +3133,7 @@ fn transPreprocessorEntities(c: *Context, unit: *ZigClangASTUnit) Error!void { |
| 3104 | 3133 | |
| 3105 | 3134 | var tok_it = tok_list.iterator(0); |
| 3106 | 3135 | const first_tok = tok_it.next().?; |
| 3107 | assert(first_tok.id == .Identifier and std.mem.eql(u8, first_tok.bytes, checked_name)); | |
| 3136 | assert(first_tok.id == .Identifier and std.mem.eql(u8, first_tok.bytes, name)); | |
| 3108 | 3137 | const next = tok_it.peek().?; |
| 3109 | 3138 | switch (next.id) { |
| 3110 | 3139 | .Identifier => { |
test/translate_c.zig+252-192| ... | ... | @@ -600,6 +600,135 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 600 | 600 | \\} |
| 601 | 601 | }); |
| 602 | 602 | |
| 603 | cases.add_both("simple union", | |
| 604 | \\union Foo { | |
| 605 | \\ int x; | |
| 606 | \\ double y; | |
| 607 | \\}; | |
| 608 | , &[_][]const u8{ | |
| 609 | \\pub const union_Foo = extern union { | |
| 610 | \\ x: c_int, | |
| 611 | \\ y: f64, | |
| 612 | \\}; | |
| 613 | , | |
| 614 | \\pub const Foo = union_Foo; | |
| 615 | }); | |
| 616 | ||
| 617 | cases.addC_both("string literal", | |
| 618 | \\const char *foo(void) { | |
| 619 | \\ return "bar"; | |
| 620 | \\} | |
| 621 | , &[_][]const u8{ | |
| 622 | \\pub export fn foo() [*c]const u8 { | |
| 623 | \\ return "bar"; | |
| 624 | \\} | |
| 625 | }); | |
| 626 | ||
| 627 | cases.addC_both("return void", | |
| 628 | \\void foo(void) { | |
| 629 | \\ return; | |
| 630 | \\} | |
| 631 | , &[_][]const u8{ | |
| 632 | \\pub export fn foo() void { | |
| 633 | \\ return; | |
| 634 | \\} | |
| 635 | }); | |
| 636 | ||
| 637 | cases.addC_both("for loop", | |
| 638 | \\void foo(void) { | |
| 639 | \\ for (int i = 0; i; i = i + 1) { } | |
| 640 | \\} | |
| 641 | , &[_][]const u8{ | |
| 642 | \\pub export fn foo() void { | |
| 643 | \\ { | |
| 644 | \\ var i: c_int = 0; | |
| 645 | \\ while (i != 0) : (i = (i + 1)) {} | |
| 646 | \\ } | |
| 647 | \\} | |
| 648 | }); | |
| 649 | ||
| 650 | cases.addC_both("empty for loop", | |
| 651 | \\void foo(void) { | |
| 652 | \\ for (;;) { } | |
| 653 | \\} | |
| 654 | , &[_][]const u8{ | |
| 655 | \\pub export fn foo() void { | |
| 656 | \\ while (true) {} | |
| 657 | \\} | |
| 658 | }); | |
| 659 | ||
| 660 | cases.addC_both("break statement", | |
| 661 | \\void foo(void) { | |
| 662 | \\ for (;;) { | |
| 663 | \\ break; | |
| 664 | \\ } | |
| 665 | \\} | |
| 666 | , &[_][]const u8{ | |
| 667 | \\pub export fn foo() void { | |
| 668 | \\ while (true) { | |
| 669 | \\ break; | |
| 670 | \\ } | |
| 671 | \\} | |
| 672 | }); | |
| 673 | ||
| 674 | cases.addC_both("continue statement", | |
| 675 | \\void foo(void) { | |
| 676 | \\ for (;;) { | |
| 677 | \\ continue; | |
| 678 | \\ } | |
| 679 | \\} | |
| 680 | , &[_][]const u8{ | |
| 681 | \\pub export fn foo() void { | |
| 682 | \\ while (true) { | |
| 683 | \\ continue; | |
| 684 | \\ } | |
| 685 | \\} | |
| 686 | }); | |
| 687 | ||
| 688 | cases.addC_both("pointer casting", | |
| 689 | \\float *ptrcast(int *a) { | |
| 690 | \\ return (float *)a; | |
| 691 | \\} | |
| 692 | , &[_][]const u8{ | |
| 693 | \\pub export fn ptrcast(a: [*c]c_int) [*c]f32 { | |
| 694 | \\ return @ptrCast([*c]f32, @alignCast(@alignOf(f32), a)); | |
| 695 | \\} | |
| 696 | }); | |
| 697 | ||
| 698 | cases.addC_both("pointer conversion with different alignment", | |
| 699 | \\void test_ptr_cast() { | |
| 700 | \\ void *p; | |
| 701 | \\ { | |
| 702 | \\ char *to_char = (char *)p; | |
| 703 | \\ short *to_short = (short *)p; | |
| 704 | \\ int *to_int = (int *)p; | |
| 705 | \\ long long *to_longlong = (long long *)p; | |
| 706 | \\ } | |
| 707 | \\ { | |
| 708 | \\ char *to_char = p; | |
| 709 | \\ short *to_short = p; | |
| 710 | \\ int *to_int = p; | |
| 711 | \\ long long *to_longlong = p; | |
| 712 | \\ } | |
| 713 | \\} | |
| 714 | , &[_][]const u8{ | |
| 715 | \\pub export fn test_ptr_cast() void { | |
| 716 | \\ var p: ?*c_void = undefined; | |
| 717 | \\ { | |
| 718 | \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@alignOf(u8), p)); | |
| 719 | \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@alignOf(c_short), p)); | |
| 720 | \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@alignOf(c_int), p)); | |
| 721 | \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@alignOf(c_longlong), p)); | |
| 722 | \\ } | |
| 723 | \\ { | |
| 724 | \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@alignOf(u8), p)); | |
| 725 | \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@alignOf(c_short), p)); | |
| 726 | \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@alignOf(c_int), p)); | |
| 727 | \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@alignOf(c_longlong), p)); | |
| 728 | \\ } | |
| 729 | \\} | |
| 730 | }); | |
| 731 | ||
| 603 | 732 | /////////////// Cases that pass for only stage2 //////////////// |
| 604 | 733 | |
| 605 | 734 | cases.add_2("Parameterless function prototypes", |
| ... | ... | @@ -957,11 +1086,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 957 | 1086 | \\ while (true) { |
| 958 | 1087 | \\ var a: c_int = 2; |
| 959 | 1088 | \\ a = 12; |
| 960 | \\ if (!4 != 0) break; | |
| 1089 | \\ if (!(4 != 0)) break; | |
| 961 | 1090 | \\ } |
| 962 | 1091 | \\ while (true) { |
| 963 | 1092 | \\ a = 7; |
| 964 | \\ if (!4 != 0) break; | |
| 1093 | \\ if (!(4 != 0)) break; | |
| 965 | 1094 | \\ } |
| 966 | 1095 | \\} |
| 967 | 1096 | }); |
| ... | ... | @@ -1145,6 +1274,66 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1145 | 1274 | \\} |
| 1146 | 1275 | }); |
| 1147 | 1276 | |
| 1277 | cases.add_2("escape sequences", | |
| 1278 | \\const char *escapes() { | |
| 1279 | \\char a = '\'', | |
| 1280 | \\ b = '\\', | |
| 1281 | \\ c = '\a', | |
| 1282 | \\ d = '\b', | |
| 1283 | \\ e = '\f', | |
| 1284 | \\ f = '\n', | |
| 1285 | \\ g = '\r', | |
| 1286 | \\ h = '\t', | |
| 1287 | \\ i = '\v', | |
| 1288 | \\ j = '\0', | |
| 1289 | \\ k = '\"'; | |
| 1290 | \\ return "\'\\\a\b\f\n\r\t\v\0\""; | |
| 1291 | \\} | |
| 1292 | \\ | |
| 1293 | , &[_][]const u8{ | |
| 1294 | \\pub export fn escapes() [*c]const u8 { | |
| 1295 | \\ var a: u8 = @as(u8, '\''); | |
| 1296 | \\ var b: u8 = @as(u8, '\\'); | |
| 1297 | \\ var c: u8 = @as(u8, '\x07'); | |
| 1298 | \\ var d: u8 = @as(u8, '\x08'); | |
| 1299 | \\ var e: u8 = @as(u8, '\x0c'); | |
| 1300 | \\ var f: u8 = @as(u8, '\n'); | |
| 1301 | \\ var g: u8 = @as(u8, '\r'); | |
| 1302 | \\ var h: u8 = @as(u8, '\t'); | |
| 1303 | \\ var i: u8 = @as(u8, '\x0b'); | |
| 1304 | \\ var j: u8 = @as(u8, '\x00'); | |
| 1305 | \\ var k: u8 = @as(u8, '\"'); | |
| 1306 | \\ return "\'\\\x07\x08\x0c\n\r\t\x0b\x00\""; | |
| 1307 | \\} | |
| 1308 | }); | |
| 1309 | ||
| 1310 | cases.add_2("do loop", | |
| 1311 | \\void foo(void) { | |
| 1312 | \\ int a = 2; | |
| 1313 | \\ do { | |
| 1314 | \\ a = a - 1; | |
| 1315 | \\ } while (a); | |
| 1316 | \\ | |
| 1317 | \\ int b = 2; | |
| 1318 | \\ do | |
| 1319 | \\ b = b -1; | |
| 1320 | \\ while (b); | |
| 1321 | \\} | |
| 1322 | , &[_][]const u8{ | |
| 1323 | \\pub export fn foo() void { | |
| 1324 | \\ var a: c_int = 2; | |
| 1325 | \\ while (true) { | |
| 1326 | \\ a = (a - 1); | |
| 1327 | \\ if (!(a != 0)) break; | |
| 1328 | \\ } | |
| 1329 | \\ var b: c_int = 2; | |
| 1330 | \\ while (true) { | |
| 1331 | \\ b = (b - 1); | |
| 1332 | \\ if (!(b != 0)) break; | |
| 1333 | \\ } | |
| 1334 | \\} | |
| 1335 | }); | |
| 1336 | ||
| 1148 | 1337 | /////////////// Cases for only stage1 which are TODO items for stage2 //////////////// |
| 1149 | 1338 | |
| 1150 | 1339 | cases.addAllowWarnings("simple data types", |
| ... | ... | @@ -1641,33 +1830,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1641 | 1830 | \\} |
| 1642 | 1831 | }); |
| 1643 | 1832 | |
| 1644 | cases.addC("do loop", | |
| 1645 | \\void foo(void) { | |
| 1646 | \\ int a = 2; | |
| 1647 | \\ do { | |
| 1648 | \\ a--; | |
| 1649 | \\ } while (a != 0); | |
| 1650 | \\ | |
| 1651 | \\ int b = 2; | |
| 1652 | \\ do | |
| 1653 | \\ b--; | |
| 1654 | \\ while (b != 0); | |
| 1655 | \\} | |
| 1656 | , &[_][]const u8{ | |
| 1657 | \\pub export fn foo() void { | |
| 1658 | \\ var a: c_int = 2; | |
| 1659 | \\ while (true) { | |
| 1660 | \\ a -= 1; | |
| 1661 | \\ if (!(a != 0)) break; | |
| 1662 | \\ } | |
| 1663 | \\ var b: c_int = 2; | |
| 1664 | \\ while (true) { | |
| 1665 | \\ b -= 1; | |
| 1666 | \\ if (!(b != 0)) break; | |
| 1667 | \\ } | |
| 1668 | \\} | |
| 1669 | }); | |
| 1670 | ||
| 1671 | 1833 | cases.addC("deref function pointer", |
| 1672 | 1834 | \\void foo(void) {} |
| 1673 | 1835 | \\int baz(void) { return 0; } |
| ... | ... | @@ -1708,20 +1870,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1708 | 1870 | \\} |
| 1709 | 1871 | }); |
| 1710 | 1872 | |
| 1711 | cases.add("simple union", | |
| 1712 | \\union Foo { | |
| 1713 | \\ int x; | |
| 1714 | \\ double y; | |
| 1715 | \\}; | |
| 1716 | , &[_][]const u8{ | |
| 1717 | \\pub const union_Foo = extern union { | |
| 1718 | \\ x: c_int, | |
| 1719 | \\ y: f64, | |
| 1720 | \\}; | |
| 1721 | , | |
| 1722 | \\pub const Foo = union_Foo; | |
| 1723 | }); | |
| 1724 | ||
| 1725 | 1873 | cases.add("address of operator", |
| 1726 | 1874 | \\int foo(void) { |
| 1727 | 1875 | \\ int x = 1234; |
| ... | ... | @@ -1736,77 +1884,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1736 | 1884 | \\} |
| 1737 | 1885 | }); |
| 1738 | 1886 | |
| 1739 | cases.add("string literal", | |
| 1740 | \\const char *foo(void) { | |
| 1741 | \\ return "bar"; | |
| 1742 | \\} | |
| 1743 | , &[_][]const u8{ | |
| 1744 | \\pub fn foo() [*c]const u8 { | |
| 1745 | \\ return "bar"; | |
| 1746 | \\} | |
| 1747 | }); | |
| 1748 | ||
| 1749 | cases.add("return void", | |
| 1750 | \\void foo(void) { | |
| 1751 | \\ return; | |
| 1752 | \\} | |
| 1753 | , &[_][]const u8{ | |
| 1754 | \\pub fn foo() void { | |
| 1755 | \\ return; | |
| 1756 | \\} | |
| 1757 | }); | |
| 1758 | ||
| 1759 | cases.add("for loop", | |
| 1760 | \\void foo(void) { | |
| 1761 | \\ for (int i = 0; i < 10; i += 1) { } | |
| 1762 | \\} | |
| 1763 | , &[_][]const u8{ | |
| 1764 | \\pub fn foo() void { | |
| 1765 | \\ { | |
| 1766 | \\ var i: c_int = 0; | |
| 1767 | \\ while (i < 10) : (i += 1) {} | |
| 1768 | \\ } | |
| 1769 | \\} | |
| 1770 | }); | |
| 1771 | ||
| 1772 | cases.add("empty for loop", | |
| 1773 | \\void foo(void) { | |
| 1774 | \\ for (;;) { } | |
| 1775 | \\} | |
| 1776 | , &[_][]const u8{ | |
| 1777 | \\pub fn foo() void { | |
| 1778 | \\ while (true) {} | |
| 1779 | \\} | |
| 1780 | }); | |
| 1781 | ||
| 1782 | cases.add("break statement", | |
| 1783 | \\void foo(void) { | |
| 1784 | \\ for (;;) { | |
| 1785 | \\ break; | |
| 1786 | \\ } | |
| 1787 | \\} | |
| 1788 | , &[_][]const u8{ | |
| 1789 | \\pub fn foo() void { | |
| 1790 | \\ while (true) { | |
| 1791 | \\ break; | |
| 1792 | \\ } | |
| 1793 | \\} | |
| 1794 | }); | |
| 1795 | ||
| 1796 | cases.add("continue statement", | |
| 1797 | \\void foo(void) { | |
| 1798 | \\ for (;;) { | |
| 1799 | \\ continue; | |
| 1800 | \\ } | |
| 1801 | \\} | |
| 1802 | , &[_][]const u8{ | |
| 1803 | \\pub fn foo() void { | |
| 1804 | \\ while (true) { | |
| 1805 | \\ continue; | |
| 1806 | \\ } | |
| 1807 | \\} | |
| 1808 | }); | |
| 1809 | ||
| 1810 | 1887 | cases.add("variable name shadowing", |
| 1811 | 1888 | \\int foo(void) { |
| 1812 | 1889 | \\ int x = 1; |
| ... | ... | @@ -1827,16 +1904,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1827 | 1904 | \\} |
| 1828 | 1905 | }); |
| 1829 | 1906 | |
| 1830 | cases.add("pointer casting", | |
| 1831 | \\float *ptrcast(int *a) { | |
| 1832 | \\ return (float *)a; | |
| 1833 | \\} | |
| 1834 | , &[_][]const u8{ | |
| 1835 | \\fn ptrcast(a: [*c]c_int) [*c]f32 { | |
| 1836 | \\ return @ptrCast([*c]f32, @alignCast(@alignOf(f32), a)); | |
| 1837 | \\} | |
| 1838 | }); | |
| 1839 | ||
| 1840 | 1907 | cases.add("bin not", |
| 1841 | 1908 | \\int foo(int x) { |
| 1842 | 1909 | \\ return ~x; |
| ... | ... | @@ -1987,74 +2054,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1987 | 2054 | \\} |
| 1988 | 2055 | }); |
| 1989 | 2056 | |
| 1990 | cases.addC("pointer conversion with different alignment", | |
| 1991 | \\void test_ptr_cast() { | |
| 1992 | \\ void *p; | |
| 1993 | \\ { | |
| 1994 | \\ char *to_char = (char *)p; | |
| 1995 | \\ short *to_short = (short *)p; | |
| 1996 | \\ int *to_int = (int *)p; | |
| 1997 | \\ long long *to_longlong = (long long *)p; | |
| 1998 | \\ } | |
| 1999 | \\ { | |
| 2000 | \\ char *to_char = p; | |
| 2001 | \\ short *to_short = p; | |
| 2002 | \\ int *to_int = p; | |
| 2003 | \\ long long *to_longlong = p; | |
| 2004 | \\ } | |
| 2005 | \\} | |
| 2006 | , &[_][]const u8{ | |
| 2007 | \\pub export fn test_ptr_cast() void { | |
| 2008 | \\ var p: ?*c_void = undefined; | |
| 2009 | \\ { | |
| 2010 | \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@alignOf(u8), p)); | |
| 2011 | \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@alignOf(c_short), p)); | |
| 2012 | \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@alignOf(c_int), p)); | |
| 2013 | \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@alignOf(c_longlong), p)); | |
| 2014 | \\ } | |
| 2015 | \\ { | |
| 2016 | \\ var to_char: [*c]u8 = @ptrCast([*c]u8, @alignCast(@alignOf(u8), p)); | |
| 2017 | \\ var to_short: [*c]c_short = @ptrCast([*c]c_short, @alignCast(@alignOf(c_short), p)); | |
| 2018 | \\ var to_int: [*c]c_int = @ptrCast([*c]c_int, @alignCast(@alignOf(c_int), p)); | |
| 2019 | \\ var to_longlong: [*c]c_longlong = @ptrCast([*c]c_longlong, @alignCast(@alignOf(c_longlong), p)); | |
| 2020 | \\ } | |
| 2021 | \\} | |
| 2022 | }); | |
| 2023 | ||
| 2024 | cases.addC("escape sequences", | |
| 2025 | \\const char *escapes() { | |
| 2026 | \\char a = '\'', | |
| 2027 | \\ b = '\\', | |
| 2028 | \\ c = '\a', | |
| 2029 | \\ d = '\b', | |
| 2030 | \\ e = '\f', | |
| 2031 | \\ f = '\n', | |
| 2032 | \\ g = '\r', | |
| 2033 | \\ h = '\t', | |
| 2034 | \\ i = '\v', | |
| 2035 | \\ j = '\0', | |
| 2036 | \\ k = '\"'; | |
| 2037 | \\ return "\'\\\a\b\f\n\r\t\v\0\""; | |
| 2038 | \\} | |
| 2039 | \\ | |
| 2040 | , &[_][]const u8{ | |
| 2041 | \\pub export fn escapes() [*c]const u8 { | |
| 2042 | \\ var a: u8 = @as(u8, '\''); | |
| 2043 | \\ var b: u8 = @as(u8, '\\'); | |
| 2044 | \\ var c: u8 = @as(u8, '\x07'); | |
| 2045 | \\ var d: u8 = @as(u8, '\x08'); | |
| 2046 | \\ var e: u8 = @as(u8, '\x0c'); | |
| 2047 | \\ var f: u8 = @as(u8, '\n'); | |
| 2048 | \\ var g: u8 = @as(u8, '\r'); | |
| 2049 | \\ var h: u8 = @as(u8, '\t'); | |
| 2050 | \\ var i: u8 = @as(u8, '\x0b'); | |
| 2051 | \\ var j: u8 = @as(u8, '\x00'); | |
| 2052 | \\ var k: u8 = @as(u8, '\"'); | |
| 2053 | \\ return "\'\\\x07\x08\x0c\n\r\t\x0b\x00\""; | |
| 2054 | \\} | |
| 2055 | \\ | |
| 2056 | }); | |
| 2057 | ||
| 2058 | 2057 | if (builtin.os != builtin.Os.windows) { |
| 2059 | 2058 | // sysv_abi not currently supported on windows |
| 2060 | 2059 | cases.add("Macro qualified functions", |
| ... | ... | @@ -2386,4 +2385,65 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2386 | 2385 | \\ }; |
| 2387 | 2386 | \\} |
| 2388 | 2387 | }); |
| 2388 | ||
| 2389 | cases.addC("escape sequences", | |
| 2390 | \\const char *escapes() { | |
| 2391 | \\char a = '\'', | |
| 2392 | \\ b = '\\', | |
| 2393 | \\ c = '\a', | |
| 2394 | \\ d = '\b', | |
| 2395 | \\ e = '\f', | |
| 2396 | \\ f = '\n', | |
| 2397 | \\ g = '\r', | |
| 2398 | \\ h = '\t', | |
| 2399 | \\ i = '\v', | |
| 2400 | \\ j = '\0', | |
| 2401 | \\ k = '\"'; | |
| 2402 | \\ return "\'\\\a\b\f\n\r\t\v\0\""; | |
| 2403 | \\} | |
| 2404 | \\ | |
| 2405 | , &[_][]const u8{ | |
| 2406 | \\pub export fn escapes() [*c]const u8 { | |
| 2407 | \\ var a: u8 = @as(u8, '\''); | |
| 2408 | \\ var b: u8 = @as(u8, '\\'); | |
| 2409 | \\ var c: u8 = @as(u8, '\x07'); | |
| 2410 | \\ var d: u8 = @as(u8, '\x08'); | |
| 2411 | \\ var e: u8 = @as(u8, '\x0c'); | |
| 2412 | \\ var f: u8 = @as(u8, '\n'); | |
| 2413 | \\ var g: u8 = @as(u8, '\r'); | |
| 2414 | \\ var h: u8 = @as(u8, '\t'); | |
| 2415 | \\ var i: u8 = @as(u8, '\x0b'); | |
| 2416 | \\ var j: u8 = @as(u8, '\x00'); | |
| 2417 | \\ var k: u8 = @as(u8, '\"'); | |
| 2418 | \\ return "\'\\\x07\x08\x0c\n\r\t\x0b\x00\""; | |
| 2419 | \\} | |
| 2420 | \\ | |
| 2421 | }); | |
| 2422 | ||
| 2423 | cases.addC("do loop", | |
| 2424 | \\void foo(void) { | |
| 2425 | \\ int a = 2; | |
| 2426 | \\ do { | |
| 2427 | \\ a--; | |
| 2428 | \\ } while (a != 0); | |
| 2429 | \\ | |
| 2430 | \\ int b = 2; | |
| 2431 | \\ do | |
| 2432 | \\ b--; | |
| 2433 | \\ while (b != 0); | |
| 2434 | \\} | |
| 2435 | , &[_][]const u8{ | |
| 2436 | \\pub export fn foo() void { | |
| 2437 | \\ var a: c_int = 2; | |
| 2438 | \\ while (true) { | |
| 2439 | \\ a -= 1; | |
| 2440 | \\ if (!(a != 0)) break; | |
| 2441 | \\ } | |
| 2442 | \\ var b: c_int = 2; | |
| 2443 | \\ while (true) { | |
| 2444 | \\ b -= 1; | |
| 2445 | \\ if (!(b != 0)) break; | |
| 2446 | \\ } | |
| 2447 | \\} | |
| 2448 | }); | |
| 2389 | 2449 | } |