10
10
11
11
use core:: prelude:: * ;
12
12
13
+ use back:: abi;
13
14
use lib:: llvm:: { llvm, ValueRef , TypeRef , Bool , True , False } ;
14
15
use metadata:: csearch;
15
16
use middle:: const_eval;
@@ -117,22 +118,6 @@ pub fn const_deref(cx: @CrateContext, v: ValueRef) -> ValueRef {
117
118
}
118
119
}
119
120
120
- pub fn const_autoderef ( cx : @CrateContext , ty : ty:: t , v : ValueRef )
121
- -> ( ty:: t , ValueRef ) {
122
- let mut t1 = ty;
123
- let mut v1 = v;
124
- loop {
125
- // Only rptrs can be autoderef'ed in a const context.
126
- match ty:: get ( t1) . sty {
127
- ty:: ty_rptr( _, mt) => {
128
- t1 = mt. ty ;
129
- v1 = const_deref ( cx, v1) ;
130
- }
131
- _ => return ( t1, v1)
132
- }
133
- }
134
- }
135
-
136
121
pub fn get_const_val ( cx : @CrateContext , def_id : ast:: def_id ) -> ValueRef {
137
122
let mut def_id = def_id;
138
123
if !ast_util:: is_local ( def_id) ||
@@ -153,15 +138,59 @@ pub fn get_const_val(cx: @CrateContext, def_id: ast::def_id) -> ValueRef {
153
138
}
154
139
155
140
pub fn const_expr( cx : @CrateContext , e : @ast:: expr ) -> ValueRef {
156
- let ety = ty:: expr_ty_adjusted ( cx. tcx , e) ;
157
- let llty = type_of:: sizing_type_of ( cx, ety) ;
158
- let llconst = const_expr_unchecked ( cx, e) ;
141
+ let mut llconst = const_expr_unadjusted ( cx, e) ;
142
+ let ety = ty:: expr_ty ( cx. tcx , e) ;
143
+ match cx. tcx . adjustments . find ( & e. id ) {
144
+ None => { }
145
+ Some ( @ty:: AutoAddEnv ( ty:: re_static, ast:: BorrowedSigil ) ) => {
146
+ llconst = C_struct ( ~[ llconst, C_null ( T_opaque_box_ptr ( cx) ) ] )
147
+ }
148
+ Some ( @ty:: AutoAddEnv ( ref r, ref s) ) => {
149
+ cx. sess . span_bug ( e. span , fmt ! ( "unexpected const function: \
150
+ region %? sigil %?", * r, * s) )
151
+ }
152
+ Some ( @ty:: AutoDerefRef ( ref adj) ) => {
153
+ for adj. autoderefs. times {
154
+ llconst = const_deref( cx, llconst)
155
+ }
156
+
157
+ match adj. autoref {
158
+ None => { }
159
+ Some ( ref autoref) => {
160
+ fail_unless ! ( autoref. region == ty:: re_static) ;
161
+ fail_unless ! ( autoref. mutbl != ast:: m_mutbl) ;
162
+ match autoref. kind {
163
+ ty : : AutoPtr => {
164
+ llconst = const_addr_of( cx, llconst) ;
165
+ }
166
+ ty:: AutoBorrowVec => {
167
+ let base = const_addr_of( cx, llconst) ;
168
+ let size = machine:: llsize_of( cx,
169
+ val_ty( llconst) ) ;
170
+ fail_unless ! ( abi:: slice_elt_base == 0 ) ;
171
+ fail_unless ! ( abi:: slice_elt_len == 1 ) ;
172
+ llconst = C_struct ( ~[ base, size] ) ;
173
+ }
174
+ _ => {
175
+ cx. sess. span_bug( e. span,
176
+ fmt ! ( "unimplemented const \
177
+ autoref %?", autoref) )
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+ }
184
+
185
+ let ety_adjusted = ty:: expr_ty_adjusted( cx. tcx, e) ;
186
+ let llty = type_of:: sizing_type_of( cx, ety_adjusted) ;
159
187
let csize = machine:: llsize_of_alloc( cx, val_ty( llconst) ) ;
160
188
let tsize = machine:: llsize_of_alloc( cx, llty) ;
161
189
if csize != tsize {
162
190
unsafe {
191
+ // XXX these values could use some context
163
192
llvm : : LLVMDumpValue ( llconst) ;
164
- llvm:: LLVMDumpValue ( C_null ( llty) ) ;
193
+ llvm:: LLVMDumpValue ( C_undef ( llty) ) ;
165
194
}
166
195
cx. sess. bug( fmt ! ( "const %s of type %s has size %u instead of %u" ,
167
196
expr_repr( cx. tcx, e) , ty_to_str( cx. tcx, ety) ,
@@ -170,7 +199,7 @@ pub fn const_expr(cx: @CrateContext, e: @ast::expr) -> ValueRef {
170
199
llconst
171
200
}
172
201
173
- fn const_expr_unchecked ( cx : @CrateContext , e : @ast:: expr ) -> ValueRef {
202
+ fn const_expr_unadjusted ( cx: @CrateContext , e: @ast:: expr) -> ValueRef {
174
203
unsafe {
175
204
let _icx = cx. insn_ctxt( "const_expr" ) ;
176
205
return match /*bad*/ copy e. node {
@@ -254,20 +283,18 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
254
283
}
255
284
}
256
285
ast:: expr_field( base, field, _) => {
257
- let bt = ty:: expr_ty ( cx. tcx , base) ;
286
+ let bt = ty:: expr_ty_adjusted ( cx. tcx, base) ;
258
287
let brepr = adt:: represent_type( cx, bt) ;
259
288
let bv = const_expr( cx, base) ;
260
- let ( bt, bv) = const_autoderef ( cx, bt, bv) ;
261
289
do expr:: with_field_tys( cx. tcx, bt, None ) |discr, field_tys| {
262
290
let ix = ty:: field_idx_strict( cx. tcx, field, field_tys) ;
263
291
adt:: const_get_field( cx, brepr, bv, discr, ix)
264
292
}
265
293
}
266
294
267
295
ast:: expr_index( base, index) => {
268
- let bt = ty:: expr_ty ( cx. tcx , base) ;
296
+ let bt = ty:: expr_ty_adjusted ( cx. tcx, base) ;
269
297
let bv = const_expr( cx, base) ;
270
- let ( bt, bv) = const_autoderef ( cx, bt, bv) ;
271
298
let iv = match const_eval:: eval_const_expr( cx. tcx, index) {
272
299
const_eval:: const_int( i) => i as u64,
273
300
const_eval:: const_uint( u) => u,
@@ -425,26 +452,12 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
425
452
fail_unless ! ( pth. types. len( ) == 0 ) ;
426
453
match cx. tcx. def_map. find( & e. id) {
427
454
Some ( ast:: def_fn( def_id, _purity) ) => {
428
- let f = if !ast_util:: is_local ( def_id) {
455
+ if !ast_util:: is_local( def_id) {
429
456
let ty = csearch:: get_type( cx. tcx, def_id) . ty;
430
457
base:: trans_external_path( cx, def_id, ty)
431
458
} else {
432
459
fail_unless ! ( ast_util:: is_local( def_id) ) ;
433
460
base:: get_item_val( cx, def_id. node)
434
- } ;
435
- let ety = ty:: expr_ty_adjusted ( cx. tcx , e) ;
436
- match ty:: get ( ety) . sty {
437
- ty:: ty_bare_fn( * ) | ty:: ty_ptr( * ) => {
438
- llvm:: LLVMConstPointerCast ( f, T_ptr ( T_i8 ( ) ) )
439
- }
440
- ty:: ty_closure( * ) => {
441
- C_struct ( ~[ f, C_null ( T_opaque_box_ptr ( cx) ) ] )
442
- }
443
- _ => {
444
- cx. sess . span_bug ( e. span , fmt ! (
445
- "unexpected const fn type: %s" ,
446
- ty_to_str( cx. tcx, ety) ) )
447
- }
448
461
}
449
462
}
450
463
Some ( ast:: def_const( def_id) ) => {
0 commit comments