@@ -188,14 +188,6 @@ pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef {
188
188
return decl_fn ( llmod, name, lib:: llvm:: CCallConv , ty) ;
189
189
}
190
190
191
- // Only use this if you are going to actually define the function. It's
192
- // not valid to simply declare a function as internal.
193
- pub fn decl_internal_cdecl_fn ( llmod : ModuleRef , name : & str , ty : Type ) -> ValueRef {
194
- let llfn = decl_cdecl_fn ( llmod, name, ty) ;
195
- lib:: llvm:: SetLinkage ( llfn, lib:: llvm:: InternalLinkage ) ;
196
- return llfn;
197
- }
198
-
199
191
pub fn get_extern_fn ( externs : & mut ExternMap , llmod : ModuleRef , name : & str ,
200
192
cc : lib:: llvm:: CallConv , ty : Type ) -> ValueRef {
201
193
match externs. find_equiv ( & name) {
@@ -204,7 +196,62 @@ pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: &str,
204
196
}
205
197
let f = decl_fn ( llmod, name, cc, ty) ;
206
198
externs. insert ( name. to_owned ( ) , f) ;
207
- return f;
199
+ f
200
+ }
201
+
202
+ pub fn get_extern_rust_fn ( ccx : & mut CrateContext , inputs : & [ ty:: t ] , output : ty:: t ,
203
+ name : & str ) -> ValueRef {
204
+ match ccx. externs . find_equiv ( & name) {
205
+ Some ( n) => return * n,
206
+ None => ( )
207
+ }
208
+ let f = decl_rust_fn ( ccx, inputs, output, name) ;
209
+ ccx. externs . insert ( name. to_owned ( ) , f) ;
210
+ f
211
+ }
212
+
213
+ pub fn decl_rust_fn ( ccx : & mut CrateContext , inputs : & [ ty:: t ] , output : ty:: t ,
214
+ name : & str ) -> ValueRef {
215
+ let llfty = type_of_rust_fn ( ccx, inputs, output) ;
216
+ let llfn = decl_cdecl_fn ( ccx. llmod , name, llfty) ;
217
+
218
+ match ty:: get ( output) . sty {
219
+ // `~` pointer return values never alias because ownership is transferred
220
+ ty:: ty_uniq( * ) |
221
+ ty:: ty_evec( _, ty:: vstore_uniq) => {
222
+ unsafe {
223
+ llvm:: LLVMAddReturnAttribute ( llfn, lib:: llvm:: NoAliasAttribute as c_uint ) ;
224
+ }
225
+ }
226
+ _ => ( )
227
+ }
228
+
229
+ let uses_outptr = type_of:: return_uses_outptr ( ccx. tcx , output) ;
230
+ let offset = if uses_outptr { 2 } else { 1 } ;
231
+
232
+ for ( i, & arg_ty) in inputs. iter ( ) . enumerate ( ) {
233
+ let llarg = unsafe { llvm:: LLVMGetParam ( llfn, ( offset + i) as c_uint ) } ;
234
+ match ty:: get ( arg_ty) . sty {
235
+ // `~` pointer parameters never alias because ownership is transferred
236
+ ty:: ty_uniq( * ) |
237
+ ty:: ty_evec( _, ty:: vstore_uniq) |
238
+ ty:: ty_closure( ty:: ClosureTy { sigil : ast:: OwnedSigil , _} ) => {
239
+ unsafe {
240
+ llvm:: LLVMAddAttribute ( llarg, lib:: llvm:: NoAliasAttribute as c_uint ) ;
241
+ }
242
+ }
243
+ _ => ( )
244
+ }
245
+ }
246
+
247
+ llfn
248
+ }
249
+
250
+ pub fn decl_internal_rust_fn ( ccx : & mut CrateContext , inputs : & [ ty:: t ] , output : ty:: t ,
251
+ name : & str ) -> ValueRef {
252
+ let llfn = decl_rust_fn ( ccx, inputs, output, name) ;
253
+ lib:: llvm:: SetLinkage ( llfn, lib:: llvm:: InternalLinkage ) ;
254
+ llfn
208
255
}
209
256
210
257
pub fn get_extern_const ( externs : & mut ExternMap , llmod : ModuleRef ,
@@ -808,19 +855,25 @@ pub fn null_env_ptr(ccx: &CrateContext) -> ValueRef {
808
855
C_null(Type::opaque_box(ccx).ptr_to())
809
856
}
810
857
811
- pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t)
812
- -> ValueRef {
858
+ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t) -> ValueRef {
813
859
let name = csearch::get_symbol(ccx.sess.cstore, did);
814
860
match ty::get(t).sty {
815
- ty::ty_bare_fn(_) | ty::ty_closure(_) => {
816
- let llty = type_of_fn_from_ty(ccx, t);
817
- return get_extern_fn(&mut ccx.externs, ccx.llmod, name,
818
- lib::llvm::CCallConv, llty);
819
- }
820
- _ => {
821
- let llty = type_of(ccx, t);
822
- return get_extern_const(&mut ccx.externs, ccx.llmod, name, llty);
823
- }
861
+ ty::ty_bare_fn(ref f) => {
862
+ if f.abis.is_rust() || f.abis.is_intrinsic() {
863
+ return get_extern_rust_fn(ccx, f.sig.inputs, f.sig.output, name);
864
+ } else {
865
+ let llty = type_of_fn_from_ty(ccx, t);
866
+ return get_extern_fn(&mut ccx.externs, ccx.llmod, name,
867
+ lib::llvm::CCallConv, llty);
868
+ }
869
+ }
870
+ ty::ty_closure(ref f) => {
871
+ return get_extern_rust_fn(ccx, f.sig.inputs, f.sig.output, name);
872
+ }
873
+ _ => {
874
+ let llty = type_of(ccx, t);
875
+ return get_extern_const(&mut ccx.externs, ccx.llmod, name, llty);
876
+ }
824
877
};
825
878
}
826
879
@@ -1692,8 +1745,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext,
1692
1745
// field of the fn_ctxt with
1693
1746
pub fn create_llargs_for_fn_args ( cx : @mut FunctionContext ,
1694
1747
self_arg : self_arg ,
1695
- args : & [ ast:: arg ] ,
1696
- arg_tys : & [ ty:: t ] )
1748
+ args : & [ ast:: arg ] )
1697
1749
-> ~[ ValueRef ] {
1698
1750
let _icx = push_ctxt ( "create_llargs_for_fn_args" ) ;
1699
1751
@@ -1711,23 +1763,7 @@ pub fn create_llargs_for_fn_args(cx: @mut FunctionContext,
1711
1763
// Return an array containing the ValueRefs that we get from
1712
1764
// llvm::LLVMGetParam for each argument.
1713
1765
do vec:: from_fn ( args. len ( ) ) |i| {
1714
- let arg_n = cx. arg_pos ( i) ;
1715
- let arg_ty = arg_tys[ i] ;
1716
- let llarg = unsafe { llvm:: LLVMGetParam ( cx. llfn , arg_n as c_uint ) } ;
1717
-
1718
- match ty:: get ( arg_ty) . sty {
1719
- // `~` pointer parameters never alias because ownership is transferred
1720
- ty:: ty_uniq( * ) |
1721
- ty:: ty_evec( _, ty:: vstore_uniq) |
1722
- ty:: ty_closure( ty:: ClosureTy { sigil : ast:: OwnedSigil , _} ) => {
1723
- unsafe {
1724
- llvm:: LLVMAddAttribute ( llarg, lib:: llvm:: NoAliasAttribute as c_uint ) ;
1725
- }
1726
- }
1727
- _ => ( )
1728
- }
1729
-
1730
- llarg
1766
+ unsafe { llvm:: LLVMGetParam ( cx. llfn , cx. arg_pos ( i) as c_uint ) }
1731
1767
}
1732
1768
}
1733
1769
@@ -1881,8 +1917,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
1881
1917
1882
1918
// Set up arguments to the function.
1883
1919
let arg_tys = ty:: ty_fn_args ( node_id_type ( bcx, id) ) ;
1884
- let raw_llargs = create_llargs_for_fn_args ( fcx, self_arg,
1885
- decl. inputs , arg_tys) ;
1920
+ let raw_llargs = create_llargs_for_fn_args ( fcx, self_arg, decl. inputs ) ;
1886
1921
1887
1922
// Set the fixed stack segment flag if necessary.
1888
1923
if attr:: contains_name ( attributes, "fixed_stack_segment" ) {
@@ -1946,18 +1981,6 @@ pub fn trans_fn(ccx: @mut CrateContext,
1946
1981
param_substs. repr( ccx. tcx) ) ;
1947
1982
let _icx = push_ctxt ( "trans_fn" ) ;
1948
1983
let output_type = ty:: ty_fn_ret ( ty:: node_id_to_type ( ccx. tcx , id) ) ;
1949
-
1950
- match ty:: get ( output_type) . sty {
1951
- // `~` pointer return values never alias because ownership is transferred
1952
- ty:: ty_uniq( * ) |
1953
- ty:: ty_evec( _, ty:: vstore_uniq) => {
1954
- unsafe {
1955
- llvm:: LLVMAddReturnAttribute ( llfndecl, lib:: llvm:: NoAliasAttribute as c_uint ) ;
1956
- }
1957
- }
1958
- _ => ( )
1959
- }
1960
-
1961
1984
trans_closure ( ccx,
1962
1985
path. clone ( ) ,
1963
1986
decl,
@@ -2105,7 +2128,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
2105
2128
2106
2129
let arg_tys = ty:: ty_fn_args ( ctor_ty) ;
2107
2130
2108
- let raw_llargs = create_llargs_for_fn_args ( fcx, no_self, fn_args, arg_tys ) ;
2131
+ let raw_llargs = create_llargs_for_fn_args ( fcx, no_self, fn_args) ;
2109
2132
2110
2133
let bcx = fcx. entry_bcx . unwrap ( ) ;
2111
2134
@@ -2275,8 +2298,25 @@ pub fn register_fn(ccx: @mut CrateContext,
2275
2298
node_id : ast:: NodeId ,
2276
2299
node_type : ty:: t )
2277
2300
-> ValueRef {
2278
- let llfty = type_of_fn_from_ty ( ccx, node_type) ;
2279
- register_fn_llvmty ( ccx, sp, sym, node_id, lib:: llvm:: CCallConv , llfty)
2301
+ let f = match ty:: get ( node_type) . sty {
2302
+ ty:: ty_bare_fn( ref f) => {
2303
+ assert ! ( f. abis. is_rust( ) || f. abis. is_intrinsic( ) ) ;
2304
+ f
2305
+ }
2306
+ _ => fail ! ( "expected bare rust fn or an intrinsic" )
2307
+ } ;
2308
+
2309
+ let llfn = decl_rust_fn ( ccx, f. sig . inputs , f. sig . output , sym) ;
2310
+ ccx. item_symbols . insert ( node_id, sym) ;
2311
+
2312
+ // FIXME #4404 android JNI hacks
2313
+ let is_entry = is_entry_fn ( & ccx. sess , node_id) && ( !* ccx. sess . building_library ||
2314
+ ( * ccx. sess . building_library &&
2315
+ ccx. sess . targ_cfg . os == session:: OsAndroid ) ) ;
2316
+ if is_entry {
2317
+ create_entry_wrapper ( ccx, sp, llfn) ;
2318
+ }
2319
+ llfn
2280
2320
}
2281
2321
2282
2322
pub fn register_fn_llvmty ( ccx : @mut CrateContext ,
0 commit comments