1
+ // trans.rs: Translate the completed AST to the LLVM IR.
2
+ //
3
+ // Some functions here, such as trans_block and trans_expr, return a value --
4
+ // the result of the translation to LLVM -- while others, such as trans_fn,
5
+ // trans_obj, and trans_item, are called only for the side effect of adding a
6
+ // particular definition to the LLVM IR output we're producing.
7
+
1
8
import std:: int;
2
9
import std:: str;
3
10
import std:: uint;
@@ -130,8 +137,9 @@ type local_ctxt = rec(vec[str] path,
130
137
@crate_ctxt ccx ) ;
131
138
132
139
133
- // The type used for llself.
134
- type self_vt = rec ( ValueRef v, ty:: t t) ;
140
+ // Types used for llself.
141
+ type val_self_pair = rec ( ValueRef v, ty:: t t) ;
142
+ type ty_self_pair = tup ( TypeRef , ty:: t ) ;
135
143
136
144
// Function context. Every LLVM function we create will have one of these.
137
145
state type fn_ctxt = rec (
@@ -155,7 +163,7 @@ state type fn_ctxt = rec(
155
163
// function, due to LLVM's quirks.
156
164
157
165
// A block for all the function's allocas, so that LLVM will coalesce them
158
- // into a single alloca.
166
+ // into a single alloca call .
159
167
mutable BasicBlockRef llallocas ,
160
168
161
169
// A block containing code that copies incoming arguments to space already
@@ -174,7 +182,7 @@ state type fn_ctxt = rec(
174
182
// llallocas?
175
183
176
184
// The 'self' object currently in use in this function, if there is one.
177
- mutable option:: t[ self_vt ] llself ,
185
+ mutable option:: t[ val_self_pair ] llself ,
178
186
179
187
// If this function is actually a iter, a block containing the code called
180
188
// whenever the iter calls 'put'.
@@ -4668,9 +4676,9 @@ fn trans_lval(&@block_ctxt cx, &@ast::expr e) -> lval_result {
4668
4676
}
4669
4677
case ( ast:: expr_self_method ( ?ident, ?ann) ) {
4670
4678
alt ( cx. fcx . llself ) {
4671
- case ( some ( ?s_vt ) ) {
4672
- auto r = s_vt . v ;
4673
- auto t = s_vt . t ;
4679
+ case ( some ( ?pair ) ) {
4680
+ auto r = pair . v ;
4681
+ auto t = pair . t ;
4674
4682
ret trans_field ( cx, e. span , r, t, ident, ann) ;
4675
4683
}
4676
4684
case ( _) {
@@ -6694,7 +6702,7 @@ fn new_fn_ctxt(@local_ctxt cx, &span sp,
6694
6702
mutable llallocas=llbbs. _0 ,
6695
6703
mutable llcopyargs=llbbs. _1 ,
6696
6704
mutable llderivedtydescs=llbbs. _2 ,
6697
- mutable llself=none[ self_vt ] ,
6705
+ mutable llself=none[ val_self_pair ] ,
6698
6706
mutable lliterbody=none[ ValueRef ] ,
6699
6707
llargs=llargs,
6700
6708
llobjfields=llobjfields,
@@ -6713,18 +6721,28 @@ fn new_fn_ctxt(@local_ctxt cx, &span sp,
6713
6721
// - new_fn_ctxt
6714
6722
// - trans_args
6715
6723
6724
+ // create_llargs_for_fn_args: Creates a mapping from incoming arguments to
6725
+ // allocas created for them.
6726
+ //
6727
+ // When we translate a function, we need to map its incoming arguments to the
6728
+ // spaces that have been created for them (by code in the llallocas field of
6729
+ // the function's fn_ctxt). create_llargs_for_fn_args populates the llargs
6730
+ // field of the fn_ctxt with
6716
6731
fn create_llargs_for_fn_args( & @fn_ctxt cx ,
6717
6732
ast:: proto proto,
6718
- option:: t[ tup ( TypeRef , ty :: t ) ] ty_self ,
6733
+ option:: t[ ty_self_pair ] ty_self ,
6719
6734
ty:: t ret_ty ,
6720
6735
& vec[ ast:: arg ] args ,
6721
6736
& vec[ ast:: ty_param ] ty_params ) {
6722
6737
6738
+ // Skip the implicit arguments 0, 1, and 2. TODO: Pull out 3u and define
6739
+ // it as a constant, since we're using it in several places in trans this
6740
+ // way.
6723
6741
auto arg_n = 3 u;
6724
6742
6725
6743
alt ( ty_self) {
6726
6744
case ( some ( ?tt) ) {
6727
- cx. llself = some[ self_vt ] ( rec ( v = cx. llenv , t = tt. _1 ) ) ;
6745
+ cx. llself = some[ val_self_pair ] ( rec ( v = cx. llenv , t = tt. _1 ) ) ;
6728
6746
}
6729
6747
case ( none) {
6730
6748
auto i = 0 u;
@@ -6738,13 +6756,18 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
6738
6756
}
6739
6757
}
6740
6758
6759
+ // If the function is actually an iter, populate the lliterbody field of
6760
+ // the function context with the ValueRef that we get from
6761
+ // llvm::LLVMGetParam for the iter's body.
6741
6762
if ( proto == ast:: proto_iter) {
6742
6763
auto llarg = llvm:: LLVMGetParam ( cx. llfn , arg_n) ;
6743
6764
assert ( llarg as int != 0 ) ;
6744
6765
cx. lliterbody = some[ ValueRef ] ( llarg) ;
6745
6766
arg_n += 1 u;
6746
6767
}
6747
6768
6769
+ // Populate the llargs field of the function context with the ValueRefs
6770
+ // that we get from llvm::LLVMGetParam for each argument.
6748
6771
for ( ast:: arg arg in args) {
6749
6772
auto llarg = llvm:: LLVMGetParam ( cx. llfn, arg_n) ;
6750
6773
assert ( llarg as int != 0 ) ;
@@ -6758,17 +6781,17 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
6758
6781
// were passed and whatnot. Apparently mem2reg will mop up.
6759
6782
6760
6783
fn copy_any_self_to_alloca ( @fn_ctxt fcx ,
6761
- option:: t[ tup ( TypeRef , ty :: t ) ] ty_self) {
6784
+ option:: t[ ty_self_pair ] ty_self ) {
6762
6785
6763
6786
auto bcx = llallocas_block_ctxt ( fcx) ;
6764
6787
6765
6788
alt ( fcx. llself ) {
6766
- case ( some( ?s_vt ) ) {
6789
+ case ( some ( ?pair ) ) {
6767
6790
alt ( ty_self) {
6768
- case ( some[ tup ( TypeRef , ty :: t ) ] ( ?tt) ) {
6791
+ case ( some[ ty_self_pair ] ( ?tt) ) {
6769
6792
auto a = alloca ( bcx, tt. _0 ) ;
6770
- bcx. build. Store ( s_vt . v, a) ;
6771
- fcx. llself = some[ self_vt ] ( rec( v = a, t = s_vt . t) ) ;
6793
+ bcx. build . Store ( pair . v , a) ;
6794
+ fcx. llself = some[ val_self_pair ] ( rec ( v = a, t = pair . t ) ) ;
6772
6795
}
6773
6796
}
6774
6797
}
@@ -6842,7 +6865,7 @@ fn ret_ty_of_fn(&@crate_ctxt ccx, ast::ann ann) -> ty::t {
6842
6865
ret ret_ty_of_fn_ty ( ccx, ty:: ann_to_type ( ccx. tcx . node_types , ann) ) ;
6843
6866
}
6844
6867
6845
- fn populate_fn_ctxt_from_llself( @fn_ctxt fcx, self_vt llself) {
6868
+ fn populate_fn_ctxt_from_llself( @fn_ctxt fcx , val_self_pair llself) {
6846
6869
auto bcx = llallocas_block_ctxt ( fcx) ;
6847
6870
6848
6871
let vec[ ty:: t] field_tys = [ ] ;
@@ -6921,7 +6944,7 @@ fn finish_fn(&@fn_ctxt fcx, BasicBlockRef lltop) {
6921
6944
// trans_fn: creates an LLVM function corresponding to a source language
6922
6945
// function.
6923
6946
fn trans_fn( @local_ctxt cx, & span sp, & ast:: _fn f, ast:: def_id fid,
6924
- option:: t[ tup ( TypeRef , ty :: t ) ] ty_self,
6947
+ option:: t[ ty_self_pair ] ty_self,
6925
6948
& vec[ ast:: ty_param] ty_params, & ast:: ann ann) {
6926
6949
auto llfndecl = cx. ccx. item_ids. get( fid) ;
6927
6950
@@ -6949,6 +6972,10 @@ fn trans_fn(@local_ctxt cx, &span sp, &ast::_fn f, ast::def_id fid,
6949
6972
auto lltop = bcx. llbb;
6950
6973
6951
6974
auto block_ty = node_ann_type( cx. ccx, f. body. node. a) ;
6975
+ // This call to trans_block is the place where we bridge between
6976
+ // translation calls that don't have a return value (trans_crate,
6977
+ // trans_mod, trans_item, trans_obj, et cetera) and those that do
6978
+ // (trans_block, trans_expr, et cetera).
6952
6979
auto res = if ( !ty:: type_is_nil( cx. ccx. tcx, block_ty)
6953
6980
&& !ty:: type_is_bot( cx. ccx. tcx, block_ty) ) {
6954
6981
trans_block( bcx, f. body, save_in( fcx. llretptr) )
@@ -7007,7 +7034,7 @@ fn create_vtbl(@local_ctxt cx,
7007
7034
cx. ccx. item_symbols. insert( m. node. id, s) ;
7008
7035
7009
7036
trans_fn( mcx, m. span, m. node. meth, m. node. id,
7010
- some[ tup ( TypeRef , ty :: t ) ] ( tup( llself_ty, self_ty) ) ,
7037
+ some[ ty_self_pair ] ( tup( llself_ty, self_ty) ) ,
7011
7038
ty_params, m. node. ann) ;
7012
7039
methods += [ llfn] ;
7013
7040
}
@@ -7036,7 +7063,7 @@ fn trans_dtor(@local_ctxt cx,
7036
7063
cx. ccx. item_symbols. insert( dtor. node. id, s) ;
7037
7064
7038
7065
trans_fn( dcx, dtor. span, dtor. node. meth, dtor. node. id,
7039
- some[ tup ( TypeRef , ty : : t ) ] ( tup( llself_ty, self_ty) ) ,
7066
+ some[ ty_self_pair ] ( tup( llself_ty, self_ty) ) ,
7040
7067
ty_params, dtor. node. ann) ;
7041
7068
7042
7069
ret llfn;
@@ -7065,7 +7092,7 @@ fn trans_obj(@local_ctxt cx, &span sp, &ast::_obj ob, ast::def_id oid,
7065
7092
7066
7093
auto fcx = new_fn_ctxt( cx, sp, llctor_decl) ;
7067
7094
create_llargs_for_fn_args( fcx, ast:: proto_fn,
7068
- none[ tup ( TypeRef , ty :: t ) ] ,
7095
+ none[ ty_self_pair ] ,
7069
7096
ret_ty_of_fn( ccx, ann) ,
7070
7097
fn_args, ty_params) ;
7071
7098
@@ -7232,7 +7259,7 @@ fn trans_tag_variant(@local_ctxt cx, ast::def_id tag_id,
7232
7259
auto fcx = new_fn_ctxt( cx, variant. span, llfndecl) ;
7233
7260
7234
7261
create_llargs_for_fn_args( fcx, ast:: proto_fn,
7235
- none[ tup ( TypeRef , ty :: t ) ] ,
7262
+ none[ ty_self_pair ] ,
7236
7263
ret_ty_of_fn( cx. ccx, variant. node. ann) ,
7237
7264
fn_args, ty_params) ;
7238
7265
@@ -7325,7 +7352,7 @@ fn trans_item(@local_ctxt cx, &ast::item item) {
7325
7352
alt ( item. node) {
7326
7353
case ( ast:: item_fn( ?name, ?f, ?tps, ?fid, ?ann) ) {
7327
7354
auto sub_cx = extend_path( cx, name) ;
7328
- trans_fn( sub_cx, item. span, f, fid, none[ tup ( TypeRef , ty :: t ) ] ,
7355
+ trans_fn( sub_cx, item. span, f, fid, none[ ty_self_pair ] ,
7329
7356
tps, ann) ;
7330
7357
}
7331
7358
case ( ast:: item_obj( ?name, ?ob, ?tps, ?oid, ?ann) ) {
0 commit comments