@@ -12,6 +12,7 @@ use core::prelude::*;
12
12
13
13
use lib:: llvm:: { llvm, ValueRef , TypeRef , Bool , True , False } ;
14
14
use middle:: const_eval;
15
+ use middle:: trans:: adt;
15
16
use middle:: trans:: base;
16
17
use middle:: trans:: base:: get_insn_ctxt;
17
18
use middle:: trans:: common:: * ;
@@ -328,24 +329,8 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
328
329
}
329
330
( expr:: cast_enum, expr:: cast_integral) |
330
331
( expr:: cast_enum, expr:: cast_float) => {
331
- let def = ty:: resolve_expr ( cx. tcx , base) ;
332
- let ( enum_did, variant_did) = match def {
333
- ast:: def_variant( enum_did, variant_did) => {
334
- ( enum_did, variant_did)
335
- }
336
- _ => cx. sess . bug ( ~"enum cast source is not enum ")
337
- } ;
338
- // Note that we know this is a C-like (nullary) enum
339
- // variant or we wouldn't have gotten here
340
- let variants = ty:: enum_variants ( cx. tcx , enum_did) ;
341
- let iv = if variants. len ( ) == 1 {
342
- // Univariants don't have a discriminant field,
343
- // because there's only one value it could have:
344
- C_integral ( T_i64 ( ) ,
345
- variants[ 0 ] . disr_val as u64 , True )
346
- } else {
347
- base:: get_discrim_val ( cx, e. span , enum_did, variant_did)
348
- } ;
332
+ let repr = adt:: represent_type ( cx, basety) ;
333
+ let iv = C_int ( cx, adt:: const_get_discrim ( cx, & repr, v) ) ;
349
334
let ety_cast = expr:: cast_type_kind ( ety) ;
350
335
match ety_cast {
351
336
expr:: cast_integral => {
@@ -373,28 +358,32 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
373
358
gv
374
359
}
375
360
ast:: expr_tup ( es) => {
376
- C_struct ( es. map ( |e| const_expr ( cx, * e) ) )
361
+ let ety = ty:: expr_ty ( cx. tcx , e) ;
362
+ let repr = adt:: represent_type ( cx, ety) ;
363
+ adt:: trans_const ( cx, & repr, 0 , es. map ( |e| const_expr ( cx, * e) ) )
377
364
}
378
365
ast:: expr_rec( ref fs, None ) => {
379
- C_struct ( [ C_struct (
380
- ( * fs) . map ( |f| const_expr ( cx, f. node . expr ) ) ) ] )
366
+ let ety = ty:: expr_ty ( cx. tcx , e) ;
367
+ let repr = adt:: represent_type ( cx, ety) ;
368
+ adt:: trans_const ( cx, & repr, 0 ,
369
+ fs. map ( |f| const_expr ( cx, f. node . expr ) ) )
381
370
}
382
- ast:: expr_struct ( _, ref fs, _ ) => {
371
+ ast:: expr_struct( _, ref fs, None ) => {
383
372
let ety = ty:: expr_ty ( cx. tcx , e) ;
384
- let cs = do expr :: with_field_tys ( cx. tcx ,
385
- ety,
386
- None ) |_hd , field_tys| {
387
- field_tys. map ( |field_ty| {
373
+ let repr = adt :: represent_type ( cx, ety ) ;
374
+ do expr :: with_field_tys ( cx . tcx , ety, Some ( e . id ) )
375
+ |discr , field_tys| {
376
+ let cs = field_tys. map ( |field_ty| {
388
377
match fs. find ( |f| field_ty. ident == f. node . ident ) {
389
378
Some ( ref f) => const_expr ( cx, ( * f) . node . expr ) ,
390
379
None => {
391
380
cx. tcx . sess . span_bug (
392
381
e. span , ~"missing struct field") ;
393
382
}
394
383
}
395
- } )
396
- } ;
397
- C_struct ( [ C_struct ( cs ) ] )
384
+ } ) ;
385
+ adt :: trans_const ( cx , & repr , discr , cs )
386
+ }
398
387
}
399
388
ast:: expr_vec( es, ast:: m_imm) => {
400
389
let ( v, _, _) = const_vec ( cx, e, es) ;
@@ -452,78 +441,44 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
452
441
get_const_val ( cx, def_id)
453
442
}
454
443
Some ( ast:: def_variant( enum_did, variant_did) ) => {
455
- // Note that we know this is a C-like (nullary) enum
456
- // variant or we wouldn't have gotten here -- the constant
457
- // checker forbids paths that don't map to C-like enum
458
- // variants.
459
- if ty:: enum_is_univariant ( cx. tcx , enum_did) {
460
- // Univariants have no discriminant field.
461
- C_struct ( ~[ ] )
462
- } else {
463
- let lldiscrim = base:: get_discrim_val ( cx, e. span ,
464
- enum_did,
465
- variant_did) ;
466
- // However, we still have to pad it out to the
467
- // size of the full enum; see the expr_call case,
468
- // below.
469
444
let ety = ty:: expr_ty ( cx. tcx , e) ;
470
- let size = machine:: static_size_of_enum ( cx, ety) ;
471
- let padding = C_null ( T_array ( T_i8 ( ) , size) ) ;
472
- C_struct ( ~[ lldiscrim, padding] )
473
- }
445
+ let repr = adt:: represent_type ( cx, ety) ;
446
+ let vinfo = ty:: enum_variant_with_id ( cx. tcx ,
447
+ enum_did,
448
+ variant_did) ;
449
+ adt:: trans_const ( cx, & repr, vinfo. disr_val , [ ] )
474
450
}
475
451
Some ( ast:: def_struct( _) ) => {
476
452
let ety = ty:: expr_ty ( cx. tcx , e) ;
477
453
let llty = type_of:: type_of ( cx, ety) ;
478
454
C_null ( llty)
479
455
}
480
456
_ => {
481
- cx. sess . span_bug ( e. span ,
482
- ~"expected a const , fn , or variant def")
457
+ cx. sess . span_bug ( e. span , ~"expected a const , fn , \
458
+ struct , or variant def")
483
459
}
484
460
}
485
461
}
486
462
ast:: expr_call( callee, args, _) => {
487
- match cx. tcx . def_map . find ( & callee. id ) {
488
- Some ( ast:: def_struct( def_id) ) => {
489
- let llstructbody =
490
- C_struct ( args. map ( |a| const_expr ( cx, * a) ) ) ;
491
- if ty:: ty_dtor ( cx. tcx , def_id) . is_present ( ) {
492
- C_struct ( ~[ llstructbody, C_u8 ( 0 ) ] )
493
- } else {
494
- C_struct ( ~[ llstructbody ] )
495
- }
496
- }
497
- Some ( ast:: def_variant( tid, vid) ) => {
498
- let ety = ty:: expr_ty ( cx. tcx , e) ;
499
- let univar = ty:: enum_is_univariant ( cx. tcx , tid) ;
500
- let size = machine:: static_size_of_enum ( cx, ety) ;
501
-
502
- let discrim = base:: get_discrim_val ( cx, e. span , tid, vid) ;
503
- let c_args = C_struct ( args. map ( |a| const_expr ( cx, * a) ) ) ;
504
-
505
- // FIXME (#1645): enum body alignment is generaly wrong.
506
- if !univar {
507
- // Pad out the data to the size of its type_of;
508
- // this is necessary if the enum is contained
509
- // within an aggregate (tuple, struct, vector) so
510
- // that the next element is at the right offset.
511
- let actual_size =
512
- machine:: llsize_of_real ( cx, llvm:: LLVMTypeOf ( c_args) ) ;
513
- let padding =
514
- C_null ( T_array ( T_i8 ( ) , size - actual_size) ) ;
515
- // A packed_struct has an alignment of 1; thus,
516
- // wrapping one around c_args will misalign it the
517
- // same way we normally misalign enum bodies
518
- // without affecting its internal alignment or
519
- // changing the alignment of the enum.
520
- C_struct ( ~[ discrim, C_packed_struct ( ~[ c_args] ) , padding] )
521
- } else {
522
- C_struct ( ~[ c_args] )
523
- }
524
- }
525
- _ => cx. sess . span_bug ( e. span , ~"expected a struct def")
526
- }
463
+ match cx. tcx . def_map . find ( & callee. id ) {
464
+ Some ( ast:: def_struct( _) ) => {
465
+ let ety = ty:: expr_ty ( cx. tcx , e) ;
466
+ let repr = adt:: represent_type ( cx, ety) ;
467
+ adt:: trans_const ( cx, & repr, 0 ,
468
+ args. map ( |a| const_expr ( cx, * a) ) )
469
+ }
470
+ Some ( ast:: def_variant( enum_did, variant_did) ) => {
471
+ let ety = ty:: expr_ty ( cx. tcx , e) ;
472
+ let repr = adt:: represent_type ( cx, ety) ;
473
+ let vinfo = ty:: enum_variant_with_id ( cx. tcx ,
474
+ enum_did,
475
+ variant_did) ;
476
+ adt:: trans_const ( cx, & repr, vinfo. disr_val ,
477
+ args. map ( |a| const_expr ( cx, * a) ) )
478
+ }
479
+ _ => cx. sess . span_bug ( e. span , ~"expected a struct or \
480
+ variant def")
481
+ }
527
482
}
528
483
ast:: expr_paren( e) => { return const_expr ( cx, e) ; }
529
484
_ => cx. sess . span_bug ( e. span ,
0 commit comments