@@ -71,6 +71,7 @@ state type crate_ctxt = rec(session.session sess,
71
71
hashmap[ str, ValueRef ] upcalls,
72
72
hashmap[ str, ValueRef ] intrinsics,
73
73
hashmap[ str, ValueRef ] item_names,
74
+ hashmap[ str, ValueRef ] native_fns,
74
75
hashmap[ ast. def_id , ValueRef ] item_ids,
75
76
hashmap[ ast. def_id , @ast. item ] items,
76
77
hashmap[ ast. def_id ,
@@ -5452,7 +5453,19 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
5452
5453
auto abi = ty. ty_fn_abi ( fn_type) ;
5453
5454
auto llfnty = type_of_native_fn ( cx, abi, ty. ty_fn_args ( fn_type) ,
5454
5455
ty. ty_fn_ret ( fn_type) , num_ty_param) ;
5455
- auto function = decl_cdecl_fn ( cx. llmod , name, llfnty) ;
5456
+
5457
+ // We can only declare a native function with a given name once; LLVM
5458
+ // unhelpfully mangles the names if we try to multiply declare one.
5459
+ auto function;
5460
+ if ( !cx. native_fns . contains_key ( name) ) {
5461
+ function = decl_cdecl_fn ( cx. llmod , name, llfnty) ;
5462
+ cx. native_fns . insert ( name, function) ;
5463
+ } else {
5464
+ // We support type-punning a native function by giving it different
5465
+ // Rust types.
5466
+ auto llorigfn = cx. native_fns . get ( name) ;
5467
+ function = bcx. build . PointerCast ( llorigfn, T_ptr ( llfnty) ) ;
5468
+ }
5456
5469
5457
5470
let vec[ ValueRef ] call_args = vec ( ) ;
5458
5471
auto arg_n = 3 u;
@@ -6200,6 +6213,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
6200
6213
upcalls = new_str_hash[ ValueRef ] ( ) ,
6201
6214
intrinsics = intrinsics,
6202
6215
item_names = new_str_hash[ ValueRef ] ( ) ,
6216
+ native_fns = new_str_hash[ ValueRef ] ( ) ,
6203
6217
item_ids = new_def_hash[ ValueRef ] ( ) ,
6204
6218
items = new_def_hash[ @ast. item ] ( ) ,
6205
6219
native_items = new_def_hash[ @ast. native_item ] ( ) ,
0 commit comments