mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
More translate-c fixes
* Translate OpaqueValueExpr * Translate BinaryConditionalOperator * Fix translation of boolean->int casts * Reoder some tokens to avoid rendering errors
This commit is contained in:
parent
2a5c622e65
commit
fd7e69a2c0
@ -1,5 +1,8 @@
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub const struct_ZigClangConditionalOperator = @OpaqueType();
|
||||
pub const struct_ZigClangBinaryConditionalOperator = @OpaqueType();
|
||||
pub const struct_ZigClangAbstractConditionalOperator = @OpaqueType();
|
||||
pub const struct_ZigClangAPInt = @OpaqueType();
|
||||
pub const struct_ZigClangAPSInt = @OpaqueType();
|
||||
pub const struct_ZigClangAPFloat = @OpaqueType();
|
||||
@ -16,7 +19,6 @@ pub const struct_ZigClangCallExpr = @OpaqueType();
|
||||
pub const struct_ZigClangCaseStmt = @OpaqueType();
|
||||
pub const struct_ZigClangCompoundAssignOperator = @OpaqueType();
|
||||
pub const struct_ZigClangCompoundStmt = @OpaqueType();
|
||||
pub const struct_ZigClangConditionalOperator = @OpaqueType();
|
||||
pub const struct_ZigClangConstantArrayType = @OpaqueType();
|
||||
pub const struct_ZigClangContinueStmt = @OpaqueType();
|
||||
pub const struct_ZigClangDecayedType = @OpaqueType();
|
||||
@ -48,6 +50,7 @@ pub const struct_ZigClangMacroQualifiedType = @OpaqueType();
|
||||
pub const struct_ZigClangMemberExpr = @OpaqueType();
|
||||
pub const struct_ZigClangNamedDecl = @OpaqueType();
|
||||
pub const struct_ZigClangNone = @OpaqueType();
|
||||
pub const struct_ZigClangOpaqueValueExpr = @OpaqueType();
|
||||
pub const struct_ZigClangPCHContainerOperations = @OpaqueType();
|
||||
pub const struct_ZigClangParenExpr = @OpaqueType();
|
||||
pub const struct_ZigClangParenType = @OpaqueType();
|
||||
@ -860,6 +863,9 @@ pub extern fn ZigClangFunctionProtoType_getReturnType(self: *const ZigClangFunct
|
||||
|
||||
pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
|
||||
pub const ZigClangQualType = struct_ZigClangQualType;
|
||||
pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator;
|
||||
pub const ZigClangBinaryConditionalOperator = struct_ZigClangBinaryConditionalOperator;
|
||||
pub const ZigClangAbstractConditionalOperator = struct_ZigClangAbstractConditionalOperator;
|
||||
pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase;
|
||||
pub const ZigClangAPValue = struct_ZigClangAPValue;
|
||||
pub const ZigClangAPSInt = struct_ZigClangAPSInt;
|
||||
@ -877,7 +883,6 @@ pub const ZigClangCallExpr = struct_ZigClangCallExpr;
|
||||
pub const ZigClangCaseStmt = struct_ZigClangCaseStmt;
|
||||
pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator;
|
||||
pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt;
|
||||
pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator;
|
||||
pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType;
|
||||
pub const ZigClangContinueStmt = struct_ZigClangContinueStmt;
|
||||
pub const ZigClangDecayedType = struct_ZigClangDecayedType;
|
||||
@ -909,6 +914,7 @@ pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType;
|
||||
pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
|
||||
pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
|
||||
pub const ZigClangNone = struct_ZigClangNone;
|
||||
pub const ZigClangOpaqueValueExpr = struct_ZigClangOpaqueValueExpr;
|
||||
pub const ZigClangPCHContainerOperations = struct_ZigClangPCHContainerOperations;
|
||||
pub const ZigClangParenExpr = struct_ZigClangParenExpr;
|
||||
pub const ZigClangParenType = struct_ZigClangParenType;
|
||||
@ -1095,9 +1101,9 @@ pub extern fn ZigClangForStmt_getBody(*const ZigClangForStmt) *const ZigClangStm
|
||||
pub extern fn ZigClangAPFloat_toString(self: *const ZigClangAPFloat, precision: c_uint, maxPadding: c_uint, truncateZero: bool) [*:0]const u8;
|
||||
pub extern fn ZigClangAPFloat_getValueAsApproximateDouble(*const ZigClangFloatingLiteral) f64;
|
||||
|
||||
pub extern fn ZigClangConditionalOperator_getCond(*const ZigClangConditionalOperator) *const ZigClangExpr;
|
||||
pub extern fn ZigClangConditionalOperator_getTrueExpr(*const ZigClangConditionalOperator) *const ZigClangExpr;
|
||||
pub extern fn ZigClangConditionalOperator_getFalseExpr(*const ZigClangConditionalOperator) *const ZigClangExpr;
|
||||
pub extern fn ZigClangAbstractConditionalOperator_getCond(*const ZigClangAbstractConditionalOperator) *const ZigClangExpr;
|
||||
pub extern fn ZigClangAbstractConditionalOperator_getTrueExpr(*const ZigClangAbstractConditionalOperator) *const ZigClangExpr;
|
||||
pub extern fn ZigClangAbstractConditionalOperator_getFalseExpr(*const ZigClangAbstractConditionalOperator) *const ZigClangExpr;
|
||||
|
||||
pub extern fn ZigClangSwitchStmt_getConditionVariableDeclStmt(*const ZigClangSwitchStmt) ?*const ZigClangDeclStmt;
|
||||
pub extern fn ZigClangSwitchStmt_getCond(*const ZigClangSwitchStmt) *const ZigClangExpr;
|
||||
@ -1140,6 +1146,8 @@ pub extern fn ZigClangUnaryOperator_getType(*const ZigClangUnaryOperator) ZigCla
|
||||
pub extern fn ZigClangUnaryOperator_getSubExpr(*const ZigClangUnaryOperator) *const ZigClangExpr;
|
||||
pub extern fn ZigClangUnaryOperator_getBeginLoc(*const ZigClangUnaryOperator) ZigClangSourceLocation;
|
||||
|
||||
pub extern fn ZigClangOpaqueValueExpr_getSourceExpr(*const ZigClangOpaqueValueExpr) ?*const ZigClangExpr;
|
||||
|
||||
pub extern fn ZigClangCompoundAssignOperator_getType(*const ZigClangCompoundAssignOperator) ZigClangQualType;
|
||||
pub extern fn ZigClangCompoundAssignOperator_getComputationLHSType(*const ZigClangCompoundAssignOperator) ZigClangQualType;
|
||||
pub extern fn ZigClangCompoundAssignOperator_getComputationResultType(*const ZigClangCompoundAssignOperator) ZigClangQualType;
|
||||
|
||||
@ -363,7 +363,7 @@ fn prepopulateGlobalNameTable(ast_unit: *ZigClangASTUnit, c: *Context) !void {
|
||||
}
|
||||
}
|
||||
|
||||
extern fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) bool {
|
||||
fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) callconv(.C) bool {
|
||||
const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
|
||||
declVisitorNamesOnly(c, decl) catch |err| {
|
||||
c.err = err;
|
||||
@ -372,7 +372,7 @@ extern fn declVisitorNamesOnlyC(context: ?*c_void, decl: *const ZigClangDecl) bo
|
||||
return true;
|
||||
}
|
||||
|
||||
extern fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) bool {
|
||||
fn declVisitorC(context: ?*c_void, decl: *const ZigClangDecl) callconv(.C) bool {
|
||||
const c = @ptrCast(*Context, @alignCast(@alignOf(Context), context));
|
||||
declVisitor(c, decl) catch |err| {
|
||||
c.err = err;
|
||||
@ -1010,7 +1010,12 @@ fn transStmt(
|
||||
.BreakStmtClass => return transBreak(rp, scope),
|
||||
.ForStmtClass => return transForLoop(rp, scope, @ptrCast(*const ZigClangForStmt, stmt)),
|
||||
.FloatingLiteralClass => return transFloatingLiteral(rp, scope, @ptrCast(*const ZigClangFloatingLiteral, stmt), result_used),
|
||||
.ConditionalOperatorClass => return transConditionalOperator(rp, scope, @ptrCast(*const ZigClangConditionalOperator, stmt), result_used),
|
||||
.ConditionalOperatorClass => {
|
||||
return transConditionalOperator(rp, scope, @ptrCast(*const ZigClangConditionalOperator, stmt), result_used);
|
||||
},
|
||||
.BinaryConditionalOperatorClass => {
|
||||
return transBinaryConditionalOperator(rp, scope, @ptrCast(*const ZigClangBinaryConditionalOperator, stmt), result_used);
|
||||
},
|
||||
.SwitchStmtClass => return transSwitch(rp, scope, @ptrCast(*const ZigClangSwitchStmt, stmt)),
|
||||
.CaseStmtClass => return transCase(rp, scope, @ptrCast(*const ZigClangCaseStmt, stmt)),
|
||||
.DefaultStmtClass => return transDefault(rp, scope, @ptrCast(*const ZigClangDefaultStmt, stmt)),
|
||||
@ -1024,6 +1029,18 @@ fn transStmt(
|
||||
.UnaryExprOrTypeTraitExprClass => return transUnaryExprOrTypeTraitExpr(rp, scope, @ptrCast(*const ZigClangUnaryExprOrTypeTraitExpr, stmt), result_used),
|
||||
.UnaryOperatorClass => return transUnaryOperator(rp, scope, @ptrCast(*const ZigClangUnaryOperator, stmt), result_used),
|
||||
.CompoundAssignOperatorClass => return transCompoundAssignOperator(rp, scope, @ptrCast(*const ZigClangCompoundAssignOperator, stmt), result_used),
|
||||
.OpaqueValueExprClass => {
|
||||
const source_expr = ZigClangOpaqueValueExpr_getSourceExpr(@ptrCast(*const ZigClangOpaqueValueExpr, stmt)).?;
|
||||
const expr = try transExpr(rp, scope, source_expr, .used, lrvalue);
|
||||
if (expr.id == .GroupedExpression) return maybeSuppressResult(rp, scope, result_used, expr);
|
||||
const node = try rp.c.a().create(ast.Node.GroupedExpression);
|
||||
node.* = .{
|
||||
.lparen = try appendToken(rp.c, .LParen, "("),
|
||||
.expr = expr,
|
||||
.rparen = try appendToken(rp.c, .RParen, ")"),
|
||||
};
|
||||
return maybeSuppressResult(rp, scope, result_used, &node.base);
|
||||
},
|
||||
else => {
|
||||
return revertAndWarn(
|
||||
rp,
|
||||
@ -1330,28 +1347,27 @@ fn transImplicitCastExpr(
|
||||
) TransError!*ast.Node {
|
||||
const c = rp.c;
|
||||
const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr);
|
||||
const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value);
|
||||
const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr));
|
||||
const src_type = getExprQualType(c, sub_expr);
|
||||
switch (ZigClangImplicitCastExpr_getCastKind(expr)) {
|
||||
.BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast, .PointerToIntegral, .IntegralToPointer => {
|
||||
const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value);
|
||||
return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);
|
||||
},
|
||||
.LValueToRValue, .NoOp, .FunctionToPointerDecay => {
|
||||
const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value);
|
||||
return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
|
||||
},
|
||||
.ArrayToPointerDecay => {
|
||||
switch (ZigClangExpr_getStmtClass(sub_expr)) {
|
||||
.StringLiteralClass, .PredefinedExprClass => {
|
||||
return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
|
||||
},
|
||||
else => {
|
||||
const prefix_op = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&");
|
||||
prefix_op.rhs = sub_expr_node;
|
||||
|
||||
return maybeSuppressResult(rp, scope, result_used, &prefix_op.base);
|
||||
},
|
||||
if (exprIsStringLiteral(sub_expr)) {
|
||||
const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value);
|
||||
return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
|
||||
}
|
||||
|
||||
const prefix_op = try transCreateNodePrefixOp(rp.c, .AddressOf, .Ampersand, "&");
|
||||
prefix_op.rhs = try transExpr(rp, scope, sub_expr, .used, .r_value);
|
||||
|
||||
return maybeSuppressResult(rp, scope, result_used, &prefix_op.base);
|
||||
},
|
||||
.NullToPointer => {
|
||||
return try transCreateNodeNullLiteral(rp.c);
|
||||
@ -1367,16 +1383,16 @@ fn transImplicitCastExpr(
|
||||
return transCreateNodeInfixOp(rp, scope, &ptr_to_int.base, .BangEqual, op_token, rhs_node, result_used, false);
|
||||
},
|
||||
.IntegralToBoolean => {
|
||||
const node = try transExpr(rp, scope, sub_expr, .used, .r_value);
|
||||
const sub_expr_node = try transExpr(rp, scope, sub_expr, .used, .r_value);
|
||||
|
||||
// The expression is already a boolean one, return it as-is
|
||||
if (isBoolRes(node))
|
||||
return node;
|
||||
if (isBoolRes(sub_expr_node))
|
||||
return sub_expr_node;
|
||||
|
||||
// val != 0
|
||||
const op_token = try appendToken(rp.c, .BangEqual, "!=");
|
||||
const rhs_node = try transCreateNodeInt(rp.c, 0);
|
||||
return transCreateNodeInfixOp(rp, scope, node, .BangEqual, op_token, rhs_node, result_used, false);
|
||||
return transCreateNodeInfixOp(rp, scope, sub_expr_node, .BangEqual, op_token, rhs_node, result_used, false);
|
||||
},
|
||||
else => |kind| return revertAndWarn(
|
||||
rp,
|
||||
@ -1412,7 +1428,7 @@ fn transBoolExpr(
|
||||
return res;
|
||||
}
|
||||
|
||||
const ty = ZigClangQualType_getTypePtr(getExprQualTypeBeforeImplicitCast(rp.c, expr));
|
||||
const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, expr));
|
||||
const node = try finishBoolExpr(rp, scope, ZigClangExpr_getBeginLoc(expr), ty, res, used);
|
||||
|
||||
if (grouped) {
|
||||
@ -1433,6 +1449,18 @@ fn exprIsBooleanType(expr: *const ZigClangExpr) bool {
|
||||
return qualTypeIsBoolean(ZigClangExpr_getType(expr));
|
||||
}
|
||||
|
||||
fn exprIsStringLiteral(expr: *const ZigClangExpr) bool {
|
||||
switch (ZigClangExpr_getStmtClass(expr)) {
|
||||
.StringLiteralClass => return true,
|
||||
.PredefinedExprClass => return true,
|
||||
.UnaryOperatorClass => {
|
||||
const op_expr = ZigClangUnaryOperator_getSubExpr(@ptrCast(*const ZigClangUnaryOperator, expr));
|
||||
return exprIsStringLiteral(op_expr);
|
||||
},
|
||||
else => return false,
|
||||
}
|
||||
}
|
||||
|
||||
fn isBoolRes(res: *ast.Node) bool {
|
||||
switch (res.id) {
|
||||
.InfixOp => switch (@fieldParentPtr(ast.Node.InfixOp, "base", res).op) {
|
||||
@ -1765,10 +1793,34 @@ fn transCCast(
|
||||
if (ZigClangType_isBooleanType(qualTypeCanon(src_type)) and
|
||||
!ZigClangType_isBooleanType(qualTypeCanon(dst_type)))
|
||||
{
|
||||
// @boolToInt returns either a comptime_int or a u1
|
||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@boolToInt");
|
||||
try builtin_node.params.push(expr);
|
||||
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
return &builtin_node.base;
|
||||
|
||||
const inner_cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
|
||||
try inner_cast_node.params.push(try transCreateNodeIdentifier(rp.c, "u1"));
|
||||
_ = try appendToken(rp.c, .Comma, ",");
|
||||
try inner_cast_node.params.push(&builtin_node.base);
|
||||
inner_cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
|
||||
const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@intCast");
|
||||
try cast_node.params.push(try transQualType(rp, dst_type, loc));
|
||||
_ = try appendToken(rp.c, .Comma, ",");
|
||||
|
||||
if (cIsSignedInteger(dst_type)) {
|
||||
const bitcast_node = try transCreateNodeBuiltinFnCall(rp.c, "@bitCast");
|
||||
try bitcast_node.params.push(try transCreateNodeIdentifier(rp.c, "i1"));
|
||||
_ = try appendToken(rp.c, .Comma, ",");
|
||||
try bitcast_node.params.push(&inner_cast_node.base);
|
||||
bitcast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
try cast_node.params.push(&bitcast_node.base);
|
||||
} else {
|
||||
try cast_node.params.push(&inner_cast_node.base);
|
||||
}
|
||||
cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
|
||||
|
||||
return &cast_node.base;
|
||||
}
|
||||
if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) {
|
||||
const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum");
|
||||
@ -3024,6 +3076,64 @@ fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFl
|
||||
return maybeSuppressResult(rp, scope, used, &node.base);
|
||||
}
|
||||
|
||||
fn transBinaryConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangBinaryConditionalOperator, used: ResultUsed) TransError!*ast.Node {
|
||||
// GNU extension of the ternary operator where the middle expression is
|
||||
// omitted, the conditition itself is returned if it evaluates to true
|
||||
const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt);
|
||||
const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt);
|
||||
const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt);
|
||||
const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt);
|
||||
|
||||
// c: (cond_expr)?:(false_expr)
|
||||
// zig: (blk: {
|
||||
// const _cond_temp = (cond_expr);
|
||||
// break :blk if (_cond_temp) _cond_temp else (false_expr);
|
||||
// })
|
||||
const lparen = try appendToken(rp.c, .LParen, "(");
|
||||
|
||||
const block_scope = try Scope.Block.init(rp.c, scope, "blk");
|
||||
block_scope.block_node = try transCreateNodeBlock(rp.c, block_scope.label);
|
||||
|
||||
const mangled_name = try block_scope.makeMangledName(rp.c, "cond_temp");
|
||||
const tmp_var = try transCreateNodeVarDecl(rp.c, false, true, mangled_name);
|
||||
tmp_var.eq_token = try appendToken(rp.c, .Equal, "=");
|
||||
tmp_var.init_node = try transExpr(rp, &block_scope.base, cond_expr, .used, .r_value);
|
||||
tmp_var.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
|
||||
try block_scope.block_node.statements.push(&tmp_var.base);
|
||||
|
||||
const break_node = try transCreateNodeBreak(rp.c, block_scope.label);
|
||||
|
||||
const if_node = try transCreateNodeIf(rp.c);
|
||||
var cond_scope = Scope{
|
||||
.parent = &block_scope.base,
|
||||
.id = .Condition,
|
||||
};
|
||||
const tmp_var_node = try transCreateNodeIdentifier(rp.c, mangled_name);
|
||||
|
||||
const ty = ZigClangQualType_getTypePtr(getExprQualType(rp.c, cond_expr));
|
||||
const cond_node = try finishBoolExpr(rp, &block_scope.base, ZigClangExpr_getBeginLoc(cond_expr), ty, tmp_var_node, used);
|
||||
if_node.condition = cond_node;
|
||||
_ = try appendToken(rp.c, .RParen, ")");
|
||||
|
||||
if_node.body = try transCreateNodeIdentifier(rp.c, mangled_name);
|
||||
if_node.@"else" = try transCreateNodeElse(rp.c);
|
||||
if_node.@"else".?.body = try transExpr(rp, &block_scope.base, false_expr, .used, .r_value);
|
||||
_ = try appendToken(rp.c, .Semicolon, ";");
|
||||
|
||||
break_node.rhs = &if_node.base;
|
||||
_ = try appendToken(rp.c, .Semicolon, ";");
|
||||
try block_scope.block_node.statements.push(&break_node.base);
|
||||
block_scope.block_node.rbrace = try appendToken(rp.c, .RBrace, "}");
|
||||
|
||||
const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
|
||||
grouped_expr.* = .{
|
||||
.lparen = lparen,
|
||||
.expr = &block_scope.block_node.base,
|
||||
.rparen = try appendToken(rp.c, .RParen, ")"),
|
||||
};
|
||||
return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
|
||||
}
|
||||
|
||||
fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangConditionalOperator, used: ResultUsed) TransError!*ast.Node {
|
||||
const grouped = scope.id == .Condition;
|
||||
const lparen = if (grouped) try appendToken(rp.c, .LParen, "(") else undefined;
|
||||
@ -3033,9 +3143,10 @@ fn transConditionalOperator(rp: RestorePoint, scope: *Scope, stmt: *const ZigCla
|
||||
.id = .Condition,
|
||||
};
|
||||
|
||||
const cond_expr = ZigClangConditionalOperator_getCond(stmt);
|
||||
const true_expr = ZigClangConditionalOperator_getTrueExpr(stmt);
|
||||
const false_expr = ZigClangConditionalOperator_getFalseExpr(stmt);
|
||||
const casted_stmt = @ptrCast(*const ZigClangAbstractConditionalOperator, stmt);
|
||||
const cond_expr = ZigClangAbstractConditionalOperator_getCond(casted_stmt);
|
||||
const true_expr = ZigClangAbstractConditionalOperator_getTrueExpr(casted_stmt);
|
||||
const false_expr = ZigClangAbstractConditionalOperator_getFalseExpr(casted_stmt);
|
||||
|
||||
if_node.condition = try transBoolExpr(rp, &cond_scope, cond_expr, .used, .r_value, false);
|
||||
_ = try appendToken(rp.c, .RParen, ")");
|
||||
@ -3278,14 +3389,6 @@ fn getExprQualType(c: *Context, expr: *const ZigClangExpr) ZigClangQualType {
|
||||
return ZigClangExpr_getType(expr);
|
||||
}
|
||||
|
||||
fn getExprQualTypeBeforeImplicitCast(c: *Context, expr: *const ZigClangExpr) ZigClangQualType {
|
||||
if (ZigClangExpr_getStmtClass(expr) == .ImplicitCastExprClass) {
|
||||
const cast_expr = @ptrCast(*const ZigClangImplicitCastExpr, expr);
|
||||
return getExprQualType(c, ZigClangImplicitCastExpr_getSubExpr(cast_expr));
|
||||
}
|
||||
return ZigClangExpr_getType(expr);
|
||||
}
|
||||
|
||||
fn typeIsOpaque(c: *Context, ty: *const ZigClangType, loc: ZigClangSourceLocation) bool {
|
||||
switch (ZigClangType_getTypeClass(ty)) {
|
||||
.Builtin => {
|
||||
|
||||
@ -1749,6 +1749,11 @@ const char* ZigClangFunctionDecl_getSectionAttribute(const struct ZigClangFuncti
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ZigClangExpr *ZigClangOpaqueValueExpr_getSourceExpr(const ZigClangOpaqueValueExpr *self) {
|
||||
auto casted = reinterpret_cast<const clang::OpaqueValueExpr *>(self);
|
||||
return reinterpret_cast<const ZigClangExpr *>(casted->getSourceExpr());
|
||||
}
|
||||
|
||||
const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *self) {
|
||||
auto casted = reinterpret_cast<const clang::TypedefType *>(self);
|
||||
const clang::TypedefNameDecl *name_decl = casted->getDecl();
|
||||
@ -2429,18 +2434,18 @@ unsigned ZigClangCharacterLiteral_getValue(const struct ZigClangCharacterLiteral
|
||||
return casted->getValue();
|
||||
}
|
||||
|
||||
const struct ZigClangExpr *ZigClangConditionalOperator_getCond(const struct ZigClangConditionalOperator *self) {
|
||||
auto casted = reinterpret_cast<const clang::ConditionalOperator *>(self);
|
||||
const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getCond(const struct ZigClangAbstractConditionalOperator *self) {
|
||||
auto casted = reinterpret_cast<const clang::AbstractConditionalOperator *>(self);
|
||||
return reinterpret_cast<const struct ZigClangExpr *>(casted->getCond());
|
||||
}
|
||||
|
||||
const struct ZigClangExpr *ZigClangConditionalOperator_getTrueExpr(const struct ZigClangConditionalOperator *self) {
|
||||
auto casted = reinterpret_cast<const clang::ConditionalOperator *>(self);
|
||||
const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getTrueExpr(const struct ZigClangAbstractConditionalOperator *self) {
|
||||
auto casted = reinterpret_cast<const clang::AbstractConditionalOperator *>(self);
|
||||
return reinterpret_cast<const struct ZigClangExpr *>(casted->getTrueExpr());
|
||||
}
|
||||
|
||||
const struct ZigClangExpr *ZigClangConditionalOperator_getFalseExpr(const struct ZigClangConditionalOperator *self) {
|
||||
auto casted = reinterpret_cast<const clang::ConditionalOperator *>(self);
|
||||
const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getFalseExpr(const struct ZigClangAbstractConditionalOperator *self) {
|
||||
auto casted = reinterpret_cast<const clang::AbstractConditionalOperator *>(self);
|
||||
return reinterpret_cast<const struct ZigClangExpr *>(casted->getFalseExpr());
|
||||
}
|
||||
|
||||
|
||||
@ -116,6 +116,7 @@ struct ZigClangMacroQualifiedType;
|
||||
struct ZigClangMemberExpr;
|
||||
struct ZigClangNamedDecl;
|
||||
struct ZigClangNone;
|
||||
struct ZigClangOpaqueValueExpr;
|
||||
struct ZigClangPCHContainerOperations;
|
||||
struct ZigClangParenExpr;
|
||||
struct ZigClangParenType;
|
||||
@ -1056,9 +1057,9 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangCharacterLiteral_getBeginLoc(
|
||||
ZIG_EXTERN_C enum ZigClangCharacterLiteral_CharacterKind ZigClangCharacterLiteral_getKind(const struct ZigClangCharacterLiteral *);
|
||||
ZIG_EXTERN_C unsigned ZigClangCharacterLiteral_getValue(const struct ZigClangCharacterLiteral *);
|
||||
|
||||
ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConditionalOperator_getCond(const struct ZigClangConditionalOperator *);
|
||||
ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConditionalOperator_getTrueExpr(const struct ZigClangConditionalOperator *);
|
||||
ZIG_EXTERN_C const struct ZigClangExpr *ZigClangConditionalOperator_getFalseExpr(const struct ZigClangConditionalOperator *);
|
||||
ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getCond(const struct ZigClangAbstractConditionalOperator *);
|
||||
ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getTrueExpr(const struct ZigClangAbstractConditionalOperator *);
|
||||
ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAbstractConditionalOperator_getFalseExpr(const struct ZigClangAbstractConditionalOperator *);
|
||||
|
||||
ZIG_EXTERN_C struct ZigClangQualType ZigClangCompoundAssignOperator_getType(const struct ZigClangCompoundAssignOperator *);
|
||||
ZIG_EXTERN_C struct ZigClangQualType ZigClangCompoundAssignOperator_getComputationLHSType(const struct ZigClangCompoundAssignOperator *);
|
||||
@ -1088,6 +1089,8 @@ ZIG_EXTERN_C const struct ZigClangExpr *ZigClangMemberExpr_getBase(const struct
|
||||
ZIG_EXTERN_C bool ZigClangMemberExpr_isArrow(const struct ZigClangMemberExpr *);
|
||||
ZIG_EXTERN_C const struct ZigClangValueDecl * ZigClangMemberExpr_getMemberDecl(const struct ZigClangMemberExpr *);
|
||||
|
||||
ZIG_EXTERN_C const ZigClangExpr *ZigClangOpaqueValueExpr_getSourceExpr(const struct ZigClangOpaqueValueExpr *);
|
||||
|
||||
ZIG_EXTERN_C const struct ZigClangExpr *ZigClangArraySubscriptExpr_getBase(const struct ZigClangArraySubscriptExpr *);
|
||||
ZIG_EXTERN_C const struct ZigClangExpr *ZigClangArraySubscriptExpr_getIdx(const struct ZigClangArraySubscriptExpr *);
|
||||
|
||||
|
||||
@ -3,6 +3,23 @@ const tests = @import("tests.zig");
|
||||
const nl = std.cstr.line_sep;
|
||||
|
||||
pub fn addCases(cases: *tests.RunTranslatedCContext) void {
|
||||
cases.add("ternary operator",
|
||||
\\#include <assert.h>
|
||||
\\static int cnt = 0;
|
||||
\\int foo() { cnt++; return 42; }
|
||||
\\int main(int argc, char **argv) {
|
||||
\\ short q = 3;
|
||||
\\ signed char z0 = q?:1;
|
||||
\\ assert(z0 == 3);
|
||||
\\ int z1 = 3?:1;
|
||||
\\ assert(z1 == 3);
|
||||
\\ int z2 = foo()?:-1;
|
||||
\\ assert(z2 == 42);
|
||||
\\ assert(cnt == 1);
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("boolean values and expressions",
|
||||
\\#include <stdlib.h>
|
||||
\\static const _Bool false_val = 0;
|
||||
@ -12,6 +29,7 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
|
||||
\\ if (!r) abort();
|
||||
\\ _Bool self = foo;
|
||||
\\ if (self == false_val) abort();
|
||||
\\ if (((r) ? 'a' : 'b') != 'a') abort();
|
||||
\\}
|
||||
\\int main(int argc, char **argv) {
|
||||
\\ foo(2, 5);
|
||||
|
||||
@ -2530,10 +2530,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
, &[_][]const u8{
|
||||
\\pub export fn foo(arg_x: bool) bool {
|
||||
\\ var x = arg_x;
|
||||
\\ var a: bool = (@boolToInt(x) != @as(c_int, 1));
|
||||
\\ var b: bool = (@boolToInt(a) != @as(c_int, 0));
|
||||
\\ var a: bool = (@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(x)))) != @as(c_int, 1));
|
||||
\\ var b: bool = (@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(a)))) != @as(c_int, 0));
|
||||
\\ var c: bool = @ptrToInt(foo) != 0;
|
||||
\\ return foo((@boolToInt(c) != @boolToInt(b)));
|
||||
\\ return foo((@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(c)))) != @intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(b))))));
|
||||
\\}
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user