summaryrefslogtreecommitdiff
path: root/src/codegen/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen/mod.rs')
-rw-r--r--src/codegen/mod.rs80
1 files changed, 78 insertions, 2 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 91acf5b0..a62979b0 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -1,3 +1,4 @@
+mod dyngen;
mod error;
mod helpers;
mod impl_debug;
@@ -10,6 +11,7 @@ pub(crate) mod bitfield_unit;
#[cfg(all(test, target_endian = "little"))]
mod bitfield_unit_tests;
+use self::dyngen::DynamicItems;
use self::helpers::attributes;
use self::struct_layout::StructLayoutTracker;
@@ -184,6 +186,7 @@ impl From<DerivableTraits> for Vec<&'static str> {
struct CodegenResult<'a> {
items: Vec<proc_macro2::TokenStream>,
+ dynamic_items: DynamicItems,
/// A monotonic counter used to add stable unique id's to stuff that doesn't
/// need to be referenced by anything.
@@ -234,6 +237,7 @@ impl<'a> CodegenResult<'a> {
fn new(codegen_id: &'a Cell<usize>) -> Self {
CodegenResult {
items: vec![],
+ dynamic_items: DynamicItems::new(),
saw_bindgen_union: false,
saw_incomplete_array: false,
saw_objc: false,
@@ -247,6 +251,10 @@ impl<'a> CodegenResult<'a> {
}
}
+ fn dynamic_items(&mut self) -> &mut DynamicItems {
+ &mut self.dynamic_items
+ }
+
fn saw_bindgen_union(&mut self) {
self.saw_bindgen_union = true;
}
@@ -3785,7 +3793,29 @@ impl CodeGenerator for Function {
pub fn #ident ( #( #args ),* ) #ret;
}
};
- result.push(tokens);
+
+ // If we're doing dynamic binding generation, add to the dynamic items.
+ if ctx.options().dynamic_library_name.is_some() &&
+ self.kind() == FunctionKind::Function
+ {
+ let args_identifiers =
+ utils::fnsig_argument_identifiers(ctx, signature);
+ let return_item = ctx.resolve_item(signature.return_type());
+ let ret_ty = match *return_item.kind().expect_type().kind() {
+ TypeKind::Void => quote! {()},
+ _ => return_item.to_rust_ty_or_opaque(ctx, &()),
+ };
+ result.dynamic_items().add_function(
+ ident,
+ abi,
+ args,
+ args_identifiers,
+ ret,
+ ret_ty,
+ );
+ } else {
+ result.push(tokens);
+ }
}
}
@@ -4075,11 +4105,28 @@ pub(crate) fn codegen(
&(),
);
+ if context.options().dynamic_library_name.is_some() {
+ let lib_ident = context.rust_ident(
+ context.options().dynamic_library_name.as_ref().unwrap(),
+ );
+ let check_struct_ident = context.rust_ident(
+ [
+ "Check",
+ context.options().dynamic_library_name.as_ref().unwrap(),
+ ]
+ .join(""),
+ );
+ let dynamic_items_tokens = result
+ .dynamic_items()
+ .get_tokens(lib_ident, check_struct_ident);
+ result.push(dynamic_items_tokens);
+ }
+
result.items
})
}
-mod utils {
+pub mod utils {
use super::{error, ToRustTyOrOpaque};
use crate::ir::context::BindgenContext;
use crate::ir::function::{Abi, FunctionSig};
@@ -4484,6 +4531,35 @@ mod utils {
args
}
+ pub fn fnsig_argument_identifiers(
+ ctx: &BindgenContext,
+ sig: &FunctionSig,
+ ) -> Vec<proc_macro2::TokenStream> {
+ let mut unnamed_arguments = 0;
+ let args = sig
+ .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)
+ }
+ };
+
+ assert!(!arg_name.is_empty());
+ let arg_name = ctx.rust_ident(arg_name);
+
+ quote! {
+ #arg_name
+ }
+ })
+ .collect::<Vec<_>>();
+
+ args
+ }
+
pub fn fnsig_block(
ctx: &BindgenContext,
sig: &FunctionSig,