diff options
Diffstat (limited to 'libbindgen/src/codegen/helpers.rs')
-rw-r--r-- | libbindgen/src/codegen/helpers.rs | 190 |
1 files changed, 0 insertions, 190 deletions
diff --git a/libbindgen/src/codegen/helpers.rs b/libbindgen/src/codegen/helpers.rs deleted file mode 100644 index 06dadab0..00000000 --- a/libbindgen/src/codegen/helpers.rs +++ /dev/null @@ -1,190 +0,0 @@ -//! Helpers for code generation that don't need macro expansion. - -use aster; -use ir::layout::Layout; -use syntax::ast; -use syntax::ptr::P; - - -pub mod attributes { - use aster; - use syntax::ast; - - pub fn repr(which: &str) -> ast::Attribute { - aster::AstBuilder::new().attr().list("repr").words(&[which]).build() - } - - pub fn repr_list(which_ones: &[&str]) -> ast::Attribute { - aster::AstBuilder::new().attr().list("repr").words(which_ones).build() - } - - pub fn derives(which_ones: &[&str]) -> ast::Attribute { - aster::AstBuilder::new().attr().list("derive").words(which_ones).build() - } - - pub fn inline() -> ast::Attribute { - aster::AstBuilder::new().attr().word("inline") - } - - pub fn doc(comment: &str) -> ast::Attribute { - aster::AstBuilder::new().attr().doc(comment) - } - - pub fn link_name(name: &str) -> ast::Attribute { - aster::AstBuilder::new().attr().name_value("link_name").str(name) - } -} - -/// Generates a proper type for a field or type with a given `Layout`, that is, -/// a type with the correct size and alignment restrictions. -pub struct BlobTyBuilder { - layout: Layout, -} - -impl BlobTyBuilder { - pub fn new(layout: Layout) -> Self { - BlobTyBuilder { - layout: layout, - } - } - - pub fn build(self) -> P<ast::Ty> { - let opaque = self.layout.opaque(); - - // FIXME(emilio, #412): We fall back to byte alignment, but there are - // some things that legitimately are more than 8-byte aligned. - // - // Eventually we should be able to `unwrap` here, but... - let ty_name = match opaque.known_rust_type_for_array() { - Some(ty) => ty, - None => { - warn!("Found unknown alignment on code generation!"); - "u8" - } - }; - - let data_len = opaque.array_size().unwrap_or(self.layout.size); - - let inner_ty = aster::AstBuilder::new().ty().path().id(ty_name).build(); - if data_len == 1 { - inner_ty - } else { - aster::ty::TyBuilder::new().array(data_len).build(inner_ty) - } - } -} - -pub mod ast_ty { - use aster; - use ir::context::BindgenContext; - use ir::function::FunctionSig; - use ir::ty::FloatKind; - use syntax::ast; - use syntax::ptr::P; - - pub fn raw_type(ctx: &BindgenContext, name: &str) -> P<ast::Ty> { - let ident = ctx.rust_ident_raw(&name); - match ctx.options().ctypes_prefix { - Some(ref prefix) => { - let prefix = ctx.rust_ident_raw(prefix); - quote_ty!(ctx.ext_cx(), $prefix::$ident) - } - None => quote_ty!(ctx.ext_cx(), ::std::os::raw::$ident), - } - } - - pub fn float_kind_rust_type(ctx: &BindgenContext, - fk: FloatKind) - -> P<ast::Ty> { - // TODO: we probably should just take the type layout into - // account? - // - // Also, maybe this one shouldn't be the default? - // - // FIXME: `c_longdouble` doesn't seem to be defined in some - // systems, so we use `c_double` directly. - match (fk, ctx.options().convert_floats) { - (FloatKind::Float, true) => aster::ty::TyBuilder::new().f32(), - (FloatKind::Double, true) | - (FloatKind::LongDouble, true) => aster::ty::TyBuilder::new().f64(), - (FloatKind::Float, false) => raw_type(ctx, "c_float"), - (FloatKind::Double, false) | - (FloatKind::LongDouble, false) => raw_type(ctx, "c_double"), - (FloatKind::Float128, _) => { - aster::ty::TyBuilder::new().array(16).u8() - } - } - } - - pub fn int_expr(val: i64) -> P<ast::Expr> { - use std::i64; - let expr = aster::AstBuilder::new().expr(); - - // This is not representable as an i64 if it's negative, so we - // special-case it. - // - // Fix in aster incoming. - if val == i64::MIN { - expr.neg().uint(1u64 << 63) - } else { - expr.int(val) - } - } - - pub fn bool_expr(val: bool) -> P<ast::Expr> { - aster::AstBuilder::new().expr().bool(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::symbol::ToSymbol; - 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()); - aster::AstBuilder::new().expr().lit().build_lit(kind) - } - - pub fn arguments_from_signature(signature: &FunctionSig, - ctx: &BindgenContext) - -> Vec<P<ast::Expr>> { - // TODO: We need to keep in sync the argument names, so we should unify - // this with the other loop that decides them. - let mut unnamed_arguments = 0; - signature.argument_types() - .iter() - .map(|&(ref name, _ty)| { - let arg_name = match *name { - Some(ref name) => ctx.rust_mangle(name).into_owned(), - None => { - unnamed_arguments += 1; - format!("arg{}", unnamed_arguments) - } - }; - aster::expr::ExprBuilder::new().id(arg_name) - }) - .collect::<Vec<_>>() - } -} |