Skip to content

Commit bdfab64

Browse files
author
bors-servo
authored
Auto merge of #240 - fitzgen:overloads, r=emilio
Add support for bindings to overloaded functions This commit (re)adds support for generating bindings to overloaded functions. First, we use the symbol name instead of the canonical name when checking if we have already generated bindings for a given function. Second, we add a map from canonical names to number of times we have generated a function with that canonical name. We increment this number every time we generate a function. When the number is greater than zero, we append it to the function name so that overloaded functions get a unique Rust symbol. Fixes #239 r? @emilio
2 parents 87c25be + 5851026 commit bdfab64

File tree

3 files changed

+68
-7
lines changed

3 files changed

+68
-7
lines changed

src/codegen/mod.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use self::helpers::{BlobTyBuilder, attributes};
2121
use std::borrow::Cow;
2222
use std::collections::HashSet;
2323
use std::collections::hash_map::{Entry, HashMap};
24+
use std::fmt::Write;
2425
use std::mem;
2526
use std::ops;
2627
use syntax::abi::Abi;
@@ -57,6 +58,11 @@ struct CodegenResult {
5758
/// Being these two different declarations.
5859
functions_seen: HashSet<String>,
5960
vars_seen: HashSet<String>,
61+
62+
/// Used for making bindings to overloaded functions. Maps from a canonical
63+
/// function name to the number of overloads we have already codegen'd for
64+
/// that name. This lets us give each overload a unique suffix.
65+
overload_counters: HashMap<String, u32>,
6066
}
6167

6268
impl CodegenResult {
@@ -67,6 +73,7 @@ impl CodegenResult {
6773
items_seen: Default::default(),
6874
functions_seen: Default::default(),
6975
vars_seen: Default::default(),
76+
overload_counters: Default::default(),
7077
}
7178
}
7279

@@ -90,6 +97,16 @@ impl CodegenResult {
9097
self.functions_seen.insert(name.into());
9198
}
9299

100+
/// Get the overload number for the given function name. Increments the
101+
/// counter internally so the next time we ask for the overload for this
102+
/// name, we get the incremented value, and so on.
103+
fn overload_number(&mut self, name: &str) -> u32 {
104+
let mut counter = self.overload_counters.entry(name.into()).or_insert(0);
105+
let number = *counter;
106+
*counter += 1;
107+
number
108+
}
109+
93110
fn seen_var(&self, name: &str) -> bool {
94111
self.vars_seen.contains(name)
95112
}
@@ -1783,14 +1800,19 @@ impl CodeGenerator for Function {
17831800
result: &mut CodegenResult,
17841801
item: &Item) {
17851802
let name = self.name();
1786-
let canonical_name = item.canonical_name(ctx);
1803+
let mut canonical_name = item.canonical_name(ctx);
1804+
let mangled_name = self.mangled_name();
17871805

1788-
// TODO: Maybe warn here if there's a type/argument mismatch, or
1789-
// something?
1790-
if result.seen_function(&canonical_name) {
1791-
return;
1806+
{
1807+
let seen_symbol_name = mangled_name.unwrap_or(&canonical_name);
1808+
1809+
// TODO: Maybe warn here if there's a type/argument mismatch, or
1810+
// something?
1811+
if result.seen_function(seen_symbol_name) {
1812+
return;
1813+
}
1814+
result.saw_function(seen_symbol_name);
17921815
}
1793-
result.saw_function(&canonical_name);
17941816

17951817
let signature_item = ctx.resolve_item(self.signature());
17961818
let signature = signature_item.kind().expect_type();
@@ -1807,7 +1829,7 @@ impl CodeGenerator for Function {
18071829
attributes.push(attributes::doc(comment));
18081830
}
18091831

1810-
if let Some(mangled) = self.mangled_name() {
1832+
if let Some(mangled) = mangled_name {
18111833
attributes.push(attributes::link_name(mangled));
18121834
} else if name != canonical_name {
18131835
attributes.push(attributes::link_name(name));
@@ -1816,6 +1838,13 @@ impl CodeGenerator for Function {
18161838
let foreign_item_kind =
18171839
ast::ForeignItemKind::Fn(fndecl, ast::Generics::default());
18181840

1841+
// Handle overloaded functions by giving each overload its own unique
1842+
// suffix.
1843+
let times_seen = result.overload_number(&canonical_name);
1844+
if times_seen > 0 {
1845+
write!(&mut canonical_name, "{}", times_seen).unwrap();
1846+
}
1847+
18191848
let foreign_item = ast::ForeignItem {
18201849
ident: ctx.rust_ident_raw(&canonical_name),
18211850
attrs: attributes,
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(non_snake_case)]
5+
6+
7+
extern "C" {
8+
#[link_name = "_Z8Evaluatec"]
9+
pub fn Evaluate(r: ::std::os::raw::c_char) -> bool;
10+
}
11+
extern "C" {
12+
#[link_name = "_Z8Evaluateii"]
13+
pub fn Evaluate1(x: ::std::os::raw::c_int, y: ::std::os::raw::c_int)
14+
-> bool;
15+
}
16+
extern "C" {
17+
#[link_name = "_ZN3foo10MyFunctionEv"]
18+
pub fn MyFunction();
19+
}
20+
extern "C" {
21+
#[link_name = "_ZN3bar10MyFunctionEv"]
22+
pub fn MyFunction1();
23+
}

tests/headers/overloading.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extern bool Evaluate(char r);
2+
extern bool Evaluate(int x, int y);
3+
4+
namespace foo {
5+
extern void MyFunction();
6+
}
7+
namespace bar {
8+
extern void MyFunction();
9+
}

0 commit comments

Comments
 (0)