| author | |
| committer | |
| log | 5b34697b21ec88f85d338144ef1f9afb6be2b25a |
| tree | ae977486b01bc5f1fd537be59a91ba92babe0d71 |
| parent | fd7e69a2c0895f08fe3b8a75fb142250678d5e1f |
3 files changed, 45 insertions(+), 4 deletions(-)
src-self-hosted/translate_c.zig+23-1| ... | ... | @@ -2419,7 +2419,29 @@ fn transConstantExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangExpr, |
| 2419 | 2419 | var result: ZigClangExprEvalResult = undefined; |
| 2420 | 2420 | if (!ZigClangExpr_EvaluateAsConstantExpr(expr, &result, .EvaluateForCodeGen, rp.c.clang_context)) |
| 2421 | 2421 | return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangExpr_getBeginLoc(expr), "invalid constant expression", .{}); |
| 2422 | return maybeSuppressResult(rp, scope, used, try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val))); | |
| 2422 | ||
| 2423 | var val_node: ?*ast.Node = null; | |
| 2424 | switch (ZigClangAPValue_getKind(&result.Val)) { | |
| 2425 | .Int => { | |
| 2426 | // See comment in `transIntegerLiteral` for why this code is here. | |
| 2427 | // @as(T, x) | |
| 2428 | const expr_base = @ptrCast(*const ZigClangExpr, expr); | |
| 2429 | const as_node = try transCreateNodeBuiltinFnCall(rp.c, "@as"); | |
| 2430 | const ty_node = try transQualType(rp, ZigClangExpr_getType(expr_base), ZigClangExpr_getBeginLoc(expr_base)); | |
| 2431 | try as_node.params.push(ty_node); | |
| 2432 | _ = try appendToken(rp.c, .Comma, ","); | |
| 2433 | ||
| 2434 | const int_lit_node = try transCreateNodeAPInt(rp.c, ZigClangAPValue_getInt(&result.Val)); | |
| 2435 | try as_node.params.push(int_lit_node); | |
| 2436 | ||
| 2437 | as_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | |
| 2438 | ||
| 2439 | return maybeSuppressResult(rp, scope, used, &as_node.base); | |
| 2440 | }, | |
| 2441 | else => { | |
| 2442 | return revertAndWarn(rp, error.UnsupportedTranslation, ZigClangExpr_getBeginLoc(expr), "unsupported constant expression kind", .{}); | |
| 2443 | }, | |
| 2444 | } | |
| 2423 | 2445 | } |
| 2424 | 2446 | |
| 2425 | 2447 | fn transPredefinedExpr(rp: RestorePoint, scope: *Scope, expr: *const ZigClangPredefinedExpr, used: ResultUsed) TransError!*ast.Node { |
test/run_translated_c.zig+19| ... | ... | @@ -20,6 +20,25 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 20 | 20 | \\} |
| 21 | 21 | , ""); |
| 22 | 22 | |
| 23 | cases.add("switch case", | |
| 24 | \\#include <stdlib.h> | |
| 25 | \\int lottery(unsigned int x) { | |
| 26 | \\ switch (x) { | |
| 27 | \\ case 3: return 0; | |
| 28 | \\ case -1: return 3; | |
| 29 | \\ case 8 ... 10: return x; | |
| 30 | \\ default: return -1; | |
| 31 | \\ } | |
| 32 | \\} | |
| 33 | \\int main(int argc, char **argv) { | |
| 34 | \\ if (lottery(2) != -1) abort(); | |
| 35 | \\ if (lottery(3) != 0) abort(); | |
| 36 | \\ if (lottery(-1) != 3) abort(); | |
| 37 | \\ if (lottery(9) != 9) abort(); | |
| 38 | \\ return 0; | |
| 39 | \\} | |
| 40 | , ""); | |
| 41 | ||
| 23 | 42 | cases.add("boolean values and expressions", |
| 24 | 43 | \\#include <stdlib.h> |
| 25 | 44 | \\static const _Bool false_val = 0; |
test/translate_c.zig+3-3| ... | ... | @@ -1468,10 +1468,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1468 | 1468 | \\ __case_1: { |
| 1469 | 1469 | \\ __case_0: { |
| 1470 | 1470 | \\ switch (i) { |
| 1471 | \\ 0 => break :__case_0, | |
| 1472 | \\ 1...3 => break :__case_1, | |
| 1471 | \\ @as(c_int, 0) => break :__case_0, | |
| 1472 | \\ @as(c_int, 1)...@as(c_int, 3) => break :__case_1, | |
| 1473 | 1473 | \\ else => break :__default, |
| 1474 | \\ 4 => break :__case_2, | |
| 1474 | \\ @as(c_int, 4) => break :__case_2, | |
| 1475 | 1475 | \\ } |
| 1476 | 1476 | \\ } |
| 1477 | 1477 | \\ res = 1; |