authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-07 10:54:42+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-08 08:43:37+01:00
logfd7e69a2c0895f08fe3b8a75fb142250678d5e1f
treebc0ce710b53042a0ae068202ddd0bbe8717c2200
parent2a5c622e65a07db95859beabf46f36d3a62c785a

More translate-c fixes

* Translate OpaqueValueExpr * Translate BinaryConditionalOperator * Fix translation of boolean->int casts * Reoder some tokens to avoid rendering errors

6 files changed, 185 insertions(+), 48 deletions(-)

src-self-hosted/clang.zig+13-5
......@@ -1,5 +1,8 @@
11const builtin = @import("builtin");
22
3pub const struct_ZigClangConditionalOperator = @OpaqueType();
4pub const struct_ZigClangBinaryConditionalOperator = @OpaqueType();
5pub const struct_ZigClangAbstractConditionalOperator = @OpaqueType();
36pub const struct_ZigClangAPInt = @OpaqueType();
47pub const struct_ZigClangAPSInt = @OpaqueType();
58pub const struct_ZigClangAPFloat = @OpaqueType();
......@@ -16,7 +19,6 @@ pub const struct_ZigClangCallExpr = @OpaqueType();
1619pub const struct_ZigClangCaseStmt = @OpaqueType();
1720pub const struct_ZigClangCompoundAssignOperator = @OpaqueType();
1821pub const struct_ZigClangCompoundStmt = @OpaqueType();
19pub const struct_ZigClangConditionalOperator = @OpaqueType();
2022pub const struct_ZigClangConstantArrayType = @OpaqueType();
2123pub const struct_ZigClangContinueStmt = @OpaqueType();
2224pub const struct_ZigClangDecayedType = @OpaqueType();
......@@ -48,6 +50,7 @@ pub const struct_ZigClangMacroQualifiedType = @OpaqueType();
4850pub const struct_ZigClangMemberExpr = @OpaqueType();
4951pub const struct_ZigClangNamedDecl = @OpaqueType();
5052pub const struct_ZigClangNone = @OpaqueType();
53pub const struct_ZigClangOpaqueValueExpr = @OpaqueType();
5154pub const struct_ZigClangPCHContainerOperations = @OpaqueType();
5255pub const struct_ZigClangParenExpr = @OpaqueType();
5356pub const struct_ZigClangParenType = @OpaqueType();
......@@ -860,6 +863,9 @@ pub extern fn ZigClangFunctionProtoType_getReturnType(self: *const ZigClangFunct
860863
861864pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
862865pub const ZigClangQualType = struct_ZigClangQualType;
866pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator;
867pub const ZigClangBinaryConditionalOperator = struct_ZigClangBinaryConditionalOperator;
868pub const ZigClangAbstractConditionalOperator = struct_ZigClangAbstractConditionalOperator;
863869pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase;
864870pub const ZigClangAPValue = struct_ZigClangAPValue;
865871pub const ZigClangAPSInt = struct_ZigClangAPSInt;
......@@ -877,7 +883,6 @@ pub const ZigClangCallExpr = struct_ZigClangCallExpr;
877883pub const ZigClangCaseStmt = struct_ZigClangCaseStmt;
878884pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator;
879885pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt;
880pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator;
881886pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType;
882887pub const ZigClangContinueStmt = struct_ZigClangContinueStmt;
883888pub const ZigClangDecayedType = struct_ZigClangDecayedType;
......@@ -909,6 +914,7 @@ pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType;
909914pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
910915pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
911916pub const ZigClangNone = struct_ZigClangNone;
917pub const ZigClangOpaqueValueExpr = struct_ZigClangOpaqueValueExpr;
912918pub const ZigClangPCHContainerOperations = struct_ZigClangPCHContainerOperations;
913919pub const ZigClangParenExpr = struct_ZigClangParenExpr;
914920pub const ZigClangParenType = struct_ZigClangParenType;
......@@ -1095,9 +1101,9 @@ pub extern fn ZigClangForStmt_getBody(*const ZigClangForStmt) *const ZigClangStm
10951101pub extern fn ZigClangAPFloat_toString(self: *const ZigClangAPFloat, precision: c_uint, maxPadding: c_uint, truncateZero: bool) [*:0]const u8;
10961102pub extern fn ZigClangAPFloat_getValueAsApproximateDouble(*const ZigClangFloatingLiteral) f64;
10971103
1098pub extern fn ZigClangConditionalOperator_getCond(*const ZigClangConditionalOperator) *const ZigClangExpr;
1099pub extern fn ZigClangConditionalOperator_getTrueExpr(*const ZigClangConditionalOperator) *const ZigClangExpr;
1100pub extern fn ZigClangConditionalOperator_getFalseExpr(*const ZigClangConditionalOperator) *const ZigClangExpr;
1104pub extern fn ZigClangAbstractConditionalOperator_getCond(*const ZigClangAbstractConditionalOperator) *const ZigClangExpr;
1105pub extern fn ZigClangAbstractConditionalOperator_getTrueExpr(*const ZigClangAbstractConditionalOperator) *const ZigClangExpr;
1106pub extern fn ZigClangAbstractConditionalOperator_getFalseExpr(*const ZigClangAbstractConditionalOperator) *const ZigClangExpr;
11011107
11021108pub extern fn ZigClangSwitchStmt_getConditionVariableDeclStmt(*const ZigClangSwitchStmt) ?*const ZigClangDeclStmt;
11031109pub extern fn ZigClangSwitchStmt_getCond(*const ZigClangSwitchStmt) *const ZigClangExpr;
......@@ -1140,6 +1146,8 @@ pub extern fn ZigClangUnaryOperator_getType(*const ZigClangUnaryOperator) ZigCla
11401146pub extern fn ZigClangUnaryOperator_getSubExpr(*const ZigClangUnaryOperator) *const ZigClangExpr;
11411147pub extern fn ZigClangUnaryOperator_getBeginLoc(*const ZigClangUnaryOperator) ZigClangSourceLocation;
11421148
1149pub extern fn ZigClangOpaqueValueExpr_getSourceExpr(*const ZigClangOpaqueValueExpr) ?*const ZigClangExpr;
1150
11431151pub extern fn ZigClangCompoundAssignOperator_getType(*const ZigClangCompoundAssignOperator) ZigClangQualType;
11441152pub extern fn ZigClangCompoundAssignOperator_getComputationLHSType(*const ZigClangCompoundAssignOperator) ZigClangQualType;
11451153pub 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 {
363363 }
364364}
365365
366extern fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) bool {
366fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) callconv(.C) bool {
367367 const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
368368 declVisitorNamesOnly(c, decl) catch |err| {
369369 c.err = err;
......@@ -372,7 +372,7 @@ extern fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) bo
372372 return true;
373373}
374374
375extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool {
375fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) callconv(.C) bool {
376376 const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
377377 declVisitor(c, decl) catch |err| {
378378 c.err = err;
......@@ -1010,7 +1010,12 @@ fn transStmt(
10101010 .BreakStmtClass => return transBreak(rp, scope),
10111011 .ForStmtClass => return transForLoop(rp, scope, @ptrCast(*const ZigClangForStmt, stmt)),
10121012 .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 },
10141019 .SwitchStmtClass => return transSwitch(rp, scope, @ptrCast(*const ZigClangSwitchStmt, stmt)),
10151020 .CaseStmtClass => return transCase(rp, scope, @ptrCast(*const ZigClangCaseStmt, stmt)),
10161021 .DefaultStmtClass => return transDefault(rp, scope, @ptrCast(*const ZigClangDefaultStmt, stmt)),
......@@ -1024,6 +1029,18 @@ fn transStmt(
10241029 .UnaryExprOrTypeTraitExprClass => return transUnaryExprOrTypeTraitExpr(rp, scope, @ptrCast(*const ZigClangUnaryExprOrTypeTraitExpr, stmt), result_used),
10251030 .UnaryOperatorClass => return transUnaryOperator(rp, scope, @ptrCast(*const ZigClangUnaryOperator, stmt), result_used),
10261031 .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 },
10271044 else => {
10281045 return revertAndWarn(
10291046 rp,
......@@ -1330,28 +1347,27 @@ fn transImplicitCastExpr(
13301347) TransError!*ast.Node {
13311348 const c = rp.c;
13321349 const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr);
1333 const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value);
13341350 const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr));
13351351 const src_type = getExprQualType(c, sub_expr);
13361352 switch (ZigClangImplicitCastExpr_getCastKind(expr)) {
13371353 .BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast, .PointerToIntegral, .IntegralToPointer => {
1354 const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value);
13381355 return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);
13391356 },
13401357 .LValueToRValue, .NoOp, .FunctionToPointerDecay => {
1358 const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value);
13411359 return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
13421360 },
13431361 .ArrayToPointerDecay => {
1344 switch (ZigClangExpr_getStmtClass(sub_expr)) {
1345 .StringLiteralClass, .PredefinedExprClass => {
1346 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 },
1362 if (exprIsStringLiteral(sub_expr)) {
1363 const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value);
1364 return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
13541365 }
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);
13551371 },
13561372 .NullToPointer => {
13571373 return try transCreateNodeNullLiteral(rp.c);
......@@ -1367,16 +1383,16 @@ fn transImplicitCastExpr(
13671383 return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false);
13681384 },
13691385 .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);
13711387
13721388 // The expression is already a boolean one, return it as-is
1373 if (isBoolRes(node))
1374 return node;
1389 if (isBoolRes(sub_expr_node))
1390 return sub_expr_node;
13751391
13761392 // val != 0
13771393 const op_token = try appendToken(rp.c, .BangEqual, "!=");
13781394 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);
13801396 },
13811397 else => |kind| return revertAndWarn(
13821398 rp,
......@@ -1412,7 +1428,7 @@ fn transBoolExpr(
14121428 return res;
14131429 }
14141430
1415 const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr));
1431 const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, expr));
14161432 const node = try finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used);
14171433
14181434 if (grouped) {
......@@ -1433,6 +1449,18 @@ fn exprIsBooleanType(expr: *const ZigClangExpr) bool {
14331449 return qualTypeIsBoolean(ZigClangExpr_getType(expr));
14341450}
14351451
1452fn 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
14361464fn isBoolRes(res: *ast.Node) bool {
14371465 switch (res.id) {
14381466 .InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {
......@@ -1765,10 +1793,34 @@ fn transCCast(
17651793 if (ZigClangType_isBooleanType(qualTypeCanon(src_type)) and
17661794 !ZigClangType_isBooleanType(qualTypeCanon(dst_type)))
17671795 {
1796 // @boolToInt returns either a comptime_int or a u1
17681797 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
17691798 try builtin_node.params.push(expr);
17701799 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;
17721824 }
17731825 if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {
17741826 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
......@@ -3024,6 +3076,64 @@ fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFl
30243076 return maybeSuppressResult(rp, scope, used, &node.base);
30253077}
30263078
3079fn 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
30273137fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangConditionalOperator, used: ResultUsed) TransError!*ast.Node {
30283138 const grouped = scope.id == .Condition;
30293139 const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined;
......@@ -3033,9 +3143,10 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla
30333143 .id = .Condition,
30343144 };
30353145
3036 const cond_expr = ZigClangConditionalOperator_getCond(stmt);
3037 const true_expr = ZigClangConditionalOperator_getTrueExpr(stmt);
3038 const false_expr = ZigClangConditionalOperator_getFalseExpr(stmt);
3146 const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt);
3147 const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt);
3148 const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt);
3149 const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt);
30393150
30403151 if_node.condition = try transBoolExpr(rp, &cond_scope, cond_expr, .used, .r_value, false);
30413152 _ = try appendToken(rp.c, .RParen, ")");
......@@ -3278,14 +3389,6 @@ fn getExprQualType(c: *Context, expr: *const ZigClangExpr) ZigClangQualType {
32783389 return ZigClangExpr_getType(expr);
32793390}
32803391
3281fn 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
32893392fn typeIsOpaque(c: *Context, ty: *const ZigClangType, loc: ZigClangSourceLocation) bool {
32903393 switch (ZigClangType_getTypeClass(ty)) {
32913394 .Builtin => {
src/zig_clang.cpp+11-6
......@@ -1749,6 +1749,11 @@ const char* ZigClangFunctionDecl_getSectionAttribute(const struct ZigClangFuncti
17491749 return nullptr;
17501750}
17511751
1752const 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
17521757const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) {
17531758 auto casted = reinterpret_cast<const clang::TypedefType *>(self);
17541759 const clang::TypedefNameDecl *name_decl = casted->getDecl();
......@@ -2429,18 +2434,18 @@ unsigned ZigClangCharacterLiteral_getValue(const struct ZigClangCharacterLiteral
24292434 return casted->getValue();
24302435}
24312436
2432const struct ZigClangExpr *ZigClangConditionalOperator_getCond(const struct ZigClangConditionalOperator *self) {
2433 auto casted = reinterpret_cast<const clang::ConditionalOperator *>(self);
2437const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getCond(const struct ZigClangAbstractConditionalOperator *self) {
2438 auto casted = reinterpret_cast<const clang::AbstractConditionalOperator *>(self);
24342439 return reinterpret_cast<const struct ZigClangExpr *>(casted->getCond());
24352440}
24362441
2437const struct ZigClangExpr *ZigClangConditionalOperator_getTrueExpr(const struct ZigClangConditionalOperator *self) {
2438 auto casted = reinterpret_cast<const clang::ConditionalOperator *>(self);
2442const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getTrueExpr(const struct ZigClangAbstractConditionalOperator *self) {
2443 auto casted = reinterpret_cast<const clang::AbstractConditionalOperator *>(self);
24392444 return reinterpret_cast<const struct ZigClangExpr *>(casted->getTrueExpr());
24402445}
24412446
2442const struct ZigClangExpr *ZigClangConditionalOperator_getFalseExpr(const struct ZigClangConditionalOperator *self) {
2443 auto casted = reinterpret_cast<const clang::ConditionalOperator *>(self);
2447const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getFalseExpr(const struct ZigClangAbstractConditionalOperator *self) {
2448 auto casted = reinterpret_cast<const clang::AbstractConditionalOperator *>(self);
24442449 return reinterpret_cast<const struct ZigClangExpr *>(casted->getFalseExpr());
24452450}
24462451
src/zig_clang.h+6-3
......@@ -116,6 +116,7 @@ struct ZigClangMacroQualifiedType;
116116struct ZigClangMemberExpr;
117117struct ZigClangNamedDecl;
118118struct ZigClangNone;
119struct ZigClangOpaqueValueExpr;
119120struct ZigClangPCHContainerOperations;
120121struct ZigClangParenExpr;
121122struct ZigClangParenType;
......@@ -1056,9 +1057,9 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangCharacterLiteral_getBeginLoc(
10561057ZIG_EXTERN_C enum ZigClangCharacterLiteral_CharacterKind ZigClangCharacterLiteral_getKind(const struct ZigClangCharacterLiteral *);
10571058ZIG_EXTERN_C unsigned ZigClangCharacterLiteral_getValue(const struct ZigClangCharacterLiteral *);
10581059
1059ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConditionalOperator_getCond(const struct ZigClangConditionalOperator *);
1060ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConditionalOperator_getTrueExpr(const struct ZigClangConditionalOperator *);
1061ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConditionalOperator_getFalseExpr(const struct ZigClangConditionalOperator *);
1060ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getCond(const struct ZigClangAbstractConditionalOperator *);
1061ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getTrueExpr(const struct ZigClangAbstractConditionalOperator *);
1062ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getFalseExpr(const struct ZigClangAbstractConditionalOperator *);
10621063
10631064ZIG_EXTERN_C struct ZigClangQualType ZigClangCompoundAssignOperator_getType(const struct ZigClangCompoundAssignOperator *);
10641065ZIG_EXTERN_C struct ZigClangQualType ZigClangCompoundAssignOperator_getComputationLHSType(const struct ZigClangCompoundAssignOperator *);
......@@ -1088,6 +1089,8 @@ ZIG_EXTERN_C const struct ZigClangExpr *ZigClangMemberExpr_getBase(const struct
10881089ZIG_EXTERN_C bool ZigClangMemberExpr_isArrow(const struct ZigClangMemberExpr *);
10891090ZIG_EXTERN_C const struct ZigClangValueDecl * ZigClangMemberExpr_getMemberDecl(const struct ZigClangMemberExpr *);
10901091
1092ZIG_EXTERN_C const ZigClangExpr *ZigClangOpaqueValueExpr_getSourceExpr(const struct ZigClangOpaqueValueExpr *);
1093
10911094ZIG_EXTERN_C const struct ZigClangExpr *ZigClangArraySubscriptExpr_getBase(const struct ZigClangArraySubscriptExpr *);
10921095ZIG_EXTERN_C const struct ZigClangExpr *ZigClangArraySubscriptExpr_getIdx(const struct ZigClangArraySubscriptExpr *);
10931096
test/run_translated_c.zig+18
......@@ -3,6 +3,23 @@ const tests = @import("tests.zig");
33const nl = std.cstr.line_sep;
44
55pub 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
623 cases.add("boolean values and expressions",
724 \\#include <stdlib.h>
825 \\static const _Bool false_val = 0;
......@@ -12,6 +29,7 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
1229 \\ if (!r) abort();
1330 \\ _Bool self = foo;
1431 \\ if (self == false_val) abort();
32 \\ if (((r) ? 'a' : 'b') != 'a') abort();
1533 \\}
1634 \\int main(int argc, char **argv) {
1735 \\ foo(2, 5);
test/translate_c.zig+3-3
......@@ -2530,10 +2530,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
25302530 , &[_][]const u8{
25312531 \\pub export fn foo(arg_x: bool) bool {
25322532 \\ var x = arg_x;
2533 \\ var a: bool = (@boolToInt(x) != @as(c_int, 1));
2534 \\ var b: bool = (@boolToInt(a) != @as(c_int, 0));
2533 \\ var a: bool = (@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(x)))) != @as(c_int, 1));
2534 \\ var b: bool = (@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(a)))) != @as(c_int, 0));
25352535 \\ 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))))));
25372537 \\}
25382538 });
25392539}