12
12
// pcwalton). You can, instead, find out its TypeRef by calling val_ty,
13
13
// but many TypeRefs correspond to one ty::t; for instance, tup(int, int,
14
14
// int) and rec(x=int, y=int, z=int) will have the same TypeRef.
15
- import std:: { str, uint, map, option, time, vec} ;
15
+ import std:: { either , str, uint, map, option, time, vec} ;
16
16
import std:: map:: hashmap;
17
17
import std:: map:: { new_int_hash, new_str_hash} ;
18
18
import std:: option:: { some, none} ;
@@ -182,7 +182,7 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
182
182
check returns_non_ty_var ( cx, t) ;
183
183
T_fn_pair ( cx, type_of_fn_from_ty ( cx, sp, t, 0 u) )
184
184
}
185
- ty:: ty_native_fn ( abi , args, out) {
185
+ ty:: ty_native_fn ( args, out) {
186
186
let nft = native_fn_wrapper_type ( cx, sp, 0 u, t) ;
187
187
T_fn_pair ( cx, nft)
188
188
}
@@ -235,7 +235,7 @@ fn type_of_ty_param_kinds_and_ty(lcx: @local_ctxt, sp: span,
235
235
let cx = lcx. ccx ;
236
236
let t = tpt. ty ;
237
237
alt ty:: struct ( cx. tcx , t) {
238
- ty:: ty_fn ( _, _, _, _, _) | ty:: ty_native_fn ( _, _, _ ) {
238
+ ty:: ty_fn ( _, _, _, _, _) | ty:: ty_native_fn ( _, _) {
239
239
check returns_non_ty_var ( cx, t) ;
240
240
ret type_of_fn_from_ty ( cx, sp, t, std:: vec:: len ( tpt. kinds ) ) ;
241
241
}
@@ -1727,7 +1727,7 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t,
1727
1727
}
1728
1728
ret next_cx;
1729
1729
}
1730
- ty:: ty_fn ( _, _, _, _, _) | ty:: ty_native_fn ( _, _, _ ) {
1730
+ ty:: ty_fn ( _, _, _, _, _) | ty:: ty_native_fn ( _, _) {
1731
1731
let box_cell_a = GEPi ( cx, av, [ 0 , abi:: fn_field_box] ) ;
1732
1732
ret iter_boxpp( cx, box_cell_a, f) ;
1733
1733
}
@@ -5305,7 +5305,7 @@ fn c_stack_tys(ccx: @crate_ctxt,
5305
5305
sp : span ,
5306
5306
id : ast:: node_id ) -> @c_stack_tys {
5307
5307
alt ty:: struct ( ccx. tcx , ty:: node_id_to_type ( ccx. tcx , id) ) {
5308
- ty:: ty_native_fn ( _ , arg_tys, ret_ty) {
5308
+ ty:: ty_native_fn ( arg_tys, ret_ty) {
5309
5309
let tcx = ccx. tcx ;
5310
5310
let llargtys = type_of_explicit_args ( ccx, sp, arg_tys) ;
5311
5311
check non_ty_var( ccx, ret_ty) ; // NDM does this truly hold?
@@ -5365,7 +5365,8 @@ fn c_stack_tys(ccx: @crate_ctxt,
5365
5365
// stack pointer appropriately to avoid a round of copies. (In fact, the shim
5366
5366
// function itself is unnecessary). We used to do this, in fact, and will
5367
5367
// perhaps do so in the future.
5368
- fn trans_native_mod ( lcx : @local_ctxt , native_mod : ast:: native_mod ) {
5368
+ fn trans_native_mod ( lcx : @local_ctxt , native_mod : ast:: native_mod ,
5369
+ abi : ast:: native_abi ) {
5369
5370
fn build_shim_fn ( lcx : @local_ctxt ,
5370
5371
native_item : @ast:: native_item ,
5371
5372
tys : @c_stack_tys ,
@@ -5448,7 +5449,7 @@ fn trans_native_mod(lcx: @local_ctxt, native_mod: ast::native_mod) {
5448
5449
5449
5450
let ccx = lcx_ccx ( lcx) ;
5450
5451
let cc: uint = lib:: llvm:: LLVMCCallConv ;
5451
- alt native_mod . abi {
5452
+ alt abi {
5452
5453
ast : : native_abi_rust_intrinsic. { ret; }
5453
5454
ast:: native_abi_cdecl. { cc = lib:: llvm:: LLVMCCallConv ; }
5454
5455
ast:: native_abi_stdcall. { cc = lib:: llvm:: LLVMX86StdcallCallConv ; }
@@ -5529,13 +5530,16 @@ fn trans_item(cx: @local_ctxt, item: ast::item) {
5529
5530
}
5530
5531
ast:: item_const ( _, expr) { trans_const ( cx. ccx , expr, item. id ) ; }
5531
5532
ast:: item_native_mod ( native_mod) {
5532
- trans_native_mod ( cx, native_mod) ;
5533
+ let abi = alt attr:: native_abi ( item. attrs ) {
5534
+ either:: right ( abi_) { abi_ }
5535
+ either:: left ( msg) { cx. ccx . sess . span_fatal ( item. span , msg) }
5536
+ } ;
5537
+ trans_native_mod ( cx, native_mod, abi) ;
5533
5538
}
5534
5539
_ { /* fall through */ }
5535
5540
}
5536
5541
}
5537
5542
5538
-
5539
5543
// Translate a module. Doing this amounts to translating the items in the
5540
5544
// module; there ends up being no artifact (aside from linkage names) of
5541
5545
// separate modules in the compiled program. That's because modules exist
@@ -5697,7 +5701,7 @@ fn native_fn_ty_param_count(cx: @crate_ctxt, id: ast::node_id) -> uint {
5697
5701
fn native_fn_wrapper_type ( cx : @crate_ctxt , sp : span , ty_param_count : uint ,
5698
5702
x : ty:: t ) -> TypeRef {
5699
5703
alt ty:: struct ( cx. tcx , x) {
5700
- ty:: ty_native_fn ( abi , args, out) {
5704
+ ty:: ty_native_fn ( args, out) {
5701
5705
check non_ty_var ( cx, out) ;
5702
5706
ret type_of_fn ( cx, sp, false , false , args, out, ty_param_count) ;
5703
5707
}
@@ -5719,18 +5723,32 @@ fn link_name(i: @ast::native_item) -> str {
5719
5723
}
5720
5724
}
5721
5725
5722
- fn collect_native_item ( ccx : @crate_ctxt , i : @ast:: native_item , & & pt: [ str ] ,
5726
+ fn collect_native_item ( ccx : @crate_ctxt ,
5727
+ abi : @mutable option:: t < ast:: native_abi > ,
5728
+ i : @ast:: native_item ,
5729
+ & & pt: [ str ] ,
5723
5730
_v : vt < [ str ] > ) {
5724
5731
alt i. node {
5725
5732
ast:: native_item_fn ( _, tps) {
5726
5733
if !ccx. obj_methods . contains_key ( i. id ) {
5727
5734
let sp = i. span ;
5728
5735
let id = i. id ;
5729
5736
let node_type = node_id_type ( ccx, id) ;
5730
- // FIXME NDM abi should come from attr
5731
- let abi = ty:: ty_fn_abi ( ccx. tcx , node_type) ;
5732
-
5733
- alt abi {
5737
+ let fn_abi =
5738
+ alt attr:: get_meta_item_value_str_by_name ( i. attrs , "abi" ) {
5739
+ option:: none. {
5740
+ // if abi isn't specified for this function, inherit from
5741
+ // its enclosing native module
5742
+ option:: get ( * abi)
5743
+ }
5744
+ _ {
5745
+ alt attr:: native_abi ( i. attrs ) {
5746
+ either:: right ( abi_) { abi_ }
5747
+ either:: left ( msg) { ccx. sess . span_fatal ( i. span , msg) }
5748
+ }
5749
+ }
5750
+ } ;
5751
+ alt fn_abi {
5734
5752
ast : : native_abi_rust_intrinsic. {
5735
5753
// For intrinsics: link the function directly to the intrinsic
5736
5754
// function itself.
@@ -5760,9 +5778,8 @@ fn collect_native_item(ccx: @crate_ctxt, i: @ast::native_item, &&pt: [str],
5760
5778
}
5761
5779
}
5762
5780
5763
- fn collect_item_1 ( ccx : @crate_ctxt , i : @ast:: item , & & pt: [ str ] ,
5764
- v : vt < [ str ] > ) {
5765
- visit:: visit_item ( i, pt + item_path ( i) , v) ;
5781
+ fn collect_item_1 ( ccx : @crate_ctxt , abi : @mutable option:: t < ast:: native_abi > ,
5782
+ i : @ast:: item , & & pt: [ str ] , v : vt < [ str ] > ) {
5766
5783
alt i. node {
5767
5784
ast:: item_const ( _, _) {
5768
5785
let typ = node_id_type ( ccx, i. id ) ;
@@ -5778,8 +5795,18 @@ fn collect_item_1(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
5778
5795
ccx. item_symbols . insert ( i. id , s) ;
5779
5796
ccx. consts . insert ( i. id , g) ;
5780
5797
}
5798
+ ast:: item_native_mod ( native_mod) {
5799
+ // Propagate the native ABI down to collect_native_item(),
5800
+ alt attr:: native_abi ( i. attrs ) {
5801
+ either:: left ( msg) { ccx. sess . span_fatal ( i. span , msg) ; }
5802
+ either:: right ( abi_) {
5803
+ * abi = option:: some ( abi_) ;
5804
+ }
5805
+ }
5806
+ }
5781
5807
_ { }
5782
5808
}
5809
+ visit:: visit_item ( i, pt + item_path ( i) , v) ;
5783
5810
}
5784
5811
5785
5812
fn collect_item_2 ( ccx : @crate_ctxt , i : @ast:: item , & & pt: [ str ] ,
@@ -5814,10 +5841,11 @@ fn collect_item_2(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
5814
5841
}
5815
5842
5816
5843
fn collect_items ( ccx : @crate_ctxt , crate : @ast:: crate ) {
5844
+ let abi = @mutable none :: < ast:: native_abi > ;
5817
5845
let visitor0 = visit:: default_visitor ( ) ;
5818
5846
let visitor1 =
5819
- @{ visit_native_item: bind collect_native_item ( ccx, _, _, _) ,
5820
- visit_item: bind collect_item_1 ( ccx, _, _, _) with * visitor0} ;
5847
+ @{ visit_native_item: bind collect_native_item ( ccx, abi , _, _, _) ,
5848
+ visit_item: bind collect_item_1 ( ccx, abi , _, _, _) with * visitor0} ;
5821
5849
let visitor2 =
5822
5850
@{ visit_item: bind collect_item_2 ( ccx, _, _, _) with * visitor0} ;
5823
5851
visit:: visit_crate ( * crate , [ ] , visit:: mk_vt ( visitor1) ) ;
0 commit comments