Commit daa22d42b0
Changed files (5)
src/zig_clang.cpp
@@ -2161,6 +2161,11 @@ unsigned ZigClangAPFloat_convertToHexString(const ZigClangAPFloat *self, char *D
return casted->convertToHexString(DST, HexDigits, UpperCase, (llvm::APFloat::roundingMode)RM);
}
+double ZigClangAPFloat_getValueAsApproximateDouble(const ZigClangFloatingLiteral *self) {
+ auto casted = reinterpret_cast<const clang::FloatingLiteral *>(self);
+ return casted->getValueAsApproximateDouble();
+}
+
enum ZigClangStringLiteral_StringKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self) {
auto casted = reinterpret_cast<const clang::StringLiteral *>(self);
return (ZigClangStringLiteral_StringKind)casted->getKind();
src/zig_clang.h
@@ -985,6 +985,7 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangDeclStmt_getBeginLoc(const st
ZIG_EXTERN_C unsigned ZigClangAPFloat_convertToHexString(const struct ZigClangAPFloat *self, char *DST,
unsigned HexDigits, bool UpperCase, enum ZigClangAPFloat_roundingMode RM);
+ZIG_EXTERN_C double ZigClangAPFloat_getValueAsApproximateDouble(const ZigClangFloatingLiteral *self);
ZIG_EXTERN_C enum ZigClangStringLiteral_StringKind ZigClangStringLiteral_getKind(const struct ZigClangStringLiteral *self);
ZIG_EXTERN_C const char *ZigClangStringLiteral_getString_bytes_begin_size(const struct ZigClangStringLiteral *self,
src-self-hosted/clang.zig
@@ -76,6 +76,7 @@ pub const struct_ZigClangFunctionType = @OpaqueType();
pub const struct_ZigClangPredefinedExpr = @OpaqueType();
pub const struct_ZigClangInitListExpr = @OpaqueType();
pub const ZigClangPreprocessingRecord = @OpaqueType();
+pub const ZigClangFloatingLiteral = @OpaqueType();
pub const ZigClangBO = extern enum {
PtrMemD,
@@ -1051,3 +1052,6 @@ pub extern fn ZigClangForStmt_getInit(*const ZigClangForStmt) ?*const ZigClangSt
pub extern fn ZigClangForStmt_getCond(*const ZigClangForStmt) ?*const ZigClangExpr;
pub extern fn ZigClangForStmt_getInc(*const ZigClangForStmt) ?*const ZigClangExpr;
pub extern fn ZigClangForStmt_getBody(*const ZigClangForStmt) *const ZigClangStmt;
+
+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;
src-self-hosted/translate_c.zig
@@ -632,6 +632,7 @@ fn transStmt(
.ContinueStmtClass => return try transCreateNodeContinue(rp.c),
.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),
else => {
return revertAndWarn(
rp,
@@ -896,16 +897,11 @@ fn transImplicitCastExpr(
const sub_expr = ZigClangImplicitCastExpr_getSubExpr(expr);
const sub_expr_node = try transExpr(rp, scope, @ptrCast(*const ZigClangExpr, sub_expr), .used, .r_value);
switch (ZigClangImplicitCastExpr_getCastKind(expr)) {
- .BitCast => {
+ .BitCast, .FloatingCast, .FloatingToIntegral, .IntegralToFloating, .IntegralCast => {
const dest_type = getExprQualType(c, @ptrCast(*const ZigClangExpr, expr));
const src_type = getExprQualType(c, sub_expr);
return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);
},
- .IntegralCast => {
- const dest_type = ZigClangExpr_getType(@ptrCast(*const ZigClangExpr, expr));
- const src_type = ZigClangExpr_getType(sub_expr);
- return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);
- },
.FunctionToPointerDecay, .ArrayToPointerDecay => {
return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
},
@@ -1057,6 +1053,30 @@ fn transCCast(
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
return &builtin_node.base;
}
+ if (cIsFloating(src_type) and cIsFloating(dst_type)) {
+ const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatCast");
+ try builtin_node.params.push(try transQualType(rp, dst_type, loc));
+ _ = try appendToken(rp.c, .Comma, ",");
+ try builtin_node.params.push(expr);
+ builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
+ return &builtin_node.base;
+ }
+ if (cIsFloating(src_type) and !cIsFloating(dst_type)) {
+ const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@floatToInt");
+ try builtin_node.params.push(try transQualType(rp, dst_type, loc));
+ _ = try appendToken(rp.c, .Comma, ",");
+ try builtin_node.params.push(expr);
+ builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
+ return &builtin_node.base;
+ }
+ if (!cIsFloating(src_type) and cIsFloating(dst_type)) {
+ const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToFloat");
+ try builtin_node.params.push(try transQualType(rp, dst_type, loc));
+ _ = try appendToken(rp.c, .Comma, ",");
+ try builtin_node.params.push(expr);
+ builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
+ return &builtin_node.base;
+ }
// TODO: maybe widen to increase size
// TODO: maybe bitcast to change sign
// TODO: maybe truncate to reduce size
@@ -1399,6 +1419,16 @@ fn transBreak(rp: RestorePoint, scope: *Scope) TransError!*ast.Node {
return &br.base;
}
+fn transFloatingLiteral(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangFloatingLiteral, used: ResultUsed) TransError!*ast.Node {
+ // TODO use something more accurate
+ const dbl = ZigClangAPFloat_getValueAsApproximateDouble(stmt);
+ const node = try rp.c.a().create(ast.Node.FloatLiteral);
+ node.* = .{
+ .token = try appendTokenFmt(rp.c, .FloatLiteral, "{d}", .{dbl}),
+ };
+ return maybeSuppressResult(rp, scope, used, &node.base);
+}
+
fn maybeSuppressResult(
rp: RestorePoint,
scope: *Scope,
@@ -1770,6 +1800,20 @@ fn cIsUnsignedInteger(qt: ZigClangQualType) bool {
};
}
+fn cIsFloating(qt: ZigClangQualType) bool {
+ const c_type = qualTypeCanon(qt);
+ if (ZigClangType_getTypeClass(c_type) != .Builtin) return false;
+ const builtin_ty = @ptrCast(*const ZigClangBuiltinType, c_type);
+ return switch (ZigClangBuiltinType_getKind(builtin_ty)) {
+ .Float,
+ .Double,
+ .Float128,
+ .LongDouble,
+ => true,
+ else => false,
+ };
+}
+
fn transCreateNodeAssign(
rp: RestorePoint,
scope: *Scope,
@@ -1964,7 +2008,7 @@ fn transCreateNodeAPInt(c: *Context, int: ?*const ZigClangAPSInt) !*ast.Node {
};
const token = try appendToken(c, .IntegerLiteral, str);
const node = try c.a().create(ast.Node.IntegerLiteral);
- node.* = ast.Node.IntegerLiteral{
+ node.* = .{
.token = token,
};
return &node.base;
@@ -2027,7 +2071,7 @@ fn transCreateNodeArrayInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.N
fn transCreateNodeInt(c: *Context, int: var) !*ast.Node {
const token = try appendTokenFmt(c, .IntegerLiteral, "{}", .{int});
const node = try c.a().create(ast.Node.IntegerLiteral);
- node.* = ast.Node.IntegerLiteral{
+ node.* = .{
.token = token,
};
return &node.base;
test/translate_c.zig
@@ -825,6 +825,18 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub export var _anyerror: c_uint = @as(c_uint, 2);
});
+ cases.add_2("floats",
+ \\float a = 3.1415;
+ \\double b = 3.1415;
+ \\int c = 3.1415;
+ \\double d = 3;
+ , &[_][]const u8{
+ \\pub export var a: f32 = @floatCast(f32, 3.1415);
+ \\pub export var b: f64 = 3.1415;
+ \\pub export var c: c_int = @floatToInt(c_int, 3.1415);
+ \\pub export var d: f64 = @intToFloat(f64, 3);
+ });
+
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
if (builtin.os != builtin.Os.windows) {