@@ -174,6 +174,7 @@ impl<'self> Drop for StatRecorder<'self> {
174174 }
175175}
176176
177+ // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
177178pub fn decl_fn ( llmod : ModuleRef , name : & str , cc : lib:: llvm:: CallConv , ty : Type ) -> ValueRef {
178179 let llfn: ValueRef = do name. with_c_str |buf| {
179180 unsafe {
@@ -185,18 +186,12 @@ pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type)
185186 return llfn;
186187}
187188
189+ // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
188190pub fn decl_cdecl_fn ( llmod : ModuleRef , name : & str , ty : Type ) -> ValueRef {
189191 return decl_fn ( llmod, name, lib:: llvm:: CCallConv , ty) ;
190192}
191193
192- // Only use this if you are going to actually define the function. It's
193- // not valid to simply declare a function as internal.
194- pub fn decl_internal_cdecl_fn ( llmod : ModuleRef , name : & str , ty : Type ) -> ValueRef {
195- let llfn = decl_cdecl_fn ( llmod, name, ty) ;
196- lib:: llvm:: SetLinkage ( llfn, lib:: llvm:: InternalLinkage ) ;
197- return llfn;
198- }
199-
194+ // only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
200195pub fn get_extern_fn ( externs : & mut ExternMap , llmod : ModuleRef , name : & str ,
201196 cc : lib:: llvm:: CallConv , ty : Type ) -> ValueRef {
202197 match externs. find_equiv ( & name) {
@@ -205,7 +200,62 @@ pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: &str,
205200 }
206201 let f = decl_fn ( llmod, name, cc, ty) ;
207202 externs. insert ( name. to_owned ( ) , f) ;
208- return f;
203+ f
204+ }
205+
206+ pub fn get_extern_rust_fn ( ccx : & mut CrateContext , inputs : & [ ty:: t ] , output : ty:: t ,
207+ name : & str ) -> ValueRef {
208+ match ccx. externs . find_equiv ( & name) {
209+ Some ( n) => return * n,
210+ None => ( )
211+ }
212+ let f = decl_rust_fn ( ccx, inputs, output, name) ;
213+ ccx. externs . insert ( name. to_owned ( ) , f) ;
214+ f
215+ }
216+
217+ pub fn decl_rust_fn ( ccx : & mut CrateContext , inputs : & [ ty:: t ] , output : ty:: t ,
218+ name : & str ) -> ValueRef {
219+ let llfty = type_of_rust_fn ( ccx, inputs, output) ;
220+ let llfn = decl_cdecl_fn ( ccx. llmod , name, llfty) ;
221+
222+ match ty:: get ( output) . sty {
223+ // `~` pointer return values never alias because ownership is transferred
224+ ty:: ty_uniq( * ) |
225+ ty:: ty_evec( _, ty:: vstore_uniq) => {
226+ unsafe {
227+ llvm:: LLVMAddReturnAttribute ( llfn, lib:: llvm:: NoAliasAttribute as c_uint ) ;
228+ }
229+ }
230+ _ => ( )
231+ }
232+
233+ let uses_outptr = type_of:: return_uses_outptr ( ccx. tcx , output) ;
234+ let offset = if uses_outptr { 2 } else { 1 } ;
235+
236+ for ( i, & arg_ty) in inputs. iter ( ) . enumerate ( ) {
237+ let llarg = unsafe { llvm:: LLVMGetParam ( llfn, ( offset + i) as c_uint ) } ;
238+ match ty:: get ( arg_ty) . sty {
239+ // `~` pointer parameters never alias because ownership is transferred
240+ ty:: ty_uniq( * ) |
241+ ty:: ty_evec( _, ty:: vstore_uniq) |
242+ ty:: ty_closure( ty:: ClosureTy { sigil : ast:: OwnedSigil , _} ) => {
243+ unsafe {
244+ llvm:: LLVMAddAttribute ( llarg, lib:: llvm:: NoAliasAttribute as c_uint ) ;
245+ }
246+ }
247+ _ => ( )
248+ }
249+ }
250+
251+ llfn
252+ }
253+
254+ pub fn decl_internal_rust_fn ( ccx : & mut CrateContext , inputs : & [ ty:: t ] , output : ty:: t ,
255+ name : & str ) -> ValueRef {
256+ let llfn = decl_rust_fn ( ccx, inputs, output, name) ;
257+ lib:: llvm:: SetLinkage ( llfn, lib:: llvm:: InternalLinkage ) ;
258+ llfn
209259}
210260
211261pub fn get_extern_const ( externs : & mut ExternMap , llmod : ModuleRef ,
@@ -809,33 +859,30 @@ pub fn null_env_ptr(ccx: &CrateContext) -> ValueRef {
809859 C_null(Type::opaque_box(ccx).ptr_to())
810860}
811861
812- pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t)
813- -> ValueRef {
862+ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t) -> ValueRef {
814863 let name = csearch::get_symbol(ccx.sess.cstore, did);
815864 match ty::get(t).sty {
816865 ty::ty_bare_fn(ref fn_ty) => {
817- // Currently llvm_calling_convention triggers unimpl/bug on
818- // Rust/RustIntrinsic, so those two are handled specially here.
819- let cconv = match fn_ty.abis.for_arch (ccx.sess.targ_cfg.arch) {
820- Some(Rust) | Some(RustIntrinsic) => lib::llvm::CCallConv,
866+ match fn_ty.abis.for_arch(ccx.sess.targ_cfg.arch) {
867+ Some(Rust) | Some(RustIntrinsic) => {
868+ get_extern_rust_fn (ccx, fn_ty.sig.inputs, fn_ty.sig.output, name)
869+ }
821870 Some(*) | None => {
822871 let c = foreign::llvm_calling_convention(ccx, fn_ty.abis);
823- c.unwrap_or(lib::llvm::CCallConv)
872+ let cconv = c.unwrap_or(lib::llvm::CCallConv);
873+ let llty = type_of_fn_from_ty(ccx, t);
874+ get_extern_fn(&mut ccx.externs, ccx.llmod, name, cconv, llty)
824875 }
825- };
826- let llty = type_of_fn_from_ty(ccx, t);
827- return get_extern_fn(&mut ccx.externs, ccx.llmod, name, cconv, llty);
876+ }
828877 }
829- ty::ty_closure(_) => {
830- let llty = type_of_fn_from_ty(ccx, t);
831- return get_extern_fn(&mut ccx.externs, ccx.llmod, name,
832- lib::llvm::CCallConv, llty);
878+ ty::ty_closure(ref f) => {
879+ get_extern_rust_fn(ccx, f.sig.inputs, f.sig.output, name)
833880 }
834881 _ => {
835882 let llty = type_of(ccx, t);
836- return get_extern_const(&mut ccx.externs, ccx.llmod, name, llty);
883+ get_extern_const(&mut ccx.externs, ccx.llmod, name, llty)
837884 }
838- };
885+ }
839886}
840887
841888pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef],
@@ -1707,8 +1754,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext,
17071754// field of the fn_ctxt with
17081755pub fn create_llargs_for_fn_args ( cx : @mut FunctionContext ,
17091756 self_arg : self_arg ,
1710- args : & [ ast:: arg ] ,
1711- arg_tys : & [ ty:: t ] )
1757+ args : & [ ast:: arg ] )
17121758 -> ~[ ValueRef ] {
17131759 let _icx = push_ctxt ( "create_llargs_for_fn_args" ) ;
17141760
@@ -1726,23 +1772,7 @@ pub fn create_llargs_for_fn_args(cx: @mut FunctionContext,
17261772 // Return an array containing the ValueRefs that we get from
17271773 // llvm::LLVMGetParam for each argument.
17281774 do vec:: from_fn ( args. len ( ) ) |i| {
1729- let arg_n = cx. arg_pos ( i) ;
1730- let arg_ty = arg_tys[ i] ;
1731- let llarg = unsafe { llvm:: LLVMGetParam ( cx. llfn , arg_n as c_uint ) } ;
1732-
1733- match ty:: get ( arg_ty) . sty {
1734- // `~` pointer parameters never alias because ownership is transferred
1735- ty:: ty_uniq( * ) |
1736- ty:: ty_evec( _, ty:: vstore_uniq) |
1737- ty:: ty_closure( ty:: ClosureTy { sigil : ast:: OwnedSigil , _} ) => {
1738- unsafe {
1739- llvm:: LLVMAddAttribute ( llarg, lib:: llvm:: NoAliasAttribute as c_uint ) ;
1740- }
1741- }
1742- _ => ( )
1743- }
1744-
1745- llarg
1775+ unsafe { llvm:: LLVMGetParam ( cx. llfn , cx. arg_pos ( i) as c_uint ) }
17461776 }
17471777}
17481778
@@ -1896,8 +1926,7 @@ pub fn trans_closure(ccx: @mut CrateContext,
18961926
18971927 // Set up arguments to the function.
18981928 let arg_tys = ty:: ty_fn_args ( node_id_type ( bcx, id) ) ;
1899- let raw_llargs = create_llargs_for_fn_args ( fcx, self_arg,
1900- decl. inputs , arg_tys) ;
1929+ let raw_llargs = create_llargs_for_fn_args ( fcx, self_arg, decl. inputs ) ;
19011930
19021931 // Set the fixed stack segment flag if necessary.
19031932 if attr:: contains_name ( attributes, "fixed_stack_segment" ) {
@@ -1961,18 +1990,6 @@ pub fn trans_fn(ccx: @mut CrateContext,
19611990 param_substs. repr( ccx. tcx) ) ;
19621991 let _icx = push_ctxt ( "trans_fn" ) ;
19631992 let output_type = ty:: ty_fn_ret ( ty:: node_id_to_type ( ccx. tcx , id) ) ;
1964-
1965- match ty:: get ( output_type) . sty {
1966- // `~` pointer return values never alias because ownership is transferred
1967- ty:: ty_uniq( * ) |
1968- ty:: ty_evec( _, ty:: vstore_uniq) => {
1969- unsafe {
1970- llvm:: LLVMAddReturnAttribute ( llfndecl, lib:: llvm:: NoAliasAttribute as c_uint ) ;
1971- }
1972- }
1973- _ => ( )
1974- }
1975-
19761993 trans_closure ( ccx,
19771994 path. clone ( ) ,
19781995 decl,
@@ -2120,7 +2137,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
21202137
21212138 let arg_tys = ty:: ty_fn_args ( ctor_ty) ;
21222139
2123- let raw_llargs = create_llargs_for_fn_args ( fcx, no_self, fn_args, arg_tys ) ;
2140+ let raw_llargs = create_llargs_for_fn_args ( fcx, no_self, fn_args) ;
21242141
21252142 let bcx = fcx. entry_bcx . unwrap ( ) ;
21262143
@@ -2298,10 +2315,28 @@ pub fn register_fn(ccx: @mut CrateContext,
22982315 node_id : ast:: NodeId ,
22992316 node_type : ty:: t )
23002317 -> ValueRef {
2301- let llfty = type_of_fn_from_ty ( ccx, node_type) ;
2302- register_fn_llvmty ( ccx, sp, sym, node_id, lib:: llvm:: CCallConv , llfty)
2318+ let f = match ty:: get ( node_type) . sty {
2319+ ty:: ty_bare_fn( ref f) => {
2320+ assert ! ( f. abis. is_rust( ) || f. abis. is_intrinsic( ) ) ;
2321+ f
2322+ }
2323+ _ => fail ! ( "expected bare rust fn or an intrinsic" )
2324+ } ;
2325+
2326+ let llfn = decl_rust_fn ( ccx, f. sig . inputs , f. sig . output , sym) ;
2327+ ccx. item_symbols . insert ( node_id, sym) ;
2328+
2329+ // FIXME #4404 android JNI hacks
2330+ let is_entry = is_entry_fn ( & ccx. sess , node_id) && ( !* ccx. sess . building_library ||
2331+ ( * ccx. sess . building_library &&
2332+ ccx. sess . targ_cfg . os == session:: OsAndroid ) ) ;
2333+ if is_entry {
2334+ create_entry_wrapper ( ccx, sp, llfn) ;
2335+ }
2336+ llfn
23032337}
23042338
2339+ // only use this for foreign function ABIs and glue, use `register_fn` for Rust functions
23052340pub fn register_fn_llvmty ( ccx : @mut CrateContext ,
23062341 sp : Span ,
23072342 sym : ~str ,
0 commit comments