@@ -21,6 +21,7 @@ use self::helpers::{BlobTyBuilder, attributes};
21
21
use std:: borrow:: Cow ;
22
22
use std:: collections:: HashSet ;
23
23
use std:: collections:: hash_map:: { Entry , HashMap } ;
24
+ use std:: fmt:: Write ;
24
25
use std:: mem;
25
26
use std:: ops;
26
27
use syntax:: abi:: Abi ;
@@ -57,6 +58,11 @@ struct CodegenResult {
57
58
/// Being these two different declarations.
58
59
functions_seen : HashSet < String > ,
59
60
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 > ,
60
66
}
61
67
62
68
impl CodegenResult {
@@ -67,6 +73,7 @@ impl CodegenResult {
67
73
items_seen : Default :: default ( ) ,
68
74
functions_seen : Default :: default ( ) ,
69
75
vars_seen : Default :: default ( ) ,
76
+ overload_counters : Default :: default ( ) ,
70
77
}
71
78
}
72
79
@@ -90,6 +97,16 @@ impl CodegenResult {
90
97
self . functions_seen . insert ( name. into ( ) ) ;
91
98
}
92
99
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
+
93
110
fn seen_var ( & self , name : & str ) -> bool {
94
111
self . vars_seen . contains ( name)
95
112
}
@@ -1783,14 +1800,19 @@ impl CodeGenerator for Function {
1783
1800
result : & mut CodegenResult ,
1784
1801
item : & Item ) {
1785
1802
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 ( ) ;
1787
1805
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) ;
1792
1815
}
1793
- result. saw_function ( & canonical_name) ;
1794
1816
1795
1817
let signature_item = ctx. resolve_item ( self . signature ( ) ) ;
1796
1818
let signature = signature_item. kind ( ) . expect_type ( ) ;
@@ -1807,7 +1829,7 @@ impl CodeGenerator for Function {
1807
1829
attributes. push ( attributes:: doc ( comment) ) ;
1808
1830
}
1809
1831
1810
- if let Some ( mangled) = self . mangled_name ( ) {
1832
+ if let Some ( mangled) = mangled_name {
1811
1833
attributes. push ( attributes:: link_name ( mangled) ) ;
1812
1834
} else if name != canonical_name {
1813
1835
attributes. push ( attributes:: link_name ( name) ) ;
@@ -1816,6 +1838,13 @@ impl CodeGenerator for Function {
1816
1838
let foreign_item_kind =
1817
1839
ast:: ForeignItemKind :: Fn ( fndecl, ast:: Generics :: default ( ) ) ;
1818
1840
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
+
1819
1848
let foreign_item = ast:: ForeignItem {
1820
1849
ident : ctx. rust_ident_raw ( & canonical_name) ,
1821
1850
attrs : attributes,
0 commit comments