@@ -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
}
@@ -1803,14 +1820,19 @@ impl CodeGenerator for Function {
1803
1820
result : & mut CodegenResult ,
1804
1821
item : & Item ) {
1805
1822
let name = self . name ( ) ;
1806
- let canonical_name = item. canonical_name ( ctx) ;
1823
+ let mut canonical_name = item. canonical_name ( ctx) ;
1824
+ let mangled_name = self . mangled_name ( ) ;
1807
1825
1808
- // TODO: Maybe warn here if there's a type/argument mismatch, or
1809
- // something?
1810
- if result. seen_function ( & canonical_name) {
1811
- return ;
1826
+ {
1827
+ let seen_symbol_name = mangled_name. unwrap_or ( & canonical_name) ;
1828
+
1829
+ // TODO: Maybe warn here if there's a type/argument mismatch, or
1830
+ // something?
1831
+ if result. seen_function ( seen_symbol_name) {
1832
+ return ;
1833
+ }
1834
+ result. saw_function ( seen_symbol_name) ;
1812
1835
}
1813
- result. saw_function ( & canonical_name) ;
1814
1836
1815
1837
let signature_item = ctx. resolve_item ( self . signature ( ) ) ;
1816
1838
let signature = signature_item. kind ( ) . expect_type ( ) ;
@@ -1827,7 +1849,7 @@ impl CodeGenerator for Function {
1827
1849
attributes. push ( attributes:: doc ( comment) ) ;
1828
1850
}
1829
1851
1830
- if let Some ( mangled) = self . mangled_name ( ) {
1852
+ if let Some ( mangled) = mangled_name {
1831
1853
attributes. push ( attributes:: link_name ( mangled) ) ;
1832
1854
} else if name != canonical_name {
1833
1855
attributes. push ( attributes:: link_name ( name) ) ;
@@ -1836,6 +1858,13 @@ impl CodeGenerator for Function {
1836
1858
let foreign_item_kind =
1837
1859
ast:: ForeignItemKind :: Fn ( fndecl, ast:: Generics :: default ( ) ) ;
1838
1860
1861
+ // Handle overloaded functions by giving each overload its own unique
1862
+ // suffix.
1863
+ let times_seen = result. overload_number ( & canonical_name) ;
1864
+ if times_seen > 0 {
1865
+ write ! ( & mut canonical_name, "{}" , times_seen) . unwrap ( ) ;
1866
+ }
1867
+
1839
1868
let foreign_item = ast:: ForeignItem {
1840
1869
ident : ctx. rust_ident_raw ( & canonical_name) ,
1841
1870
attrs : attributes,
0 commit comments