diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/codegen/helpers.rs | 35 | ||||
-rw-r--r-- | src/codegen/mod.rs | 10 | ||||
-rw-r--r-- | src/ir/var.rs | 6 |
3 files changed, 37 insertions, 14 deletions
diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index 811d87c5..608f3f9e 100644 --- a/src/codegen/helpers.rs +++ b/src/codegen/helpers.rs @@ -158,17 +158,38 @@ pub mod ast_ty { .build_lit(aster::AstBuilder::new().lit().byte_str(string)) } - pub fn float_expr(f: f64) -> P<ast::Expr> { + pub fn float_expr(ctx: &BindgenContext, + f: f64) + -> Result<P<ast::Expr>, ()> { use aster::symbol::ToSymbol; - let mut string = f.to_string(); - // So it gets properly recognised as a floating point constant. - if !string.contains('.') { - string.push('.'); + if f.is_finite() { + let mut string = f.to_string(); + + // So it gets properly recognised as a floating point constant. + if !string.contains('.') { + string.push('.'); + } + + let kind = ast::LitKind::FloatUnsuffixed(string.as_str().to_symbol()); + return Ok(aster::AstBuilder::new().expr().lit().build_lit(kind)) + } + + let prefix = ctx.trait_prefix(); + if f.is_nan() { + return Ok(quote_expr!(ctx.ext_cx(), ::$prefix::f64::NAN)); + } + + if f.is_infinite() { + return Ok(if f.is_sign_positive() { + quote_expr!(ctx.ext_cx(), ::$prefix::f64::INFINITY) + } else { + quote_expr!(ctx.ext_cx(), ::$prefix::f64::NEG_INFINITY) + }); } - let kind = ast::LitKind::FloatUnsuffixed(string.as_str().to_symbol()); - aster::AstBuilder::new().expr().lit().build_lit(kind) + warn!("Unknown non-finite float number: {:?}", f); + return Err(()); } pub fn arguments_from_signature(signature: &FunctionSig, diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 2e404a5c..17769144 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -470,8 +470,12 @@ impl CodeGenerator for Var { } } VarType::Float(f) => { - const_item.build(helpers::ast_ty::float_expr(f)) - .build(ty) + match helpers::ast_ty::float_expr(ctx, f) { + Ok(expr) => { + const_item.build(expr).build(ty) + } + Err(..) => return, + } } VarType::Char(c) => { const_item @@ -2419,7 +2423,7 @@ impl ToRustTy for TemplateInstantiation { .map(|(arg, _)| arg.to_rust_ty(ctx)) .collect::<Vec<_>>(); - path.segments.last_mut().unwrap().parameters = if + path.segments.last_mut().unwrap().parameters = if template_args.is_empty() { None } else { diff --git a/src/ir/var.rs b/src/ir/var.rs index 350bfe4a..2e56e9f5 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -146,7 +146,7 @@ impl ClangSubItemParser for Var { let (type_kind, val) = match value { EvalResult::Invalid => return Err(ParseError::Continue), EvalResult::Float(f) => { - (TypeKind::Float(FloatKind::Float), VarType::Float(f)) + (TypeKind::Float(FloatKind::Double), VarType::Float(f)) } EvalResult::Char(c) => { let c = match c { @@ -178,9 +178,7 @@ impl ClangSubItemParser for Var { } else { IntKind::Int } - } else if value > - u32::max_value() as - i64 { + } else if value > u32::max_value() as i64 { IntKind::ULongLong } else { IntKind::UInt |