| author | |
| committer | |
| log | fd7e69a2c0895f08fe3b8a75fb142250678d5e1f |
| tree | bc0ce710b53042a0ae068202ddd0bbe8717c2200 |
| parent | 2a5c622e65a07db95859beabf46f36d3a62c785a |
* Translate OpaqueValueExpr
* Translate BinaryConditionalOperator
* Fix translation of boolean->int casts
* Reoder some tokens to avoid rendering errors6 files changed, 185 insertions(+), 48 deletions(-)
src-self-hosted/clang.zig+13-5| ... | @@ -1,5 +1,8 @@ | ... | @@ -1,5 +1,8 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | 2 | ||
| 3 | pub const struct_ZigClangConditionalOperator = @OpaqueType(); | ||
| 4 | pub const struct_ZigClangBinaryConditionalOperator = @OpaqueType(); | ||
| 5 | pub const struct_ZigClangAbstractConditionalOperator = @OpaqueType(); | ||
| 3 | pub const struct_ZigClangAPInt = @OpaqueType(); | 6 | pub const struct_ZigClangAPInt = @OpaqueType(); |
| 4 | pub const struct_ZigClangAPSInt = @OpaqueType(); | 7 | pub const struct_ZigClangAPSInt = @OpaqueType(); |
| 5 | pub const struct_ZigClangAPFloat = @OpaqueType(); | 8 | pub const struct_ZigClangAPFloat = @OpaqueType(); |
| ... | @@ -16,7 +19,6 @@ pub const struct_ZigClangCallExpr = @OpaqueType(); | ... | @@ -16,7 +19,6 @@ pub const struct_ZigClangCallExpr = @OpaqueType(); |
| 16 | pub const struct_ZigClangCaseStmt = @OpaqueType(); | 19 | pub const struct_ZigClangCaseStmt = @OpaqueType(); |
| 17 | pub const struct_ZigClangCompoundAssignOperator = @OpaqueType(); | 20 | pub const struct_ZigClangCompoundAssignOperator = @OpaqueType(); |
| 18 | pub const struct_ZigClangCompoundStmt = @OpaqueType(); | 21 | pub const struct_ZigClangCompoundStmt = @OpaqueType(); |
| 19 | pub const struct_ZigClangConditionalOperator = @OpaqueType(); | ||
| 20 | pub const struct_ZigClangConstantArrayType = @OpaqueType(); | 22 | pub const struct_ZigClangConstantArrayType = @OpaqueType(); |
| 21 | pub const struct_ZigClangContinueStmt = @OpaqueType(); | 23 | pub const struct_ZigClangContinueStmt = @OpaqueType(); |
| 22 | pub const struct_ZigClangDecayedType = @OpaqueType(); | 24 | pub const struct_ZigClangDecayedType = @OpaqueType(); |
| ... | @@ -48,6 +50,7 @@ pub const struct_ZigClangMacroQualifiedType = @OpaqueType(); | ... | @@ -48,6 +50,7 @@ pub const struct_ZigClangMacroQualifiedType = @OpaqueType(); |
| 48 | pub const struct_ZigClangMemberExpr = @OpaqueType(); | 50 | pub const struct_ZigClangMemberExpr = @OpaqueType(); |
| 49 | pub const struct_ZigClangNamedDecl = @OpaqueType(); | 51 | pub const struct_ZigClangNamedDecl = @OpaqueType(); |
| 50 | pub const struct_ZigClangNone = @OpaqueType(); | 52 | pub const struct_ZigClangNone = @OpaqueType(); |
| 53 | pub const struct_ZigClangOpaqueValueExpr = @OpaqueType(); | ||
| 51 | pub const struct_ZigClangPCHContainerOperations = @OpaqueType(); | 54 | pub const struct_ZigClangPCHContainerOperations = @OpaqueType(); |
| 52 | pub const struct_ZigClangParenExpr = @OpaqueType(); | 55 | pub const struct_ZigClangParenExpr = @OpaqueType(); |
| 53 | pub const struct_ZigClangParenType = @OpaqueType(); | 56 | pub const struct_ZigClangParenType = @OpaqueType(); |
| ... | @@ -860,6 +863,9 @@ pub extern fn ZigClangFunctionProtoType_getReturnType(self: *const ZigClangFunct | ... | @@ -860,6 +863,9 @@ pub extern fn ZigClangFunctionProtoType_getReturnType(self: *const ZigClangFunct |
| 860 | 863 | ||
| 861 | pub const ZigClangSourceLocation = struct_ZigClangSourceLocation; | 864 | pub const ZigClangSourceLocation = struct_ZigClangSourceLocation; |
| 862 | pub const ZigClangQualType = struct_ZigClangQualType; | 865 | pub const ZigClangQualType = struct_ZigClangQualType; |
| 866 | pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator; | ||
| 867 | pub const ZigClangBinaryConditionalOperator = struct_ZigClangBinaryConditionalOperator; | ||
| 868 | pub const ZigClangAbstractConditionalOperator = struct_ZigClangAbstractConditionalOperator; | ||
| 863 | pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase; | 869 | pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase; |
| 864 | pub const ZigClangAPValue = struct_ZigClangAPValue; | 870 | pub const ZigClangAPValue = struct_ZigClangAPValue; |
| 865 | pub const ZigClangAPSInt = struct_ZigClangAPSInt; | 871 | pub const ZigClangAPSInt = struct_ZigClangAPSInt; |
| ... | @@ -877,7 +883,6 @@ pub const ZigClangCallExpr = struct_ZigClangCallExpr; | ... | @@ -877,7 +883,6 @@ pub const ZigClangCallExpr = struct_ZigClangCallExpr; |
| 877 | pub const ZigClangCaseStmt = struct_ZigClangCaseStmt; | 883 | pub const ZigClangCaseStmt = struct_ZigClangCaseStmt; |
| 878 | pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator; | 884 | pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator; |
| 879 | pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt; | 885 | pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt; |
| 880 | pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator; | ||
| 881 | pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType; | 886 | pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType; |
| 882 | pub const ZigClangContinueStmt = struct_ZigClangContinueStmt; | 887 | pub const ZigClangContinueStmt = struct_ZigClangContinueStmt; |
| 883 | pub const ZigClangDecayedType = struct_ZigClangDecayedType; | 888 | pub const ZigClangDecayedType = struct_ZigClangDecayedType; |
| ... | @@ -909,6 +914,7 @@ pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType; | ... | @@ -909,6 +914,7 @@ pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType; |
| 909 | pub const ZigClangMemberExpr = struct_ZigClangMemberExpr; | 914 | pub const ZigClangMemberExpr = struct_ZigClangMemberExpr; |
| 910 | pub const ZigClangNamedDecl = struct_ZigClangNamedDecl; | 915 | pub const ZigClangNamedDecl = struct_ZigClangNamedDecl; |
| 911 | pub const ZigClangNone = struct_ZigClangNone; | 916 | pub const ZigClangNone = struct_ZigClangNone; |
| 917 | pub const ZigClangOpaqueValueExpr = struct_ZigClangOpaqueValueExpr; | ||
| 912 | pub const ZigClangPCHContainerOperations = struct_ZigClangPCHContainerOperations; | 918 | pub const ZigClangPCHContainerOperations = struct_ZigClangPCHContainerOperations; |
| 913 | pub const ZigClangParenExpr = struct_ZigClangParenExpr; | 919 | pub const ZigClangParenExpr = struct_ZigClangParenExpr; |
| 914 | pub const ZigClangParenType = struct_ZigClangParenType; | 920 | pub const ZigClangParenType = struct_ZigClangParenType; |
| ... | @@ -1095,9 +1101,9 @@ pub extern fn ZigClangForStmt_getBody(*const ZigClangForStmt) *const ZigClangStm | ... | @@ -1095,9 +1101,9 @@ pub extern fn ZigClangForStmt_getBody(*const ZigClangForStmt) *const ZigClangStm |
| 1095 | pub extern fn ZigClangAPFloat_toString(self: *const ZigClangAPFloat, precision: c_uint, maxPadding: c_uint, truncateZero: bool) [*:0]const u8; | 1101 | pub extern fn ZigClangAPFloat_toString(self: *const ZigClangAPFloat, precision: c_uint, maxPadding: c_uint, truncateZero: bool) [*:0]const u8; |
| 1096 | pub extern fn ZigClangAPFloat_getValueAsApproximateDouble(*const ZigClangFloatingLiteral) f64; | 1102 | pub extern fn ZigClangAPFloat_getValueAsApproximateDouble(*const ZigClangFloatingLiteral) f64; |
| 1097 | 1103 | ||
| 1098 | pub extern fn ZigClangConditionalOperator_getCond(*const ZigClangConditionalOperator) *const ZigClangExpr; | 1104 | pub extern fn ZigClangAbstractConditionalOperator_getCond(*const ZigClangAbstractConditionalOperator) *const ZigClangExpr; |
| 1099 | pub extern fn ZigClangConditionalOperator_getTrueExpr(*const ZigClangConditionalOperator) *const ZigClangExpr; | 1105 | pub extern fn ZigClangAbstractConditionalOperator_getTrueExpr(*const ZigClangAbstractConditionalOperator) *const ZigClangExpr; |
| 1100 | pub extern fn ZigClangConditionalOperator_getFalseExpr(*const ZigClangConditionalOperator) *const ZigClangExpr; | 1106 | pub extern fn ZigClangAbstractConditionalOperator_getFalseExpr(*const ZigClangAbstractConditionalOperator) *const ZigClangExpr; |
| 1101 | 1107 | ||
| 1102 | pub extern fn ZigClangSwitchStmt_getConditionVariableDeclStmt(*const ZigClangSwitchStmt) ?*const ZigClangDeclStmt; | 1108 | pub extern fn ZigClangSwitchStmt_getConditionVariableDeclStmt(*const ZigClangSwitchStmt) ?*const ZigClangDeclStmt; |
| 1103 | pub extern fn ZigClangSwitchStmt_getCond(*const ZigClangSwitchStmt) *const ZigClangExpr; | 1109 | pub extern fn ZigClangSwitchStmt_getCond(*const ZigClangSwitchStmt) *const ZigClangExpr; |
| ... | @@ -1140,6 +1146,8 @@ pub extern fn ZigClangUnaryOperator_getType(*const ZigClangUnaryOperator) ZigCla | ... | @@ -1140,6 +1146,8 @@ pub extern fn ZigClangUnaryOperator_getType(*const ZigClangUnaryOperator) ZigCla |
| 1140 | pub extern fn ZigClangUnaryOperator_getSubExpr(*const ZigClangUnaryOperator) *const ZigClangExpr; | 1146 | pub extern fn ZigClangUnaryOperator_getSubExpr(*const ZigClangUnaryOperator) *const ZigClangExpr; |
| 1141 | pub extern fn ZigClangUnaryOperator_getBeginLoc(*const ZigClangUnaryOperator) ZigClangSourceLocation; | 1147 | pub extern fn ZigClangUnaryOperator_getBeginLoc(*const ZigClangUnaryOperator) ZigClangSourceLocation; |
| 1142 | 1148 | ||
| 1149 | pub extern fn ZigClangOpaqueValueExpr_getSourceExpr(*const ZigClangOpaqueValueExpr) ?*const ZigClangExpr; | ||
| 1150 | |||
| 1143 | pub extern fn ZigClangCompoundAssignOperator_getType(*const ZigClangCompoundAssignOperator) ZigClangQualType; | 1151 | pub extern fn ZigClangCompoundAssignOperator_getType(*const ZigClangCompoundAssignOperator) ZigClangQualType; |
| 1144 | pub extern fn ZigClangCompoundAssignOperator_getComputationLHSType(*const ZigClangCompoundAssignOperator) ZigClangQualType; | 1152 | pub extern fn ZigClangCompoundAssignOperator_getComputationLHSType(*const ZigClangCompoundAssignOperator) ZigClangQualType; |
| 1145 | pub extern fn ZigClangCompoundAssignOperator_getComputationResultType(*const ZigClangCompoundAssignOperator) ZigClangQualType; | 1153 | pub extern fn ZigClangCompoundAssignOperator_getComputationResultType(*const ZigClangCompoundAssignOperator) ZigClangQualType; |
src-self-hosted/translate_c.zig+134-31| ... | @@ -363,7 +363,7 @@ fn prepopulateGlobalNameTable(ast_unit: *ZigClangASTUnit, c: *Context) !void { | ... | @@ -363,7 +363,7 @@ fn prepopulateGlobalNameTable(ast_unit: *ZigClangASTUnit, c: *Context) !void { |
| 363 | } | 363 | } |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | extern fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) bool { | 366 | fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) callconv(.C) bool { |
| 367 | const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context)); | 367 | const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context)); |
| 368 | declVisitorNamesOnly(c, decl) catch |err| { | 368 | declVisitorNamesOnly(c, decl) catch |err| { |
| 369 | c.err = err; | 369 | c.err = err; |
| ... | @@ -372,7 +372,7 @@ extern fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) bo | ... | @@ -372,7 +372,7 @@ extern fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) bo |
| 372 | return true; | 372 | return true; |
| 373 | } | 373 | } |
| 374 | 374 | ||
| 375 | extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool { | 375 | fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) callconv(.C) bool { |
| 376 | const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context)); | 376 | const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context)); |
| 377 | declVisitor(c, decl) catch |err| { | 377 | declVisitor(c, decl) catch |err| { |
| 378 | c.err = err; | 378 | c.err = err; |
| ... | @@ -1010,7 +1010,12 @@ fn transStmt( | ... | @@ -1010,7 +1010,12 @@ fn transStmt( |
| 1010 | .BreakStmtClass => return transBreak(rp, scope), | 1010 | .BreakStmtClass => return transBreak(rp, scope), |
| 1011 | .ForStmtClass => return transForLoop(rp, scope, @ptrCast(*const ZigClangForStmt, stmt)), | 1011 | .ForStmtClass => return transForLoop(rp, scope, @ptrCast(*const ZigClangForStmt, stmt)), |
| 1012 | .FloatingLiteralClass => return transFloatingLiteral(rp, scope, @ptrCast(*const ZigClangFloatingLiteral, stmt), result_used), | 1012 | .FloatingLiteralClass => return transFloatingLiteral(rp, scope, @ptrCast(*const ZigClangFloatingLiteral, stmt), result_used), |
| 1013 | .ConditionalOperatorClass => return transConditionalOperator(rp, scope, @ptrCast(*const ZigClangConditionalOperator, stmt), result_used), | 1013 | .ConditionalOperatorClass => { |
| 1014 | return transConditionalOperator(rp, scope, @ptrCast(*const ZigClangConditionalOperator, stmt), result_used); | ||
| 1015 | }, | ||
| 1016 | .BinaryConditionalOperatorClass => { | ||
| 1017 | return transBinaryConditionalOperator(rp, scope, @ptrCast(*const ZigClangBinaryConditionalOperator, stmt), result_used); | ||
| 1018 | }, | ||
| 1014 | .SwitchStmtClass => return transSwitch(rp, scope, @ptrCast(*const ZigClangSwitchStmt, stmt)), | 1019 | .SwitchStmtClass => return transSwitch(rp, scope, @ptrCast(*const ZigClangSwitchStmt, stmt)), |
| 1015 | .CaseStmtClass => return transCase(rp, scope, @ptrCast(*const ZigClangCaseStmt, stmt)), | 1020 | .CaseStmtClass => return transCase(rp, scope, @ptrCast(*const ZigClangCaseStmt, stmt)), |
| 1016 | .DefaultStmtClass => return transDefault(rp, scope, @ptrCast(*const ZigClangDefaultStmt, stmt)), | 1021 | .DefaultStmtClass => return transDefault(rp, scope, @ptrCast(*const ZigClangDefaultStmt, stmt)), |
| ... | @@ -1024,6 +1029,18 @@ fn transStmt( | ... | @@ -1024,6 +1029,18 @@ fn transStmt( |
| 1024 | .UnaryExprOrTypeTraitExprClass => return transUnaryExprOrTypeTraitExpr(rp, scope, @ptrCast(*const ZigClangUnaryExprOrTypeTraitExpr, stmt), result_used), | 1029 | .UnaryExprOrTypeTraitExprClass => return transUnaryExprOrTypeTraitExpr(rp, scope, @ptrCast(*const ZigClangUnaryExprOrTypeTraitExpr, stmt), result_used), |
| 1025 | .UnaryOperatorClass => return transUnaryOperator(rp, scope, @ptrCast(*const ZigClangUnaryOperator, stmt), result_used), | 1030 | .UnaryOperatorClass => return transUnaryOperator(rp, scope, @ptrCast(*const ZigClangUnaryOperator, stmt), result_used), |
| 1026 | .CompoundAssignOperatorClass => return transCompoundAssignOperator(rp, scope, @ptrCast(*const ZigClangCompoundAssignOperator, stmt), result_used), | 1031 | .CompoundAssignOperatorClass => return transCompoundAssignOperator(rp, scope, @ptrCast(*const ZigClangCompoundAssignOperator, stmt), result_used), |
| 1032 | .OpaqueValueExprClass => { | ||
| 1033 | const source_expr = ZigClangOpaqueValueExpr_getSourceExpr(@ptrCast(*const ZigClangOpaqueValueExpr, stmt)).?; | ||
| 1034 | const expr = try transExpr(rp, scope, source_expr, .used, lrvalue); | ||
| 1035 | if (expr.id == .GroupedExpression) return maybeSuppressResult(rp, scope, result_used, expr); | ||
| 1036 | const node = try rp.c.a().create(ast.Node.GroupedExpression); | ||
| 1037 | node.* = .{ | ||
| 1038 | .lparen = try appendToken(rp.c, .LParen, "("), | ||
| 1039 | .expr = expr, | ||
| 1040 | .rparen = try appendToken(rp.c, .RParen, ")"), | ||
| 1041 | }; | ||
| 1042 | return maybeSuppressResult(rp, scope, result_used, &node.base); | ||
| 1043 | }, | ||
| 1027 | else => { | 1044 | else => { |
| 1028 | return revertAndWarn( | 1045 | return revertAndWarn( |
| 1029 | rp, | 1046 | rp, |
| ... | @@ -1330,28 +1347,27 @@ fn transImplicitCastExpr( | ... | @@ -1330,28 +1347,27 @@ fn transImplicitCastExpr( |
| 1330 | ) TransError!*ast.Node { | 1347 | ) TransError!*ast.Node { |
| 1331 | const c = rp.c; | 1348 | const c = rp.c; |
| 1332 | const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr); | 1349 | const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr); |
| 1333 | const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value); | ||
| 1334 | const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr)); | 1350 | const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr)); |
| 1335 | const src_type = getExprQualType(c, sub_expr); | 1351 | const src_type = getExprQualType(c, sub_expr); |
| 1336 | switch (ZigClangImplicitCastExpr_getCastKind(expr)) { | 1352 | switch (ZigClangImplicitCastExpr_getCastKind(expr)) { |
| 1337 | .BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast, .PointerToIntegral, .IntegralToPointer => { | 1353 | .BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast, .PointerToIntegral, .IntegralToPointer => { |
| 1354 | const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value); | ||
| 1338 | return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node); | 1355 | return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node); |
| 1339 | }, | 1356 | }, |
| 1340 | .LValueToRValue, .NoOp, .FunctionToPointerDecay => { | 1357 | .LValueToRValue, .NoOp, .FunctionToPointerDecay => { |
| 1358 | const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value); | ||
| 1341 | return maybeSuppressResult(rp, scope, result_used, sub_expr_node); | 1359 | return maybeSuppressResult(rp, scope, result_used, sub_expr_node); |
| 1342 | }, | 1360 | }, |
| 1343 | .ArrayToPointerDecay => { | 1361 | .ArrayToPointerDecay => { |
| 1344 | switch (ZigClangExpr_getStmtClass(sub_expr)) { | 1362 | if (exprIsStringLiteral(sub_expr)) { |
| 1345 | .StringLiteralClass, .PredefinedExprClass => { | 1363 | const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value); |
| 1346 | return maybeSuppressResult(rp, scope, result_used, sub_expr_node); | 1364 | return maybeSuppressResult(rp, scope, result_used, sub_expr_node); |
| 1347 | }, | ||
| 1348 | else => { | ||
| 1349 | const prefix_op = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&"); | ||
| 1350 | prefix_op.rhs = sub_expr_node; | ||
| 1351 | |||
| 1352 | return maybeSuppressResult(rp, scope, result_used, &prefix_op.base); | ||
| 1353 | }, | ||
| 1354 | } | 1365 | } |
| 1366 | |||
| 1367 | const prefix_op = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&"); | ||
| 1368 | prefix_op.rhs = try transExpr(rp, scope, sub_expr, .used, .r_value); | ||
| 1369 | |||
| 1370 | return maybeSuppressResult(rp, scope, result_used, &prefix_op.base); | ||
| 1355 | }, | 1371 | }, |
| 1356 | .NullToPointer => { | 1372 | .NullToPointer => { |
| 1357 | return try transCreateNodeNullLiteral(rp.c); | 1373 | return try transCreateNodeNullLiteral(rp.c); |
| ... | @@ -1367,16 +1383,16 @@ fn transImplicitCastExpr( | ... | @@ -1367,16 +1383,16 @@ fn transImplicitCastExpr( |
| 1367 | return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false); | 1383 | return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false); |
| 1368 | }, | 1384 | }, |
| 1369 | .IntegralToBoolean => { | 1385 | .IntegralToBoolean => { |
| 1370 | const node = try transExpr(rp, scope, sub_expr, .used, .r_value); | 1386 | const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value); |
| 1371 | 1387 | ||
| 1372 | // The expression is already a boolean one, return it as-is | 1388 | // The expression is already a boolean one, return it as-is |
| 1373 | if (isBoolRes(node)) | 1389 | if (isBoolRes(sub_expr_node)) |
| 1374 | return node; | 1390 | return sub_expr_node; |
| 1375 | 1391 | ||
| 1376 | // val != 0 | 1392 | // val != 0 |
| 1377 | const op_token = try appendToken(rp.c, .BangEqual, "!="); | 1393 | const op_token = try appendToken(rp.c, .BangEqual, "!="); |
| 1378 | const rhs_node = try transCreateNodeInt(rp.c, 0); | 1394 | const rhs_node = try transCreateNodeInt(rp.c, 0); |
| 1379 | return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false); | 1395 | return transCreateNodeInfixOp(rp, scope, sub_expr_node, .BangEqual, op_token, rhs_node, result_used, false); |
| 1380 | }, | 1396 | }, |
| 1381 | else => |kind| return revertAndWarn( | 1397 | else => |kind| return revertAndWarn( |
| 1382 | rp, | 1398 | rp, |
| ... | @@ -1412,7 +1428,7 @@ fn transBoolExpr( | ... | @@ -1412,7 +1428,7 @@ fn transBoolExpr( |
| 1412 | return res; | 1428 | return res; |
| 1413 | } | 1429 | } |
| 1414 | 1430 | ||
| 1415 | const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr)); | 1431 | const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, expr)); |
| 1416 | const node = try finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used); | 1432 | const node = try finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used); |
| 1417 | 1433 | ||
| 1418 | if (grouped) { | 1434 | if (grouped) { |
| ... | @@ -1433,6 +1449,18 @@ fn exprIsBooleanType(expr: *const ZigClangExpr) bool { | ... | @@ -1433,6 +1449,18 @@ fn exprIsBooleanType(expr: *const ZigClangExpr) bool { |
| 1433 | return qualTypeIsBoolean(ZigClangExpr_getType(expr)); | 1449 | return qualTypeIsBoolean(ZigClangExpr_getType(expr)); |
| 1434 | } | 1450 | } |
| 1435 | 1451 | ||
| 1452 | fn exprIsStringLiteral(expr: *const ZigClangExpr) bool { | ||
| 1453 | switch (ZigClangExpr_getStmtClass(expr)) { | ||
| 1454 | .StringLiteralClass => return true, | ||
| 1455 | .PredefinedExprClass => return true, | ||
| 1456 | .UnaryOperatorClass => { | ||
| 1457 | const op_expr = ZigClangUnaryOperator_getSubExpr(@ptrCast(*const ZigClangUnaryOperator, expr)); | ||
| 1458 | return exprIsStringLiteral(op_expr); | ||
| 1459 | }, | ||
| 1460 | else => return false, | ||
| 1461 | } | ||
| 1462 | } | ||
| 1463 | |||
| 1436 | fn isBoolRes(res: *ast.Node) bool { | 1464 | fn isBoolRes(res: *ast.Node) bool { |
| 1437 | switch (res.id) { | 1465 | switch (res.id) { |
| 1438 | .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) { | 1466 | .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) { |
| ... | @@ -1765,10 +1793,34 @@ fn transCCast( | ... | @@ -1765,10 +1793,34 @@ fn transCCast( |
| 1765 | if (ZigClangType_isBooleanType(qualTypeCanon(src_type)) and | 1793 | if (ZigClangType_isBooleanType(qualTypeCanon(src_type)) and |
| 1766 | !ZigClangType_isBooleanType(qualTypeCanon(dst_type))) | 1794 | !ZigClangType_isBooleanType(qualTypeCanon(dst_type))) |
| 1767 | { | 1795 | { |
| 1796 | // @boolToInt returns either a comptime_int or a u1 | ||
| 1768 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); | 1797 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt"); |
| 1769 | try builtin_node.params.push(expr); | 1798 | try builtin_node.params.push(expr); |
| 1770 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | 1799 | builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); |
| 1771 | return &builtin_node.base; | 1800 | |
| 1801 | const inner_cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); | ||
| 1802 | try inner_cast_node.params.push(try transCreateNodeIdentifier(rp.c, "u1")); | ||
| 1803 | _ = try appendToken(rp.c, .Comma, ","); | ||
| 1804 | try inner_cast_node.params.push(&builtin_node.base); | ||
| 1805 | inner_cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | ||
| 1806 | |||
| 1807 | const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast"); | ||
| 1808 | try cast_node.params.push(try transQualType(rp, dst_type, loc)); | ||
| 1809 | _ = try appendToken(rp.c, .Comma, ","); | ||
| 1810 | |||
| 1811 | if (cIsSignedInteger(dst_type)) { | ||
| 1812 | const bitcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast"); | ||
| 1813 | try bitcast_node.params.push(try transCreateNodeIdentifier(rp.c, "i1")); | ||
| 1814 | _ = try appendToken(rp.c, .Comma, ","); | ||
| 1815 | try bitcast_node.params.push(&inner_cast_node.base); | ||
| 1816 | bitcast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | ||
| 1817 | try cast_node.params.push(&bitcast_node.base); | ||
| 1818 | } else { | ||
| 1819 | try cast_node.params.push(&inner_cast_node.base); | ||
| 1820 | } | ||
| 1821 | cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); | ||
| 1822 | |||
| 1823 | return &cast_node.base; | ||
| 1772 | } | 1824 | } |
| 1773 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) { | 1825 | if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) { |
| 1774 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); | 1826 | const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); |
| ... | @@ -3024,6 +3076,64 @@ fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFl | ... | @@ -3024,6 +3076,64 @@ fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFl |
| 3024 | return maybeSuppressResult(rp, scope, used, &node.base); | 3076 | return maybeSuppressResult(rp, scope, used, &node.base); |
| 3025 | } | 3077 | } |
| 3026 | 3078 | ||
| 3079 | fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangBinaryConditionalOperator, used: ResultUsed) TransError!*ast.Node { | ||
| 3080 | // GNU extension of the ternary operator where the middle expression is | ||
| 3081 | // omitted, the conditition itself is returned if it evaluates to true | ||
| 3082 | const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt); | ||
| 3083 | const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt); | ||
| 3084 | const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt); | ||
| 3085 | const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt); | ||
| 3086 | |||
| 3087 | // c: (cond_expr)?:(false_expr) | ||
| 3088 | // zig: (blk: { | ||
| 3089 | // const _cond_temp = (cond_expr); | ||
| 3090 | // break :blk if (_cond_temp) _cond_temp else (false_expr); | ||
| 3091 | // }) | ||
| 3092 | const lparen = try appendToken(rp.c, .LParen, "("); | ||
| 3093 | |||
| 3094 | const block_scope = try Scope.Block.init(rp.c, scope, "blk"); | ||
| 3095 | block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label); | ||
| 3096 | |||
| 3097 | const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp"); | ||
| 3098 | const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name); | ||
| 3099 | tmp_var.eq_token = try appendToken(rp.c, .Equal, "="); | ||
| 3100 | tmp_var.init_node = try transExpr(rp, &block_scope.base, cond_expr, .used, .r_value); | ||
| 3101 | tmp_var.semicolon_token = try appendToken(rp.c, .Semicolon, ";"); | ||
| 3102 | try block_scope.block_node.statements.push(&tmp_var.base); | ||
| 3103 | |||
| 3104 | const break_node = try transCreateNodeBreak(rp.c, block_scope.label); | ||
| 3105 | |||
| 3106 | const if_node = try transCreateNodeIf(rp.c); | ||
| 3107 | var cond_scope = Scope{ | ||
| 3108 | .parent = &block_scope.base, | ||
| 3109 | .id = .Condition, | ||
| 3110 | }; | ||
| 3111 | const tmp_var_node = try transCreateNodeIdentifier(rp.c, mangled_name); | ||
| 3112 | |||
| 3113 | const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, cond_expr)); | ||
| 3114 | const cond_node = try finishBoolExpr(rp, &block_scope.base, ZigClangExpr_getBeginLoc(cond_expr), ty, tmp_var_node, used); | ||
| 3115 | if_node.condition = cond_node; | ||
| 3116 | _ = try appendToken(rp.c, .RParen, ")"); | ||
| 3117 | |||
| 3118 | if_node.body = try transCreateNodeIdentifier(rp.c, mangled_name); | ||
| 3119 | if_node.@"else" = try transCreateNodeElse(rp.c); | ||
| 3120 | if_node.@"else".?.body = try transExpr(rp, &block_scope.base, false_expr, .used, .r_value); | ||
| 3121 | _ = try appendToken(rp.c, .Semicolon, ";"); | ||
| 3122 | |||
| 3123 | break_node.rhs = &if_node.base; | ||
| 3124 | _ = try appendToken(rp.c, .Semicolon, ";"); | ||
| 3125 | try block_scope.block_node.statements.push(&break_node.base); | ||
| 3126 | block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}"); | ||
| 3127 | |||
| 3128 | const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression); | ||
| 3129 | grouped_expr.* = .{ | ||
| 3130 | .lparen = lparen, | ||
| 3131 | .expr = &block_scope.block_node.base, | ||
| 3132 | .rparen = try appendToken(rp.c, .RParen, ")"), | ||
| 3133 | }; | ||
| 3134 | return maybeSuppressResult(rp, scope, used, &grouped_expr.base); | ||
| 3135 | } | ||
| 3136 | |||
| 3027 | fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangConditionalOperator, used: ResultUsed) TransError!*ast.Node { | 3137 | fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangConditionalOperator, used: ResultUsed) TransError!*ast.Node { |
| 3028 | const grouped = scope.id == .Condition; | 3138 | const grouped = scope.id == .Condition; |
| 3029 | const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined; | 3139 | const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined; |
| ... | @@ -3033,9 +3143,10 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla | ... | @@ -3033,9 +3143,10 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla |
| 3033 | .id = .Condition, | 3143 | .id = .Condition, |
| 3034 | }; | 3144 | }; |
| 3035 | 3145 | ||
| 3036 | const cond_expr = ZigClangConditionalOperator_getCond(stmt); | 3146 | const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt); |
| 3037 | const true_expr = ZigClangConditionalOperator_getTrueExpr(stmt); | 3147 | const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt); |
| 3038 | const false_expr = ZigClangConditionalOperator_getFalseExpr(stmt); | 3148 | const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt); |
| 3149 | const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt); | ||
| 3039 | 3150 | ||
| 3040 | if_node.condition = try transBoolExpr(rp, &cond_scope, cond_expr, .used, .r_value, false); | 3151 | if_node.condition = try transBoolExpr(rp, &cond_scope, cond_expr, .used, .r_value, false); |
| 3041 | _ = try appendToken(rp.c, .RParen, ")"); | 3152 | _ = try appendToken(rp.c, .RParen, ")"); |
| ... | @@ -3278,14 +3389,6 @@ fn getExprQualType(c: *Context, expr: *const ZigClangExpr) ZigClangQualType { | ... | @@ -3278,14 +3389,6 @@ fn getExprQualType(c: *Context, expr: *const ZigClangExpr) ZigClangQualType { |
| 3278 | return ZigClangExpr_getType(expr); | 3389 | return ZigClangExpr_getType(expr); |
| 3279 | } | 3390 | } |
| 3280 | 3391 | ||
| 3281 | fn getExprQualTypeBeforeImplicitCast(c: *Context, expr: *const ZigClangExpr) ZigClangQualType { | ||
| 3282 | if (ZigClangExpr_getStmtClass(expr) == .ImplicitCastExprClass) { | ||
| 3283 | const cast_expr = @ptrCast(*const ZigClangImplicitCastExpr, expr); | ||
| 3284 | return getExprQualType(c, ZigClangImplicitCastExpr_getSubExpr(cast_expr)); | ||
| 3285 | } | ||
| 3286 | return ZigClangExpr_getType(expr); | ||
| 3287 | } | ||
| 3288 | |||
| 3289 | fn typeIsOpaque(c: *Context, ty: *const ZigClangType, loc: ZigClangSourceLocation) bool { | 3392 | fn typeIsOpaque(c: *Context, ty: *const ZigClangType, loc: ZigClangSourceLocation) bool { |
| 3290 | switch (ZigClangType_getTypeClass(ty)) { | 3393 | switch (ZigClangType_getTypeClass(ty)) { |
| 3291 | .Builtin => { | 3394 | .Builtin => { |
src/zig_clang.cpp+11-6| ... | @@ -1749,6 +1749,11 @@ const char* ZigClangFunctionDecl_getSectionAttribute(const struct ZigClangFuncti | ... | @@ -1749,6 +1749,11 @@ const char* ZigClangFunctionDecl_getSectionAttribute(const struct ZigClangFuncti |
| 1749 | return nullptr; | 1749 | return nullptr; |
| 1750 | } | 1750 | } |
| 1751 | 1751 | ||
| 1752 | const ZigClangExpr *ZigClangOpaqueValueExpr_getSourceExpr(const ZigClangOpaqueValueExpr *self) { | ||
| 1753 | auto casted = reinterpret_cast<const clang::OpaqueValueExpr *>(self); | ||
| 1754 | return reinterpret_cast<const ZigClangExpr *>(casted->getSourceExpr()); | ||
| 1755 | } | ||
| 1756 | |||
| 1752 | const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) { | 1757 | const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) { |
| 1753 | auto casted = reinterpret_cast<const clang::TypedefType *>(self); | 1758 | auto casted = reinterpret_cast<const clang::TypedefType *>(self); |
| 1754 | const clang::TypedefNameDecl *name_decl = casted->getDecl(); | 1759 | const clang::TypedefNameDecl *name_decl = casted->getDecl(); |
| ... | @@ -2429,18 +2434,18 @@ unsigned ZigClangCharacterLiteral_getValue(const struct ZigClangCharacterLiteral | ... | @@ -2429,18 +2434,18 @@ unsigned ZigClangCharacterLiteral_getValue(const struct ZigClangCharacterLiteral |
| 2429 | return casted->getValue(); | 2434 | return casted->getValue(); |
| 2430 | } | 2435 | } |
| 2431 | 2436 | ||
| 2432 | const struct ZigClangExpr *ZigClangConditionalOperator_getCond(const struct ZigClangConditionalOperator *self) { | 2437 | const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getCond(const struct ZigClangAbstractConditionalOperator *self) { |
| 2433 | auto casted = reinterpret_cast<const clang::ConditionalOperator *>(self); | 2438 | auto casted = reinterpret_cast<const clang::AbstractConditionalOperator *>(self); |
| 2434 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getCond()); | 2439 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getCond()); |
| 2435 | } | 2440 | } |
| 2436 | 2441 | ||
| 2437 | const struct ZigClangExpr *ZigClangConditionalOperator_getTrueExpr(const struct ZigClangConditionalOperator *self) { | 2442 | const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getTrueExpr(const struct ZigClangAbstractConditionalOperator *self) { |
| 2438 | auto casted = reinterpret_cast<const clang::ConditionalOperator *>(self); | 2443 | auto casted = reinterpret_cast<const clang::AbstractConditionalOperator *>(self); |
| 2439 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getTrueExpr()); | 2444 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getTrueExpr()); |
| 2440 | } | 2445 | } |
| 2441 | 2446 | ||
| 2442 | const struct ZigClangExpr *ZigClangConditionalOperator_getFalseExpr(const struct ZigClangConditionalOperator *self) { | 2447 | const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getFalseExpr(const struct ZigClangAbstractConditionalOperator *self) { |
| 2443 | auto casted = reinterpret_cast<const clang::ConditionalOperator *>(self); | 2448 | auto casted = reinterpret_cast<const clang::AbstractConditionalOperator *>(self); |
| 2444 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getFalseExpr()); | 2449 | return reinterpret_cast<const struct ZigClangExpr *>(casted->getFalseExpr()); |
| 2445 | } | 2450 | } |
| 2446 | 2451 |
src/zig_clang.h+6-3| ... | @@ -116,6 +116,7 @@ struct ZigClangMacroQualifiedType; | ... | @@ -116,6 +116,7 @@ struct ZigClangMacroQualifiedType; |
| 116 | struct ZigClangMemberExpr; | 116 | struct ZigClangMemberExpr; |
| 117 | struct ZigClangNamedDecl; | 117 | struct ZigClangNamedDecl; |
| 118 | struct ZigClangNone; | 118 | struct ZigClangNone; |
| 119 | struct ZigClangOpaqueValueExpr; | ||
| 119 | struct ZigClangPCHContainerOperations; | 120 | struct ZigClangPCHContainerOperations; |
| 120 | struct ZigClangParenExpr; | 121 | struct ZigClangParenExpr; |
| 121 | struct ZigClangParenType; | 122 | struct ZigClangParenType; |
| ... | @@ -1056,9 +1057,9 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangCharacterLiteral_getBeginLoc( | ... | @@ -1056,9 +1057,9 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangCharacterLiteral_getBeginLoc( |
| 1056 | ZIG_EXTERN_C enum ZigClangCharacterLiteral_CharacterKind ZigClangCharacterLiteral_getKind(const struct ZigClangCharacterLiteral *); | 1057 | ZIG_EXTERN_C enum ZigClangCharacterLiteral_CharacterKind ZigClangCharacterLiteral_getKind(const struct ZigClangCharacterLiteral *); |
| 1057 | ZIG_EXTERN_C unsigned ZigClangCharacterLiteral_getValue(const struct ZigClangCharacterLiteral *); | 1058 | ZIG_EXTERN_C unsigned ZigClangCharacterLiteral_getValue(const struct ZigClangCharacterLiteral *); |
| 1058 | 1059 | ||
| 1059 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConditionalOperator_getCond(const struct ZigClangConditionalOperator *); | 1060 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getCond(const struct ZigClangAbstractConditionalOperator *); |
| 1060 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConditionalOperator_getTrueExpr(const struct ZigClangConditionalOperator *); | 1061 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getTrueExpr(const struct ZigClangAbstractConditionalOperator *); |
| 1061 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConditionalOperator_getFalseExpr(const struct ZigClangConditionalOperator *); | 1062 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getFalseExpr(const struct ZigClangAbstractConditionalOperator *); |
| 1062 | 1063 | ||
| 1063 | ZIG_EXTERN_C struct ZigClangQualType ZigClangCompoundAssignOperator_getType(const struct ZigClangCompoundAssignOperator *); | 1064 | ZIG_EXTERN_C struct ZigClangQualType ZigClangCompoundAssignOperator_getType(const struct ZigClangCompoundAssignOperator *); |
| 1064 | ZIG_EXTERN_C struct ZigClangQualType ZigClangCompoundAssignOperator_getComputationLHSType(const struct ZigClangCompoundAssignOperator *); | 1065 | ZIG_EXTERN_C struct ZigClangQualType ZigClangCompoundAssignOperator_getComputationLHSType(const struct ZigClangCompoundAssignOperator *); |
| ... | @@ -1088,6 +1089,8 @@ ZIG_EXTERN_C const struct ZigClangExpr *ZigClangMemberExpr_getBase(const struct | ... | @@ -1088,6 +1089,8 @@ ZIG_EXTERN_C const struct ZigClangExpr *ZigClangMemberExpr_getBase(const struct |
| 1088 | ZIG_EXTERN_C bool ZigClangMemberExpr_isArrow(const struct ZigClangMemberExpr *); | 1089 | ZIG_EXTERN_C bool ZigClangMemberExpr_isArrow(const struct ZigClangMemberExpr *); |
| 1089 | ZIG_EXTERN_C const struct ZigClangValueDecl * ZigClangMemberExpr_getMemberDecl(const struct ZigClangMemberExpr *); | 1090 | ZIG_EXTERN_C const struct ZigClangValueDecl * ZigClangMemberExpr_getMemberDecl(const struct ZigClangMemberExpr *); |
| 1090 | 1091 | ||
| 1092 | ZIG_EXTERN_C const ZigClangExpr *ZigClangOpaqueValueExpr_getSourceExpr(const struct ZigClangOpaqueValueExpr *); | ||
| 1093 | |||
| 1091 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangArraySubscriptExpr_getBase(const struct ZigClangArraySubscriptExpr *); | 1094 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangArraySubscriptExpr_getBase(const struct ZigClangArraySubscriptExpr *); |
| 1092 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangArraySubscriptExpr_getIdx(const struct ZigClangArraySubscriptExpr *); | 1095 | ZIG_EXTERN_C const struct ZigClangExpr *ZigClangArraySubscriptExpr_getIdx(const struct ZigClangArraySubscriptExpr *); |
| 1093 | 1096 |
test/run_translated_c.zig+18| ... | @@ -3,6 +3,23 @@ const tests = @import("tests.zig"); | ... | @@ -3,6 +3,23 @@ const tests = @import("tests.zig"); |
| 3 | const nl = std.cstr.line_sep; | 3 | const nl = std.cstr.line_sep; |
| 4 | 4 | ||
| 5 | pub fn addCases(cases: *tests.RunTranslatedCContext) void { | 5 | pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 6 | cases.add("ternary operator", | ||
| 7 | \\#include <assert.h> | ||
| 8 | \\static int cnt = 0; | ||
| 9 | \\int foo() { cnt++; return 42; } | ||
| 10 | \\int main(int argc, char **argv) { | ||
| 11 | \\ short q = 3; | ||
| 12 | \\ signed char z0 = q?:1; | ||
| 13 | \\ assert(z0 == 3); | ||
| 14 | \\ int z1 = 3?:1; | ||
| 15 | \\ assert(z1 == 3); | ||
| 16 | \\ int z2 = foo()?:-1; | ||
| 17 | \\ assert(z2 == 42); | ||
| 18 | \\ assert(cnt == 1); | ||
| 19 | \\ return 0; | ||
| 20 | \\} | ||
| 21 | , ""); | ||
| 22 | |||
| 6 | cases.add("boolean values and expressions", | 23 | cases.add("boolean values and expressions", |
| 7 | \\#include <stdlib.h> | 24 | \\#include <stdlib.h> |
| 8 | \\static const _Bool false_val = 0; | 25 | \\static const _Bool false_val = 0; |
| ... | @@ -12,6 +29,7 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { | ... | @@ -12,6 +29,7 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 12 | \\ if (!r) abort(); | 29 | \\ if (!r) abort(); |
| 13 | \\ _Bool self = foo; | 30 | \\ _Bool self = foo; |
| 14 | \\ if (self == false_val) abort(); | 31 | \\ if (self == false_val) abort(); |
| 32 | \\ if (((r) ? 'a' : 'b') != 'a') abort(); | ||
| 15 | \\} | 33 | \\} |
| 16 | \\int main(int argc, char **argv) { | 34 | \\int main(int argc, char **argv) { |
| 17 | \\ foo(2, 5); | 35 | \\ foo(2, 5); |
test/translate_c.zig+3-3| ... | @@ -2530,10 +2530,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -2530,10 +2530,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 2530 | , &[_][]const u8{ | 2530 | , &[_][]const u8{ |
| 2531 | \\pub export fn foo(arg_x: bool) bool { | 2531 | \\pub export fn foo(arg_x: bool) bool { |
| 2532 | \\ var x = arg_x; | 2532 | \\ var x = arg_x; |
| 2533 | \\ var a: bool = (@boolToInt(x) != @as(c_int, 1)); | 2533 | \\ var a: bool = (@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(x)))) != @as(c_int, 1)); |
| 2534 | \\ var b: bool = (@boolToInt(a) != @as(c_int, 0)); | 2534 | \\ var b: bool = (@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(a)))) != @as(c_int, 0)); |
| 2535 | \\ var c: bool = @ptrToInt(foo) != 0; | 2535 | \\ var c: bool = @ptrToInt(foo) != 0; |
| 2536 | \\ return foo((@boolToInt(c) != @boolToInt(b))); | 2536 | \\ return foo((@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(c)))) != @intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(b)))))); |
| 2537 | \\} | 2537 | \\} |
| 2538 | }); | 2538 | }); |
| 2539 | } | 2539 | } |