@@ -48,17 +48,13 @@ use std;
48
48
use llvm:: { ValueRef , True , IntEQ , IntNE } ;
49
49
use rustc:: ty:: layout;
50
50
use rustc:: ty:: { self , Ty , AdtKind } ;
51
- use rustc:: mir:: tcx:: LvalueTy ;
52
- use mir:: lvalue:: LvalueRef ;
53
51
use common:: * ;
54
52
use builder:: Builder ;
55
- use glue;
56
53
use base;
57
54
use machine;
58
55
use monomorphize;
59
56
use type_:: Type ;
60
57
use type_of;
61
- use value:: Value ;
62
58
63
59
#[ derive( Copy , Clone , PartialEq ) ]
64
60
pub enum BranchKind {
@@ -471,163 +467,6 @@ pub fn assert_discr_in_range(min: Disr, max: Disr, discr: Disr) {
471
467
}
472
468
}
473
469
474
- /// Access a field, at a point when the value's case is known.
475
- pub fn trans_field_ptr < ' a , ' tcx > (
476
- bcx : & Builder < ' a , ' tcx > ,
477
- val : LvalueRef < ' tcx > ,
478
- ix : usize ,
479
- ) -> ValueRef {
480
- let discr = match val. ty {
481
- LvalueTy :: Ty { .. } => 0 ,
482
- LvalueTy :: Downcast { variant_index, .. } => variant_index,
483
- } ;
484
- let t = val. ty . to_ty ( bcx. tcx ( ) ) ;
485
- let l = bcx. ccx . layout_of ( t) ;
486
- // Note: if this ever needs to generate conditionals (e.g., if we
487
- // decide to do some kind of cdr-coding-like non-unique repr
488
- // someday), it will need to return a possibly-new bcx as well.
489
- match * l {
490
- layout:: Univariant { ref variant, .. } => {
491
- assert_eq ! ( discr, 0 ) ;
492
- struct_field_ptr ( bcx, & variant,
493
- & compute_fields ( bcx. ccx , t, 0 , false ) ,
494
- val, ix, false )
495
- }
496
- layout:: Vector { count, .. } => {
497
- assert_eq ! ( discr, 0 ) ;
498
- assert ! ( ( ix as u64 ) < count) ;
499
- bcx. struct_gep ( val. llval , ix)
500
- }
501
- layout:: General { discr : d, ref variants, .. } => {
502
- let mut fields = compute_fields ( bcx. ccx , t, discr, false ) ;
503
- fields. insert ( 0 , d. to_ty ( & bcx. tcx ( ) , false ) ) ;
504
- struct_field_ptr ( bcx, & variants[ discr] ,
505
- & fields,
506
- val, ix + 1 , true )
507
- }
508
- layout:: UntaggedUnion { .. } => {
509
- let fields = compute_fields ( bcx. ccx , t, 0 , false ) ;
510
- let ty = type_of:: in_memory_type_of ( bcx. ccx , fields[ ix] ) ;
511
- bcx. pointercast ( val. llval , ty. ptr_to ( ) )
512
- }
513
- layout:: RawNullablePointer { nndiscr, .. } |
514
- layout:: StructWrappedNullablePointer { nndiscr, .. } if discr as u64 != nndiscr => {
515
- let nullfields = compute_fields ( bcx. ccx , t, ( 1 -nndiscr) as usize , false ) ;
516
- // The unit-like case might have a nonzero number of unit-like fields.
517
- // (e.d., Result of Either with (), as one side.)
518
- let ty = type_of:: type_of ( bcx. ccx , nullfields[ ix] ) ;
519
- assert_eq ! ( machine:: llsize_of_alloc( bcx. ccx, ty) , 0 ) ;
520
- bcx. pointercast ( val. llval , ty. ptr_to ( ) )
521
- }
522
- layout:: RawNullablePointer { nndiscr, .. } => {
523
- let nnty = compute_fields ( bcx. ccx , t, nndiscr as usize , false ) [ 0 ] ;
524
- assert_eq ! ( ix, 0 ) ;
525
- assert_eq ! ( discr as u64 , nndiscr) ;
526
- let ty = type_of:: type_of ( bcx. ccx , nnty) ;
527
- bcx. pointercast ( val. llval , ty. ptr_to ( ) )
528
- }
529
- layout:: StructWrappedNullablePointer { ref nonnull, nndiscr, .. } => {
530
- assert_eq ! ( discr as u64 , nndiscr) ;
531
- struct_field_ptr ( bcx, & nonnull,
532
- & compute_fields ( bcx. ccx , t, discr, false ) ,
533
- val, ix, false )
534
- }
535
- _ => bug ! ( "element access in type without elements: {} represented as {:#?}" , t, l)
536
- }
537
- }
538
-
539
- fn struct_field_ptr < ' a , ' tcx > (
540
- bcx : & Builder < ' a , ' tcx > ,
541
- st : & layout:: Struct ,
542
- fields : & Vec < Ty < ' tcx > > ,
543
- val : LvalueRef ,
544
- ix : usize ,
545
- needs_cast : bool
546
- ) -> ValueRef {
547
- let fty = fields[ ix] ;
548
- let ccx = bcx. ccx ;
549
-
550
- let ptr_val = if needs_cast {
551
- let fields = st. field_index_by_increasing_offset ( ) . map ( |i| {
552
- type_of:: in_memory_type_of ( ccx, fields[ i] )
553
- } ) . collect :: < Vec < _ > > ( ) ;
554
- let real_ty = Type :: struct_ ( ccx, & fields[ ..] , st. packed ) ;
555
- bcx. pointercast ( val. llval , real_ty. ptr_to ( ) )
556
- } else {
557
- val. llval
558
- } ;
559
-
560
- // Simple case - we can just GEP the field
561
- // * First field - Always aligned properly
562
- // * Packed struct - There is no alignment padding
563
- // * Field is sized - pointer is properly aligned already
564
- if st. offsets [ ix] == layout:: Size :: from_bytes ( 0 ) || st. packed ||
565
- bcx. ccx . shared ( ) . type_is_sized ( fty) {
566
- return bcx. struct_gep ( ptr_val, st. memory_index [ ix] as usize ) ;
567
- }
568
-
569
- // If the type of the last field is [T] or str, then we don't need to do
570
- // any adjusments
571
- match fty. sty {
572
- ty:: TySlice ( ..) | ty:: TyStr => {
573
- return bcx. struct_gep ( ptr_val, st. memory_index [ ix] as usize ) ;
574
- }
575
- _ => ( )
576
- }
577
-
578
- // There's no metadata available, log the case and just do the GEP.
579
- if !val. has_extra ( ) {
580
- debug ! ( "Unsized field `{}`, of `{:?}` has no metadata for adjustment" ,
581
- ix, Value ( ptr_val) ) ;
582
- return bcx. struct_gep ( ptr_val, ix) ;
583
- }
584
-
585
- // We need to get the pointer manually now.
586
- // We do this by casting to a *i8, then offsetting it by the appropriate amount.
587
- // We do this instead of, say, simply adjusting the pointer from the result of a GEP
588
- // because the field may have an arbitrary alignment in the LLVM representation
589
- // anyway.
590
- //
591
- // To demonstrate:
592
- // struct Foo<T: ?Sized> {
593
- // x: u16,
594
- // y: T
595
- // }
596
- //
597
- // The type Foo<Foo<Trait>> is represented in LLVM as { u16, { u16, u8 }}, meaning that
598
- // the `y` field has 16-bit alignment.
599
-
600
- let meta = val. llextra ;
601
-
602
-
603
- let offset = st. offsets [ ix] . bytes ( ) ;
604
- let unaligned_offset = C_uint ( bcx. ccx , offset) ;
605
-
606
- // Get the alignment of the field
607
- let ( _, align) = glue:: size_and_align_of_dst ( bcx, fty, meta) ;
608
-
609
- // Bump the unaligned offset up to the appropriate alignment using the
610
- // following expression:
611
- //
612
- // (unaligned offset + (align - 1)) & -align
613
-
614
- // Calculate offset
615
- let align_sub_1 = bcx. sub ( align, C_uint ( bcx. ccx , 1u64 ) ) ;
616
- let offset = bcx. and ( bcx. add ( unaligned_offset, align_sub_1) ,
617
- bcx. neg ( align) ) ;
618
-
619
- debug ! ( "struct_field_ptr: DST field offset: {:?}" , Value ( offset) ) ;
620
-
621
- // Cast and adjust pointer
622
- let byte_ptr = bcx. pointercast ( ptr_val, Type :: i8p ( bcx. ccx ) ) ;
623
- let byte_ptr = bcx. gep ( byte_ptr, & [ offset] ) ;
624
-
625
- // Finally, cast back to the type expected
626
- let ll_fty = type_of:: in_memory_type_of ( bcx. ccx , fty) ;
627
- debug ! ( "struct_field_ptr: Field type is {:?}" , ll_fty) ;
628
- bcx. pointercast ( byte_ptr, ll_fty. ptr_to ( ) )
629
- }
630
-
631
470
// FIXME this utility routine should be somewhere more general
632
471
#[ inline]
633
472
fn roundup ( x : u64 , a : u32 ) -> u64 { let a = a as u64 ; ( ( x + ( a - 1 ) ) / a) * a }
0 commit comments