summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/codegen/mod.rs43
-rw-r--r--tests/expectations/tests/overloading.rs23
-rw-r--r--tests/headers/overloading.hpp9
3 files changed, 68 insertions, 7 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 3bee69b6..5ced46a1 100755
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -21,6 +21,7 @@ use self::helpers::{BlobTyBuilder, attributes};
use std::borrow::Cow;
use std::collections::HashSet;
use std::collections::hash_map::{Entry, HashMap};
+use std::fmt::Write;
use std::mem;
use std::ops;
use syntax::abi::Abi;
@@ -57,6 +58,11 @@ struct CodegenResult {
/// Being these two different declarations.
functions_seen: HashSet<String>,
vars_seen: HashSet<String>,
+
+ /// Used for making bindings to overloaded functions. Maps from a canonical
+ /// function name to the number of overloads we have already codegen'd for
+ /// that name. This lets us give each overload a unique suffix.
+ overload_counters: HashMap<String, u32>,
}
impl CodegenResult {
@@ -67,6 +73,7 @@ impl CodegenResult {
items_seen: Default::default(),
functions_seen: Default::default(),
vars_seen: Default::default(),
+ overload_counters: Default::default(),
}
}
@@ -90,6 +97,16 @@ impl CodegenResult {
self.functions_seen.insert(name.into());
}
+ /// Get the overload number for the given function name. Increments the
+ /// counter internally so the next time we ask for the overload for this
+ /// name, we get the incremented value, and so on.
+ fn overload_number(&mut self, name: &str) -> u32 {
+ let mut counter = self.overload_counters.entry(name.into()).or_insert(0);
+ let number = *counter;
+ *counter += 1;
+ number
+ }
+
fn seen_var(&self, name: &str) -> bool {
self.vars_seen.contains(name)
}
@@ -1803,14 +1820,19 @@ impl CodeGenerator for Function {
result: &mut CodegenResult,
item: &Item) {
let name = self.name();
- let canonical_name = item.canonical_name(ctx);
+ let mut canonical_name = item.canonical_name(ctx);
+ let mangled_name = self.mangled_name();
- // TODO: Maybe warn here if there's a type/argument mismatch, or
- // something?
- if result.seen_function(&canonical_name) {
- return;
+ {
+ let seen_symbol_name = mangled_name.unwrap_or(&canonical_name);
+
+ // TODO: Maybe warn here if there's a type/argument mismatch, or
+ // something?
+ if result.seen_function(seen_symbol_name) {
+ return;
+ }
+ result.saw_function(seen_symbol_name);
}
- result.saw_function(&canonical_name);
let signature_item = ctx.resolve_item(self.signature());
let signature = signature_item.kind().expect_type();
@@ -1827,7 +1849,7 @@ impl CodeGenerator for Function {
attributes.push(attributes::doc(comment));
}
- if let Some(mangled) = self.mangled_name() {
+ if let Some(mangled) = mangled_name {
attributes.push(attributes::link_name(mangled));
} else if name != canonical_name {
attributes.push(attributes::link_name(name));
@@ -1836,6 +1858,13 @@ impl CodeGenerator for Function {
let foreign_item_kind =
ast::ForeignItemKind::Fn(fndecl, ast::Generics::default());
+ // 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 foreign_item = ast::ForeignItem {
ident: ctx.rust_ident_raw(&canonical_name),
attrs: attributes,
diff --git a/tests/expectations/tests/overloading.rs b/tests/expectations/tests/overloading.rs
new file mode 100644
index 00000000..4e138e7d
--- /dev/null
+++ b/tests/expectations/tests/overloading.rs
@@ -0,0 +1,23 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(non_snake_case)]
+
+
+extern "C" {
+ #[link_name = "_Z8Evaluatec"]
+ pub fn Evaluate(r: ::std::os::raw::c_char) -> bool;
+}
+extern "C" {
+ #[link_name = "_Z8Evaluateii"]
+ pub fn Evaluate1(x: ::std::os::raw::c_int, y: ::std::os::raw::c_int)
+ -> bool;
+}
+extern "C" {
+ #[link_name = "_ZN3foo10MyFunctionEv"]
+ pub fn MyFunction();
+}
+extern "C" {
+ #[link_name = "_ZN3bar10MyFunctionEv"]
+ pub fn MyFunction1();
+}
diff --git a/tests/headers/overloading.hpp b/tests/headers/overloading.hpp
new file mode 100644
index 00000000..3c2b0487
--- /dev/null
+++ b/tests/headers/overloading.hpp
@@ -0,0 +1,9 @@
+extern bool Evaluate(char r);
+extern bool Evaluate(int x, int y);
+
+namespace foo {
+ extern void MyFunction();
+}
+namespace bar {
+ extern void MyFunction();
+}