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.rs99
1 files changed, 68 insertions, 31 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 95162204..e62b1a87 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -422,37 +422,36 @@ trait CodeGenerator {
/// Extra information from the caller.
type Extra;
+ /// Extra information returned to the caller.
+ type Return;
+
fn codegen<'a>(
&self,
ctx: &BindgenContext,
result: &mut CodegenResult<'a>,
extra: &Self::Extra,
- );
+ ) -> Self::Return;
}
-impl CodeGenerator for Item {
- type Extra = ();
-
- fn codegen<'a>(
+impl Item {
+ fn process_before_codegen(
&self,
ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- _extra: &(),
- ) {
+ result: &mut CodegenResult,
+ ) -> bool {
if !self.is_enabled_for_codegen(ctx) {
- return;
+ return false;
}
if self.is_blocklisted(ctx) || result.seen(self.id()) {
debug!(
- "<Item as CodeGenerator>::codegen: Ignoring hidden or seen: \
+ "<Item as CodeGenerator>::process_before_codegen: Ignoring hidden or seen: \
self = {:?}",
self
);
- return;
+ return false;
}
- debug!("<Item as CodeGenerator>::codegen: self = {:?}", self);
if !ctx.codegen_items().contains(&self.id()) {
// TODO(emilio, #453): Figure out what to do when this happens
// legitimately, we could track the opaque stuff and disable the
@@ -461,6 +460,24 @@ impl CodeGenerator for Item {
}
result.set_seen(self.id());
+ true
+ }
+}
+
+impl CodeGenerator for Item {
+ type Extra = ();
+ type Return = ();
+
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ _extra: &(),
+ ) {
+ debug!("<Item as CodeGenerator>::codegen: self = {:?}", self);
+ if !self.process_before_codegen(ctx, result) {
+ return;
+ }
match *self.kind() {
ItemKind::Module(ref module) => {
@@ -481,6 +498,7 @@ impl CodeGenerator for Item {
impl CodeGenerator for Module {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -572,6 +590,8 @@ impl CodeGenerator for Module {
impl CodeGenerator for Var {
type Extra = Item;
+ type Return = ();
+
fn codegen<'a>(
&self,
ctx: &BindgenContext,
@@ -698,6 +718,7 @@ impl CodeGenerator for Var {
impl CodeGenerator for Type {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -1004,6 +1025,7 @@ impl<'a> Vtable<'a> {
impl<'a> CodeGenerator for Vtable<'a> {
type Extra = Item;
+ type Return = ();
fn codegen<'b>(
&self,
@@ -1048,6 +1070,7 @@ impl<'a> TryToRustTy for Vtable<'a> {
impl CodeGenerator for TemplateInstantiation {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -1664,6 +1687,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
impl CodeGenerator for CompInfo {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -2261,13 +2285,15 @@ impl MethodCodegen for Method {
// First of all, output the actual function.
let function_item = ctx.resolve_item(self.signature());
- if function_item.is_blocklisted(ctx) {
- // We shouldn't emit a method declaration if the function is blocklisted
+ if !function_item.process_before_codegen(ctx, result) {
return;
}
- function_item.codegen(ctx, result, &());
-
let function = function_item.expect_function();
+ let times_seen = function.codegen(ctx, result, &function_item);
+ let times_seen = match times_seen {
+ Some(seen) => seen,
+ None => return,
+ };
let signature_item = ctx.resolve_item(function.signature());
let mut name = match self.kind() {
MethodKind::Constructor => "new".into(),
@@ -2302,7 +2328,11 @@ impl MethodCodegen for Method {
name.push_str(&count.to_string());
}
- let function_name = ctx.rust_ident(function_item.canonical_name(ctx));
+ let mut function_name = function_item.canonical_name(ctx);
+ if times_seen > 0 {
+ write!(&mut function_name, "{}", times_seen).unwrap();
+ }
+ let function_name = ctx.rust_ident(function_name);
let mut args = utils::fnsig_arguments(ctx, signature);
let mut ret = utils::fnsig_return_ty(ctx, signature);
@@ -2808,6 +2838,7 @@ impl<'a> EnumBuilder<'a> {
impl CodeGenerator for Enum {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -3731,19 +3762,23 @@ impl TryToRustTy for FunctionSig {
impl CodeGenerator for Function {
type Extra = Item;
+ /// If we've actually generated the symbol, the number of times we've seen
+ /// it.
+ type Return = Option<u32>;
+
fn codegen<'a>(
&self,
ctx: &BindgenContext,
result: &mut CodegenResult<'a>,
item: &Item,
- ) {
+ ) -> Self::Return {
debug!("<Function as CodeGenerator>::codegen: item = {:?}", item);
debug_assert!(item.is_enabled_for_codegen(ctx));
// We can't currently do anything with Internal functions so just
// avoid generating anything for them.
match self.linkage() {
- Linkage::Internal => return,
+ Linkage::Internal => return None,
Linkage::External => {}
}
@@ -3753,7 +3788,7 @@ impl CodeGenerator for Function {
FunctionKind::Method(ref method_kind)
if method_kind.is_pure_virtual() =>
{
- return;
+ return None;
}
_ => {}
}
@@ -3763,7 +3798,7 @@ impl CodeGenerator for Function {
// instantiations is open ended and we have no way of knowing which
// monomorphizations actually exist.
if !item.all_template_params(ctx).is_empty() {
- return;
+ return None;
}
let name = self.name();
@@ -3776,7 +3811,7 @@ impl CodeGenerator for Function {
// TODO: Maybe warn here if there's a type/argument mismatch, or
// something?
if result.seen_function(seen_symbol_name) {
- return;
+ return None;
}
result.saw_function(seen_symbol_name);
}
@@ -3803,21 +3838,14 @@ impl CodeGenerator for Function {
attributes.push(attributes::doc(comment));
}
- // Handle overloaded functions by giving each overload its own unique
- // suffix.
- let times_seen = result.overload_number(&canonical_name);
- if times_seen > 0 {
- write!(&mut canonical_name, "{}", times_seen).unwrap();
- }
-
let abi = match signature.abi() {
Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => {
warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target");
- return;
+ return None;
}
Abi::Win64 if signature.is_variadic() => {
warn!("Skipping variadic function with Win64 ABI that isn't supported");
- return;
+ return None;
}
Abi::Unknown(unknown_abi) => {
panic!(
@@ -3828,6 +3856,13 @@ impl CodeGenerator for Function {
abi => abi,
};
+ // Handle overloaded functions by giving each overload its own unique
+ // suffix.
+ let times_seen = result.overload_number(&canonical_name);
+ if times_seen > 0 {
+ write!(&mut canonical_name, "{}", times_seen).unwrap();
+ }
+
let link_name = mangled_name.unwrap_or(name);
if !utils::names_will_be_identical_after_mangling(
&canonical_name,
@@ -3878,6 +3913,7 @@ impl CodeGenerator for Function {
} else {
result.push(tokens);
}
+ Some(times_seen)
}
}
@@ -3933,6 +3969,7 @@ fn objc_method_codegen(
impl CodeGenerator for ObjCInterface {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,