translate-c-2 floats

This commit is contained in:
Vexu 2019-12-17 11:15:41 +02:00
parent 9cda93a24e
commit daa22d42b0
No known key found for this signature in database
GPG Key ID: 59AEB8936E16A6AC
5 changed files with 74 additions and 8 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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,

View File

@ -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) {