diff options
Diffstat (limited to 'libbindgen/src/codegen')
-rw-r--r-- | libbindgen/src/codegen/helpers.rs | 33 | ||||
-rw-r--r-- | libbindgen/src/codegen/mod.rs | 43 |
2 files changed, 72 insertions, 4 deletions
diff --git a/libbindgen/src/codegen/helpers.rs b/libbindgen/src/codegen/helpers.rs index 6e5a6f0e..8c3d3cea 100644 --- a/libbindgen/src/codegen/helpers.rs +++ b/libbindgen/src/codegen/helpers.rs @@ -132,4 +132,37 @@ pub mod ast_ty { expr.int(val) } } + + pub fn byte_array_expr(bytes: &[u8]) -> P<ast::Expr> { + let mut vec = Vec::with_capacity(bytes.len() + 1); + for byte in bytes { + vec.push(int_expr(*byte as i64)); + } + vec.push(int_expr(0)); + + let kind = ast::ExprKind::Vec(vec); + + aster::AstBuilder::new().expr().build_expr_kind(kind) + } + + pub fn cstr_expr(mut string: String) -> P<ast::Expr> { + string.push('\0'); + aster::AstBuilder::new() + .expr() + .build_lit(aster::AstBuilder::new().lit().byte_str(string)) + } + + pub fn float_expr(f: f64) -> P<ast::Expr> { + use aster::str::ToInternedString; + let mut string = f.to_string(); + + // So it gets properly recognised as a floating point constant. + if !string.contains('.') { + string.push('.'); + } + + let interned_str = string.as_str().to_interned_string(); + let kind = ast::LitKind::FloatUnsuffixed(interned_str); + aster::AstBuilder::new().expr().lit().build_lit(kind) + } } diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 99ec56f4..ceb023f7 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -304,6 +304,7 @@ impl CodeGenerator for Var { ctx: &BindgenContext, result: &mut CodegenResult, item: &Item) { + use ir::var::VarType; debug!("<Var as CodeGenerator>::codegen: item = {:?}", item); let canonical_name = item.canonical_name(ctx); @@ -320,10 +321,44 @@ impl CodeGenerator for Var { .item() .pub_() .const_(canonical_name) - .expr() - .build(helpers::ast_ty::int_expr(val)) - .build(ty); - result.push(const_item) + .expr(); + let item = match *val { + VarType::Int(val) => { + const_item.build(helpers::ast_ty::int_expr(val)) + .build(ty) + } + VarType::String(ref bytes) => { + // Account the trailing zero. + // + // TODO: Here we ignore the type we just made up, probably + // we should refactor how the variable type and ty id work. + let len = bytes.len() + 1; + let ty = quote_ty!(ctx.ext_cx(), [u8; $len]); + + match String::from_utf8(bytes.clone()) { + Ok(string) => { + const_item.build(helpers::ast_ty::cstr_expr(string)) + .build(quote_ty!(ctx.ext_cx(), &'static $ty)) + } + Err(..) => { + const_item + .build(helpers::ast_ty::byte_array_expr(bytes)) + .build(ty) + } + } + } + VarType::Float(f) => { + const_item.build(helpers::ast_ty::float_expr(f)) + .build(ty) + } + VarType::Char(c) => { + const_item + .build(aster::AstBuilder::new().expr().lit().byte(c)) + .build(ty) + } + }; + + result.push(item); } else { let mut attrs = vec![]; if let Some(mangled) = self.mangled_name() { |