diff options
author | Christian Poveda <christian.poveda@ferrous-systems.com> | 2022-09-23 21:36:14 -0500 |
---|---|---|
committer | Christian Poveda <christian.poveda@ferrous-systems.com> | 2022-10-04 20:47:17 -0500 |
commit | 0296f9e86c7756e718b6b82836ce1e09b5f8d08a (patch) | |
tree | b5954c6680b243c0b1671a80ea973ef90877e462 /src/codegen/helpers.rs | |
parent | a900f8f863d1313ad76603234aaeea22bb9ba7b3 (diff) |
split the repo into a workspace
remove `clap` dependency :tada:
update the book installation instructions
Diffstat (limited to 'src/codegen/helpers.rs')
-rw-r--r-- | src/codegen/helpers.rs | 309 |
1 files changed, 0 insertions, 309 deletions
diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs deleted file mode 100644 index 5bf36acb..00000000 --- a/src/codegen/helpers.rs +++ /dev/null @@ -1,309 +0,0 @@ -//! Helpers for code generation that don't need macro expansion. - -use crate::ir::context::BindgenContext; -use crate::ir::layout::Layout; -use proc_macro2::{Ident, Span, TokenStream}; -use quote::TokenStreamExt; - -pub mod attributes { - use proc_macro2::{Ident, Span, TokenStream}; - use std::str::FromStr; - - pub fn repr(which: &str) -> TokenStream { - let which = Ident::new(which, Span::call_site()); - quote! { - #[repr( #which )] - } - } - - pub fn repr_list(which_ones: &[&str]) -> TokenStream { - let which_ones = which_ones - .iter() - .cloned() - .map(|one| TokenStream::from_str(one).expect("repr to be valid")); - quote! { - #[repr( #( #which_ones ),* )] - } - } - - pub fn derives(which_ones: &[&str]) -> TokenStream { - let which_ones = which_ones - .iter() - .cloned() - .map(|one| TokenStream::from_str(one).expect("derive to be valid")); - quote! { - #[derive( #( #which_ones ),* )] - } - } - - pub fn inline() -> TokenStream { - quote! { - #[inline] - } - } - - pub fn must_use() -> TokenStream { - quote! { - #[must_use] - } - } - - pub fn non_exhaustive() -> TokenStream { - quote! { - #[non_exhaustive] - } - } - - pub fn doc(comment: String) -> TokenStream { - // NOTE(emilio): By this point comments are already preprocessed and in - // `///` form. Quote turns them into `#[doc]` comments, but oh well. - TokenStream::from_str(&comment).unwrap() - } - - pub fn link_name(name: &str) -> TokenStream { - // LLVM mangles the name by default but it's already mangled. - // Prefixing the name with \u{1} should tell LLVM to not mangle it. - let name = format!("\u{1}{}", name); - quote! { - #[link_name = #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 fn blob(ctx: &BindgenContext, layout: Layout) -> TokenStream { - let opaque = 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(ctx) { - Some(ty) => ty, - None => { - warn!("Found unknown alignment on code generation!"); - "u8" - } - }; - - let ty_name = Ident::new(ty_name, Span::call_site()); - - let data_len = opaque.array_size(ctx).unwrap_or(layout.size); - - if data_len == 1 { - quote! { - #ty_name - } - } else { - quote! { - [ #ty_name ; #data_len ] - } - } -} - -/// Integer type of the same size as the given `Layout`. -pub fn integer_type( - ctx: &BindgenContext, - layout: Layout, -) -> Option<TokenStream> { - let name = Layout::known_type_for_size(ctx, layout.size)?; - let name = Ident::new(name, Span::call_site()); - Some(quote! { #name }) -} - -/// Generates a bitfield allocation unit type for a type with the given `Layout`. -pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> TokenStream { - let mut tokens = quote! {}; - - if ctx.options().enable_cxx_namespaces { - tokens.append_all(quote! { root:: }); - } - - let size = layout.size; - tokens.append_all(quote! { - __BindgenBitfieldUnit<[u8; #size]> - }); - - tokens -} - -pub mod ast_ty { - use crate::ir::context::BindgenContext; - use crate::ir::function::FunctionSig; - use crate::ir::layout::Layout; - use crate::ir::ty::FloatKind; - use proc_macro2::{self, TokenStream}; - use std::str::FromStr; - - pub fn c_void(ctx: &BindgenContext) -> TokenStream { - // ctypes_prefix takes precedence - match ctx.options().ctypes_prefix { - Some(ref prefix) => { - let prefix = TokenStream::from_str(prefix.as_str()).unwrap(); - quote! { - #prefix::c_void - } - } - None => { - if ctx.options().use_core && - ctx.options().rust_features.core_ffi_c_void - { - quote! { ::core::ffi::c_void } - } else { - quote! { ::std::os::raw::c_void } - } - } - } - } - - pub fn raw_type(ctx: &BindgenContext, name: &str) -> TokenStream { - let ident = ctx.rust_ident_raw(name); - match ctx.options().ctypes_prefix { - Some(ref prefix) => { - let prefix = TokenStream::from_str(prefix.as_str()).unwrap(); - quote! { - #prefix::#ident - } - } - None => { - if ctx.options().use_core && - ctx.options().rust_features().core_ffi_c - { - quote! { - ::core::ffi::#ident - } - } else { - quote! { - ::std::os::raw::#ident - } - } - } - } - } - - pub fn float_kind_rust_type( - ctx: &BindgenContext, - fk: FloatKind, - layout: Option<Layout>, - ) -> TokenStream { - // TODO: we probably should take the type layout into account more - // often? - // - // Also, maybe this one shouldn't be the default? - match (fk, ctx.options().convert_floats) { - (FloatKind::Float, true) => quote! { f32 }, - (FloatKind::Double, true) => quote! { f64 }, - (FloatKind::Float, false) => raw_type(ctx, "c_float"), - (FloatKind::Double, false) => raw_type(ctx, "c_double"), - (FloatKind::LongDouble, _) => { - match layout { - Some(layout) => { - match layout.size { - 4 => quote! { f32 }, - 8 => quote! { f64 }, - // TODO(emilio): If rust ever gains f128 we should - // use it here and below. - _ => super::integer_type(ctx, layout) - .unwrap_or(quote! { f64 }), - } - } - None => { - debug_assert!( - false, - "How didn't we know the layout for a primitive type?" - ); - quote! { f64 } - } - } - } - (FloatKind::Float128, _) => { - if ctx.options().rust_features.i128_and_u128 { - quote! { u128 } - } else { - quote! { [u64; 2] } - } - } - } - } - - pub fn int_expr(val: i64) -> TokenStream { - // Don't use quote! { #val } because that adds the type suffix. - let val = proc_macro2::Literal::i64_unsuffixed(val); - quote!(#val) - } - - pub fn uint_expr(val: u64) -> TokenStream { - // Don't use quote! { #val } because that adds the type suffix. - let val = proc_macro2::Literal::u64_unsuffixed(val); - quote!(#val) - } - - pub fn byte_array_expr(bytes: &[u8]) -> TokenStream { - let mut bytes: Vec<_> = bytes.to_vec(); - bytes.push(0); - quote! { [ #(#bytes),* ] } - } - - pub fn cstr_expr(mut string: String) -> TokenStream { - string.push('\0'); - let b = proc_macro2::Literal::byte_string(string.as_bytes()); - quote! { - #b - } - } - - pub fn float_expr(ctx: &BindgenContext, f: f64) -> Result<TokenStream, ()> { - if f.is_finite() { - let val = proc_macro2::Literal::f64_unsuffixed(f); - - return Ok(quote!(#val)); - } - - let prefix = ctx.trait_prefix(); - - if f.is_nan() { - return Ok(quote! { - ::#prefix::f64::NAN - }); - } - - if f.is_infinite() { - return Ok(if f.is_sign_positive() { - quote! { - ::#prefix::f64::INFINITY - } - } else { - quote! { - ::#prefix::f64::NEG_INFINITY - } - }); - } - - warn!("Unknown non-finite float number: {:?}", f); - Err(()) - } - - pub fn arguments_from_signature( - signature: &FunctionSig, - ctx: &BindgenContext, - ) -> Vec<TokenStream> { - let mut unnamed_arguments = 0; - signature - .argument_types() - .iter() - .map(|&(ref name, _ty)| match *name { - Some(ref name) => { - let name = ctx.rust_ident(name); - quote! { #name } - } - None => { - unnamed_arguments += 1; - let name = - ctx.rust_ident(format!("arg{}", unnamed_arguments)); - quote! { #name } - } - }) - .collect() - } -} |