@@ -44,157 +44,80 @@ import util::ppaux::{ty_to_str, ty_to_short_str};
44
44
import common:: * ;
45
45
import build:: * ;
46
46
import shape:: * ;
47
+ import type_of:: * ;
48
+ import type_of:: type_of; // Issue #1873
47
49
import ast_map:: { path, path_mod, path_name} ;
48
50
49
- fn type_of_explicit_args ( cx : crate_ctxt , inputs : [ ty:: arg ] ) -> [ TypeRef ] {
50
- vec:: map ( inputs) { |arg|
51
- let arg_ty = arg. ty ;
52
- let llty = type_of ( cx, arg_ty) ;
53
- alt ty:: resolved_mode ( cx. tcx , arg. mode ) {
54
- ast:: by_val { llty }
55
- _ { T_ptr ( llty) }
56
- }
57
- }
58
- }
51
+ // Destinations
59
52
53
+ // These are passed around by the code generating functions to track the
54
+ // destination of a computation's value.
60
55
61
- // NB: must keep 4 fns in sync:
62
- //
63
- // - type_of_fn
64
- // - create_llargs_for_fn_args.
65
- // - new_fn_ctxt
66
- // - trans_args
67
- fn type_of_fn ( cx : crate_ctxt , inputs : [ ty:: arg ] ,
68
- output : ty:: t , params : [ ty:: param_bounds ] ) -> TypeRef {
69
- let atys: [ TypeRef ] = [ ] ;
56
+ enum dest {
57
+ by_val( @mutable ValueRef ) ,
58
+ save_in( ValueRef ) ,
59
+ ignore,
60
+ }
70
61
71
- // Arg 0: Output pointer.
72
- atys += [ T_ptr ( type_of ( cx, output) ) ] ;
62
+ fn empty_dest_cell ( ) -> @mutable ValueRef {
63
+ ret @mutable llvm:: LLVMGetUndef ( T_nil ( ) ) ;
64
+ }
73
65
74
- // Arg 1: Environment
75
- atys += [ T_opaque_box_ptr ( cx) ] ;
66
+ fn dup_for_join ( dest : dest ) -> dest {
67
+ alt dest {
68
+ by_val( _) { by_val ( empty_dest_cell ( ) ) }
69
+ _ { dest }
70
+ }
71
+ }
76
72
77
- // Args >2: ty params, if not acquired via capture...
78
- for bounds in params {
79
- atys += [ T_ptr ( cx. tydesc_type ) ] ;
80
- for bound in * bounds {
81
- alt bound {
82
- ty : : bound_iface ( _) { atys += [ T_ptr ( T_dict ( ) ) ] ; }
73
+ fn join_returns ( parent_cx : block , in_cxs : [ block ] ,
74
+ in_ds : [ dest ] , out_dest : dest ) -> block {
75
+ let out = sub_block ( parent_cx, "join" ) ;
76
+ let reachable = false , i = 0 u, phi = none;
77
+ for cx in in_cxs {
78
+ if !cx. unreachable {
79
+ Br ( cx, out. llbb ) ;
80
+ reachable = true ;
81
+ alt in_ds[ i] {
82
+ by_val ( cell) {
83
+ if option:: is_none ( phi) {
84
+ phi = some ( EmptyPhi ( out, val_ty ( * cell) ) ) ;
85
+ }
86
+ AddIncomingToPhi ( option:: get ( phi) , * cell, cx. llbb ) ;
87
+ }
83
88
_ { }
84
89
}
85
90
}
91
+ i += 1 u;
86
92
}
87
- // ... then explicit args.
88
- atys += type_of_explicit_args ( cx, inputs) ;
89
- ret T_fn ( atys, llvm:: LLVMVoidType ( ) ) ;
90
- }
91
-
92
- // Given a function type and a count of ty params, construct an llvm type
93
- fn type_of_fn_from_ty ( cx : crate_ctxt , fty : ty:: t ,
94
- param_bounds : [ ty:: param_bounds ] ) -> TypeRef {
95
- type_of_fn ( cx, ty:: ty_fn_args ( fty) , ty:: ty_fn_ret ( fty) , param_bounds)
96
- }
97
-
98
- fn type_of ( cx : crate_ctxt , t : ty:: t ) -> TypeRef {
99
- assert !ty:: type_has_vars ( t) ;
100
- // Check the cache.
101
-
102
- if cx. lltypes . contains_key ( t) { ret cx. lltypes . get ( t) ; }
103
- let llty = alt ty:: get ( t) . struct {
104
- ty:: ty_nil | ty:: ty_bot { T_nil ( ) }
105
- ty:: ty_bool { T_bool ( ) }
106
- ty:: ty_int ( t) { T_int_ty ( cx, t) }
107
- ty:: ty_uint ( t) { T_uint_ty ( cx, t) }
108
- ty:: ty_float ( t) { T_float_ty ( cx, t) }
109
- ty:: ty_str { T_ptr ( T_vec ( cx, T_i8 ( ) ) ) }
110
- ty:: ty_enum ( did, _) { type_of_enum ( cx, did, t) }
111
- ty:: ty_box ( mt) {
112
- let mt_ty = mt. ty ;
113
- T_ptr ( T_box ( cx, type_of ( cx, mt_ty) ) ) }
114
- ty:: ty_opaque_box { T_ptr ( T_box ( cx, T_i8 ( ) ) ) }
115
- ty:: ty_uniq ( mt) {
116
- let mt_ty = mt. ty ;
117
- T_ptr ( type_of ( cx, mt_ty) ) }
118
- ty:: ty_vec ( mt) {
119
- let mt_ty = mt. ty ;
120
- if ty:: type_has_dynamic_size ( cx. tcx , mt_ty) {
121
- T_ptr ( cx. opaque_vec_type )
122
- } else {
123
- T_ptr ( T_vec ( cx, type_of ( cx, mt_ty) ) ) }
124
- }
125
- ty:: ty_ptr ( mt) {
126
- let mt_ty = mt. ty ;
127
- T_ptr ( type_of ( cx, mt_ty) ) }
128
- ty:: ty_rec ( fields) {
129
- let tys: [ TypeRef ] = [ ] ;
130
- for f: ty:: field in fields {
131
- let mt_ty = f. mt . ty ;
132
- tys += [ type_of ( cx, mt_ty) ] ;
133
- }
134
- T_struct ( tys)
135
- }
136
- ty:: ty_fn ( _) {
137
- T_fn_pair ( cx, type_of_fn_from_ty ( cx, t, [ ] ) )
138
- }
139
- ty:: ty_iface ( _, _) { T_opaque_iface ( cx) }
140
- ty:: ty_res ( _, sub, tps) {
141
- let sub1 = ty:: substitute_type_params ( cx. tcx , tps, sub) ;
142
- ret T_struct ( [ T_i8 ( ) , type_of ( cx, sub1) ] ) ;
143
- }
144
- ty:: ty_param ( _, _) { T_typaram ( cx. tn ) }
145
- ty:: ty_send_type | ty:: ty_type { T_ptr ( cx. tydesc_type ) }
146
- ty:: ty_tup ( elts) {
147
- let tys = [ ] ;
148
- for elt in elts {
149
- tys += [ type_of ( cx, elt) ] ;
93
+ if !reachable {
94
+ Unreachable ( out) ;
95
+ } else {
96
+ alt out_dest {
97
+ by_val( cell) { * cell = option:: get ( phi) ; }
98
+ _ { }
150
99
}
151
- T_struct ( tys)
152
- }
153
- ty:: ty_opaque_closure_ptr ( _) { T_opaque_box_ptr ( cx) }
154
- ty:: ty_constr ( subt, _) { type_of ( cx, subt) }
155
-
156
- _ { fail "type_of not implemented for this kind of type" ; }
157
- } ;
158
- cx. lltypes . insert ( t, llty) ;
159
- ret llty;
160
- }
161
-
162
- fn type_of_enum ( cx : crate_ctxt , did : ast:: def_id , t : ty:: t )
163
- -> TypeRef {
164
- let degen = ( * ty:: enum_variants ( cx. tcx , did) ) . len ( ) == 1 u;
165
- if check type_has_static_size ( cx, t) {
166
- let size = static_size_of_enum ( cx, t) ;
167
- if !degen { T_enum ( cx, size) }
168
- else if size == 0 u { T_struct ( [ T_enum_variant ( cx) ] ) }
169
- else { T_array ( T_i8 ( ) , size) }
170
- }
171
- else {
172
- if degen { T_struct ( [ T_enum_variant ( cx) ] ) }
173
- else { T_opaque_enum ( cx) }
174
100
}
101
+ ret out;
175
102
}
176
103
177
- fn type_of_ty_param_bounds_and_ty
178
- ( ccx : crate_ctxt , tpt : ty:: ty_param_bounds_and_ty ) -> TypeRef {
179
- let t = tpt. ty ;
180
- alt ty:: get ( t) . struct {
181
- ty:: ty_fn ( _) {
182
- ret type_of_fn_from_ty ( ccx, t, * tpt. bounds ) ;
183
- }
184
- _ {
185
- // fall through
186
- }
104
+ // Used to put an immediate value in a dest.
105
+ fn store_in_dest ( bcx : block , val : ValueRef , dest : dest ) -> block {
106
+ alt dest {
107
+ ignore { }
108
+ by_val ( cell) { * cell = val; }
109
+ save_in ( addr) { Store ( bcx, val, addr) ; }
187
110
}
188
- type_of ( ccx , t )
111
+ ret bcx ;
189
112
}
190
113
191
- fn type_of_or_i8 ( ccx : crate_ctxt , typ : ty:: t ) -> TypeRef {
192
- if check type_has_static_size ( ccx, typ) {
193
- type_of ( ccx, typ)
194
- } else { T_i8 ( ) }
114
+ fn get_dest_addr ( dest : dest ) -> ValueRef {
115
+ alt dest {
116
+ save_in( a) { a }
117
+ _ { fail "get_dest_addr: not a save_in" ; }
118
+ }
195
119
}
196
120
197
-
198
121
// Name sanitation. LLVM will happily accept identifiers with weird names, but
199
122
// gas doesn't!
200
123
fn sanitize ( s : str ) -> str {
@@ -1886,8 +1809,6 @@ fn trans_lazy_binop(bcx: block, op: lazy_binop_ty, a: @ast::expr,
1886
1809
ret store_in_dest ( join, phi, dest) ;
1887
1810
}
1888
1811
1889
-
1890
-
1891
1812
fn trans_binary ( bcx : block , op : ast:: binop , lhs : @ast:: expr ,
1892
1813
rhs : @ast:: expr , dest : dest , ex : @ast:: expr ) -> block {
1893
1814
// User-defined operators
@@ -1921,71 +1842,6 @@ fn trans_binary(bcx: block, op: ast::binop, lhs: @ast::expr,
1921
1842
}
1922
1843
}
1923
1844
1924
- enum dest {
1925
- by_val( @mutable ValueRef ) ,
1926
- save_in( ValueRef ) ,
1927
- ignore,
1928
- }
1929
-
1930
- fn empty_dest_cell ( ) -> @mutable ValueRef {
1931
- ret @mutable llvm:: LLVMGetUndef ( T_nil ( ) ) ;
1932
- }
1933
-
1934
- fn dup_for_join ( dest : dest ) -> dest {
1935
- alt dest {
1936
- by_val( _) { by_val ( empty_dest_cell ( ) ) }
1937
- _ { dest }
1938
- }
1939
- }
1940
-
1941
- fn join_returns ( parent_cx : block , in_cxs : [ block ] ,
1942
- in_ds : [ dest ] , out_dest : dest ) -> block {
1943
- let out = sub_block ( parent_cx, "join" ) ;
1944
- let reachable = false , i = 0 u, phi = none;
1945
- for cx in in_cxs {
1946
- if !cx. unreachable {
1947
- Br ( cx, out. llbb ) ;
1948
- reachable = true ;
1949
- alt in_ds[ i] {
1950
- by_val ( cell) {
1951
- if option:: is_none ( phi) {
1952
- phi = some ( EmptyPhi ( out, val_ty ( * cell) ) ) ;
1953
- }
1954
- AddIncomingToPhi ( option:: get ( phi) , * cell, cx. llbb ) ;
1955
- }
1956
- _ { }
1957
- }
1958
- }
1959
- i += 1 u;
1960
- }
1961
- if !reachable {
1962
- Unreachable ( out) ;
1963
- } else {
1964
- alt out_dest {
1965
- by_val( cell) { * cell = option:: get ( phi) ; }
1966
- _ { }
1967
- }
1968
- }
1969
- ret out;
1970
- }
1971
-
1972
- // Used to put an immediate value in a dest.
1973
- fn store_in_dest ( bcx : block , val : ValueRef , dest : dest ) -> block {
1974
- alt dest {
1975
- ignore { }
1976
- by_val ( cell) { * cell = val; }
1977
- save_in ( addr) { Store ( bcx, val, addr) ; }
1978
- }
1979
- ret bcx;
1980
- }
1981
-
1982
- fn get_dest_addr ( dest : dest ) -> ValueRef {
1983
- alt dest {
1984
- save_in( a) { a }
1985
- _ { fail "get_dest_addr: not a save_in" ; }
1986
- }
1987
- }
1988
-
1989
1845
fn trans_if ( cx : block , cond : @ast:: expr , thn : ast:: blk ,
1990
1846
els : option < @ast:: expr > , dest : dest )
1991
1847
-> block {
0 commit comments