@@ -174,7 +174,6 @@ impl<'self> Drop for StatRecorder<'self> {
174
174
}
175
175
}
176
176
177
- // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
178
177
pub fn decl_fn ( llmod : ModuleRef , name : & str , cc : lib:: llvm:: CallConv , ty : Type ) -> ValueRef {
179
178
let llfn: ValueRef = do name. with_c_str |buf| {
180
179
unsafe {
@@ -186,12 +185,18 @@ pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type)
186
185
return llfn;
187
186
}
188
187
189
- // only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
190
188
pub fn decl_cdecl_fn ( llmod : ModuleRef , name : & str , ty : Type ) -> ValueRef {
191
189
return decl_fn ( llmod, name, lib:: llvm:: CCallConv , ty) ;
192
190
}
193
191
194
- // only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
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
+
195
200
pub fn get_extern_fn ( externs : & mut ExternMap , llmod : ModuleRef , name : & str ,
196
201
cc : lib:: llvm:: CallConv , ty : Type ) -> ValueRef {
197
202
match externs. find_equiv ( & name) {
@@ -200,73 +205,7 @@ pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: &str,
200
205
}
201
206
let f = decl_fn ( llmod, name, cc, ty) ;
202
207
externs. insert ( name. to_owned ( ) , 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
- // The out pointer will never alias with any other pointers, as the object only exists at a
252
- // language level after the call. It can also be tagged with SRet to indicate that it is
253
- // guaranteed to point to a usable block of memory for the type.
254
- if uses_outptr {
255
- unsafe {
256
- let outptr = llvm:: LLVMGetParam ( llfn, 0 ) ;
257
- llvm:: LLVMAddAttribute ( outptr, lib:: llvm:: StructRetAttribute as c_uint ) ;
258
- llvm:: LLVMAddAttribute ( outptr, lib:: llvm:: NoAliasAttribute as c_uint ) ;
259
- }
260
- }
261
-
262
- llfn
263
- }
264
-
265
- pub fn decl_internal_rust_fn ( ccx : & mut CrateContext , inputs : & [ ty:: t ] , output : ty:: t ,
266
- name : & str ) -> ValueRef {
267
- let llfn = decl_rust_fn ( ccx, inputs, output, name) ;
268
- lib:: llvm:: SetLinkage ( llfn, lib:: llvm:: InternalLinkage ) ;
269
- llfn
208
+ return f;
270
209
}
271
210
272
211
pub fn get_extern_const ( externs : & mut ExternMap , llmod : ModuleRef ,
@@ -870,30 +809,33 @@ pub fn null_env_ptr(ccx: &CrateContext) -> ValueRef {
870
809
C_null(Type::opaque_box(ccx).ptr_to())
871
810
}
872
811
873
- pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t) -> ValueRef {
812
+ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t)
813
+ -> ValueRef {
874
814
let name = csearch::get_symbol(ccx.sess.cstore, did);
875
815
match ty::get(t).sty {
876
816
ty::ty_bare_fn(ref fn_ty) => {
877
- match fn_ty.abis.for_arch(ccx.sess.targ_cfg.arch) {
878
- Some(Rust) | Some(RustIntrinsic) => {
879
- get_extern_rust_fn(ccx, fn_ty.sig.inputs, fn_ty.sig.output, name)
880
- }
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,
881
821
Some(*) | None => {
882
822
let c = foreign::llvm_calling_convention(ccx, fn_ty.abis);
883
- let cconv = c.unwrap_or(lib::llvm::CCallConv);
884
- let llty = type_of_fn_from_ty(ccx, t);
885
- get_extern_fn(&mut ccx.externs, ccx.llmod, name, cconv, llty)
823
+ c.unwrap_or(lib::llvm::CCallConv)
886
824
}
887
- }
825
+ };
826
+ let llty = type_of_fn_from_ty(ccx, t);
827
+ return get_extern_fn(&mut ccx.externs, ccx.llmod, name, cconv, llty);
888
828
}
889
- ty::ty_closure(ref f) => {
890
- get_extern_rust_fn(ccx, f.sig.inputs, f.sig.output, name)
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);
891
833
}
892
834
_ => {
893
835
let llty = type_of(ccx, t);
894
- get_extern_const(&mut ccx.externs, ccx.llmod, name, llty)
836
+ return get_extern_const(&mut ccx.externs, ccx.llmod, name, llty);
895
837
}
896
- }
838
+ };
897
839
}
898
840
899
841
pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef],
@@ -926,8 +868,7 @@ pub fn invoke(bcx: @mut Block, llfn: ValueRef, llargs: ~[ValueRef],
926
868
llfn,
927
869
llargs,
928
870
normal_bcx. llbb ,
929
- get_landing_pad ( bcx) ,
930
- attributes) ;
871
+ get_landing_pad ( bcx) ) ;
931
872
return ( llresult, normal_bcx) ;
932
873
} else {
933
874
unsafe {
@@ -1766,7 +1707,8 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext,
1766
1707
// field of the fn_ctxt with
1767
1708
pub fn create_llargs_for_fn_args ( cx : @mut FunctionContext ,
1768
1709
self_arg : self_arg ,
1769
- args : & [ ast:: arg ] )
1710
+ args : & [ ast:: arg ] ,
1711
+ arg_tys : & [ ty:: t ] )
1770
1712
-> ~[ ValueRef ] {
1771
1713
let _icx = push_ctxt ( "create_llargs_for_fn_args" ) ;
1772
1714
@@ -1784,7 +1726,23 @@ pub fn create_llargs_for_fn_args(cx: @mut FunctionContext,
1784
1726
// Return an array containing the ValueRefs that we get from
1785
1727
// llvm::LLVMGetParam for each argument.
1786
1728
do vec:: from_fn ( args. len ( ) ) |i| {
1787
- unsafe { llvm:: LLVMGetParam ( cx. llfn , cx. arg_pos ( i) as c_uint ) }
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
1788
1746
}
1789
1747
}
1790
1748
@@ -1938,7 +1896,8 @@ pub fn trans_closure(ccx: @mut CrateContext,
1938
1896
1939
1897
// Set up arguments to the function.
1940
1898
let arg_tys = ty:: ty_fn_args ( node_id_type ( bcx, id) ) ;
1941
- let raw_llargs = create_llargs_for_fn_args ( fcx, self_arg, decl. inputs ) ;
1899
+ let raw_llargs = create_llargs_for_fn_args ( fcx, self_arg,
1900
+ decl. inputs , arg_tys) ;
1942
1901
1943
1902
// Set the fixed stack segment flag if necessary.
1944
1903
if attr:: contains_name ( attributes, "fixed_stack_segment" ) {
@@ -2002,6 +1961,18 @@ pub fn trans_fn(ccx: @mut CrateContext,
2002
1961
param_substs. repr( ccx. tcx) ) ;
2003
1962
let _icx = push_ctxt ( "trans_fn" ) ;
2004
1963
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
+
2005
1976
trans_closure ( ccx,
2006
1977
path. clone ( ) ,
2007
1978
decl,
@@ -2149,7 +2120,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
2149
2120
2150
2121
let arg_tys = ty:: ty_fn_args ( ctor_ty) ;
2151
2122
2152
- let raw_llargs = create_llargs_for_fn_args ( fcx, no_self, fn_args) ;
2123
+ let raw_llargs = create_llargs_for_fn_args ( fcx, no_self, fn_args, arg_tys ) ;
2153
2124
2154
2125
let bcx = fcx. entry_bcx . unwrap ( ) ;
2155
2126
@@ -2327,28 +2298,10 @@ pub fn register_fn(ccx: @mut CrateContext,
2327
2298
node_id : ast:: NodeId ,
2328
2299
node_type : ty:: t )
2329
2300
-> ValueRef {
2330
- let f = match ty:: get ( node_type) . sty {
2331
- ty:: ty_bare_fn( ref f) => {
2332
- assert ! ( f. abis. is_rust( ) || f. abis. is_intrinsic( ) ) ;
2333
- f
2334
- }
2335
- _ => fail ! ( "expected bare rust fn or an intrinsic" )
2336
- } ;
2337
-
2338
- let llfn = decl_rust_fn ( ccx, f. sig . inputs , f. sig . output , sym) ;
2339
- ccx. item_symbols . insert ( node_id, sym) ;
2340
-
2341
- // FIXME #4404 android JNI hacks
2342
- let is_entry = is_entry_fn ( & ccx. sess , node_id) && ( !* ccx. sess . building_library ||
2343
- ( * ccx. sess . building_library &&
2344
- ccx. sess . targ_cfg . os == session:: OsAndroid ) ) ;
2345
- if is_entry {
2346
- create_entry_wrapper ( ccx, sp, llfn) ;
2347
- }
2348
- llfn
2301
+ let llfty = type_of_fn_from_ty ( ccx, node_type) ;
2302
+ register_fn_llvmty ( ccx, sp, sym, node_id, lib:: llvm:: CCallConv , llfty)
2349
2303
}
2350
2304
2351
- // only use this for foreign function ABIs and glue, use `register_fn` for Rust functions
2352
2305
pub fn register_fn_llvmty ( ccx : @mut CrateContext ,
2353
2306
sp : Span ,
2354
2307
sym : ~str ,
0 commit comments