@@ -53,14 +53,9 @@ use rustc::ty::{self, Ty, TyCtxt};
5353use syntax:: ast;
5454use syntax:: attr;
5555use syntax:: attr:: IntType ;
56- use _match;
5756use abi:: FAT_PTR_ADDR ;
58- use base:: InitAlloca ;
5957use build:: * ;
60- use cleanup;
61- use cleanup:: CleanupMethods ;
6258use common:: * ;
63- use datum;
6459use debuginfo:: DebugLoc ;
6560use glue;
6661use machine;
@@ -69,6 +64,12 @@ use type_::Type;
6964use type_of;
7065use value:: Value ;
7166
67+ #[ derive( Copy , Clone , PartialEq ) ]
68+ pub enum BranchKind {
69+ Switch ,
70+ Single
71+ }
72+
7273type Hint = attr:: ReprAttr ;
7374
7475// Representation of the context surrounding an unsized type. I want
@@ -178,14 +179,6 @@ impl MaybeSizedValue {
178179 }
179180}
180181
181- /// Convenience for `represent_type`. There should probably be more or
182- /// these, for places in trans where the `Ty` isn't directly
183- /// available.
184- pub fn represent_node < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
185- node : ast:: NodeId ) -> Rc < Repr < ' tcx > > {
186- represent_type ( bcx. ccx ( ) , node_id_type ( bcx, node) )
187- }
188-
189182/// Decides how to represent a given type.
190183pub fn represent_type < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > ,
191184 t : Ty < ' tcx > )
@@ -201,49 +194,15 @@ pub fn represent_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
201194 repr
202195}
203196
204- const fn repeat_u8_as_u32 ( val : u8 ) -> u32 {
205- ( val as u32 ) << 24 | ( val as u32 ) << 16 | ( val as u32 ) << 8 | val as u32
206- }
207-
208- const fn repeat_u8_as_u64 ( val : u8 ) -> u64 {
209- ( repeat_u8_as_u32 ( val) as u64 ) << 32 | repeat_u8_as_u32 ( val) as u64
210- }
211-
212- /// `DTOR_NEEDED_HINT` is a stack-local hint that just means
213- /// "we do not know whether the destructor has run or not; check the
214- /// drop-flag embedded in the value itself."
215- pub const DTOR_NEEDED_HINT : u8 = 0x3d ;
216-
217- /// `DTOR_MOVED_HINT` is a stack-local hint that means "this value has
218- /// definitely been moved; you do not need to run its destructor."
219- ///
220- /// (However, for now, such values may still end up being explicitly
221- /// zeroed by the generated code; this is the distinction between
222- /// `datum::DropFlagInfo::ZeroAndMaintain` versus
223- /// `datum::DropFlagInfo::DontZeroJustUse`.)
224- pub const DTOR_MOVED_HINT : u8 = 0x2d ;
225-
226- pub const DTOR_NEEDED : u8 = 0xd4 ;
227- #[ allow( dead_code) ]
228- pub const DTOR_NEEDED_U64 : u64 = repeat_u8_as_u64 ( DTOR_NEEDED ) ;
229-
230- pub const DTOR_DONE : u8 = 0x1d ;
231- #[ allow( dead_code) ]
232- pub const DTOR_DONE_U64 : u64 = repeat_u8_as_u64 ( DTOR_DONE ) ;
233-
234197fn dtor_to_init_u8 ( dtor : bool ) -> u8 {
235- if dtor { DTOR_NEEDED } else { 0 }
198+ if dtor { 1 } else { 0 }
236199}
237200
238201pub trait GetDtorType < ' tcx > { fn dtor_type ( self ) -> Ty < ' tcx > ; }
239202impl < ' a , ' tcx > GetDtorType < ' tcx > for TyCtxt < ' a , ' tcx , ' tcx > {
240203 fn dtor_type ( self ) -> Ty < ' tcx > { self . types . u8 }
241204}
242205
243- fn dtor_active ( flag : u8 ) -> bool {
244- flag != 0
245- }
246-
247206fn represent_type_uncached < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > ,
248207 t : Ty < ' tcx > ) -> Repr < ' tcx > {
249208 match t. sty {
@@ -873,22 +832,19 @@ fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, st: &Struct<'tcx>,
873832
874833/// Obtain a representation of the discriminant sufficient to translate
875834/// destructuring; this may or may not involve the actual discriminant.
876- ///
877- /// This should ideally be less tightly tied to `_match`.
878835pub fn trans_switch < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
879836 r : & Repr < ' tcx > ,
880837 scrutinee : ValueRef ,
881838 range_assert : bool )
882- -> ( _match :: BranchKind , Option < ValueRef > ) {
839+ -> ( BranchKind , Option < ValueRef > ) {
883840 match * r {
884841 CEnum ( ..) | General ( ..) |
885842 RawNullablePointer { .. } | StructWrappedNullablePointer { .. } => {
886- ( _match:: Switch , Some ( trans_get_discr ( bcx, r, scrutinee, None ,
887- range_assert) ) )
843+ ( BranchKind :: Switch , Some ( trans_get_discr ( bcx, r, scrutinee, None , range_assert) ) )
888844 }
889845 Univariant ( ..) => {
890846 // N.B.: Univariant means <= 1 enum variants (*not* == 1 variants).
891- ( _match :: Single , None )
847+ ( BranchKind :: Single , None )
892848 }
893849 }
894850}
@@ -1001,21 +957,12 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
1001957 Store ( bcx, C_integral ( ll_inttype ( bcx. ccx ( ) , ity) , discr. 0 , true ) ,
1002958 val) ;
1003959 }
1004- General ( ity, ref cases, dtor) => {
1005- if dtor_active ( dtor) {
1006- let ptr = trans_field_ptr ( bcx, r, MaybeSizedValue :: sized ( val) , discr,
1007- cases[ discr. 0 as usize ] . fields . len ( ) - 2 ) ;
1008- Store ( bcx, C_u8 ( bcx. ccx ( ) , DTOR_NEEDED ) , ptr) ;
1009- }
960+ General ( ity, _, _) => {
1010961 Store ( bcx, C_integral ( ll_inttype ( bcx. ccx ( ) , ity) , discr. 0 , true ) ,
1011962 StructGEP ( bcx, val, 0 ) ) ;
1012963 }
1013- Univariant ( ref st , dtor ) => {
964+ Univariant ( _ , _ ) => {
1014965 assert_eq ! ( discr, Disr ( 0 ) ) ;
1015- if dtor_active ( dtor) {
1016- Store ( bcx, C_u8 ( bcx. ccx ( ) , DTOR_NEEDED ) ,
1017- StructGEP ( bcx, val, st. fields . len ( ) - 1 ) ) ;
1018- }
1019966 }
1020967 RawNullablePointer { nndiscr, nnty, ..} => {
1021968 if discr != nndiscr {
@@ -1046,28 +993,6 @@ fn assert_discr_in_range(ity: IntType, min: Disr, max: Disr, discr: Disr) {
1046993 }
1047994}
1048995
1049- /// The number of fields in a given case; for use when obtaining this
1050- /// information from the type or definition is less convenient.
1051- pub fn num_args ( r : & Repr , discr : Disr ) -> usize {
1052- match * r {
1053- CEnum ( ..) => 0 ,
1054- Univariant ( ref st, dtor) => {
1055- assert_eq ! ( discr, Disr ( 0 ) ) ;
1056- st. fields . len ( ) - ( if dtor_active ( dtor) { 1 } else { 0 } )
1057- }
1058- General ( _, ref cases, dtor) => {
1059- cases[ discr. 0 as usize ] . fields . len ( ) - 1 - ( if dtor_active ( dtor) { 1 } else { 0 } )
1060- }
1061- RawNullablePointer { nndiscr, ref nullfields, .. } => {
1062- if discr == nndiscr { 1 } else { nullfields. len ( ) }
1063- }
1064- StructWrappedNullablePointer { ref nonnull, nndiscr,
1065- ref nullfields, .. } => {
1066- if discr == nndiscr { nonnull. fields . len ( ) } else { nullfields. len ( ) }
1067- }
1068- }
1069- }
1070-
1071996/// Access a field, at a point when the value's case is known.
1072997pub fn trans_field_ptr < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > , r : & Repr < ' tcx > ,
1073998 val : MaybeSizedValue , discr : Disr , ix : usize ) -> ValueRef {
@@ -1218,108 +1143,6 @@ fn struct_field_ptr<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
12181143 bcx. pointercast ( byte_ptr, ll_fty. ptr_to ( ) )
12191144}
12201145
1221- pub fn fold_variants < ' blk , ' tcx , F > ( bcx : Block < ' blk , ' tcx > ,
1222- r : & Repr < ' tcx > ,
1223- value : ValueRef ,
1224- mut f : F )
1225- -> Block < ' blk , ' tcx > where
1226- F : FnMut ( Block < ' blk , ' tcx > , & Struct < ' tcx > , ValueRef ) -> Block < ' blk , ' tcx > ,
1227- {
1228- let fcx = bcx. fcx ;
1229- match * r {
1230- Univariant ( ref st, _) => {
1231- f ( bcx, st, value)
1232- }
1233- General ( ity, ref cases, _) => {
1234- let ccx = bcx. ccx ( ) ;
1235-
1236- // See the comments in trans/base.rs for more information (inside
1237- // iter_structural_ty), but the gist here is that if the enum's
1238- // discriminant is *not* in the range that we're expecting (in which
1239- // case we'll take the fall-through branch on the switch
1240- // instruction) then we can't just optimize this to an Unreachable
1241- // block.
1242- //
1243- // Currently we still have filling drop, so this means that the drop
1244- // glue for enums may be called when the enum has been paved over
1245- // with the "I've been dropped" value. In this case the default
1246- // branch of the switch instruction will actually be taken at
1247- // runtime, so the basic block isn't actually unreachable, so we
1248- // need to make it do something with defined behavior. In this case
1249- // we just return early from the function.
1250- //
1251- // Note that this is also why the `trans_get_discr` below has
1252- // `false` to indicate that loading the discriminant should
1253- // not have a range assert.
1254- let ret_void_cx = fcx. new_temp_block ( "enum-variant-iter-ret-void" ) ;
1255- RetVoid ( ret_void_cx, DebugLoc :: None ) ;
1256-
1257- let discr_val = trans_get_discr ( bcx, r, value, None , false ) ;
1258- let llswitch = Switch ( bcx, discr_val, ret_void_cx. llbb , cases. len ( ) ) ;
1259- let bcx_next = fcx. new_temp_block ( "enum-variant-iter-next" ) ;
1260-
1261- for ( discr, case) in cases. iter ( ) . enumerate ( ) {
1262- let mut variant_cx = fcx. new_temp_block (
1263- & format ! ( "enum-variant-iter-{}" , & discr. to_string( ) )
1264- ) ;
1265- let rhs_val = C_integral ( ll_inttype ( ccx, ity) , discr as u64 , true ) ;
1266- AddCase ( llswitch, rhs_val, variant_cx. llbb ) ;
1267-
1268- let fields = case. fields . iter ( ) . map ( |& ty|
1269- type_of:: type_of ( bcx. ccx ( ) , ty) ) . collect :: < Vec < _ > > ( ) ;
1270- let real_ty = Type :: struct_ ( ccx, & fields[ ..] , case. packed ) ;
1271- let variant_value = PointerCast ( variant_cx, value, real_ty. ptr_to ( ) ) ;
1272-
1273- variant_cx = f ( variant_cx, case, variant_value) ;
1274- Br ( variant_cx, bcx_next. llbb , DebugLoc :: None ) ;
1275- }
1276-
1277- bcx_next
1278- }
1279- _ => bug ! ( )
1280- }
1281- }
1282-
1283- /// Access the struct drop flag, if present.
1284- pub fn trans_drop_flag_ptr < ' blk , ' tcx > ( mut bcx : Block < ' blk , ' tcx > ,
1285- r : & Repr < ' tcx > ,
1286- val : ValueRef )
1287- -> datum:: DatumBlock < ' blk , ' tcx , datum:: Expr >
1288- {
1289- let tcx = bcx. tcx ( ) ;
1290- let ptr_ty = bcx. tcx ( ) . mk_imm_ptr ( tcx. dtor_type ( ) ) ;
1291- match * r {
1292- Univariant ( ref st, dtor) if dtor_active ( dtor) => {
1293- let flag_ptr = StructGEP ( bcx, val, st. fields . len ( ) - 1 ) ;
1294- datum:: immediate_rvalue_bcx ( bcx, flag_ptr, ptr_ty) . to_expr_datumblock ( )
1295- }
1296- General ( _, _, dtor) if dtor_active ( dtor) => {
1297- let fcx = bcx. fcx ;
1298- let custom_cleanup_scope = fcx. push_custom_cleanup_scope ( ) ;
1299- let scratch = unpack_datum ! ( bcx, datum:: lvalue_scratch_datum(
1300- bcx, tcx. dtor_type( ) , "drop_flag" ,
1301- InitAlloca :: Uninit ( "drop flag itself has no dtor" ) ,
1302- cleanup:: CustomScope ( custom_cleanup_scope) , |bcx, _| {
1303- debug!( "no-op populate call for trans_drop_flag_ptr on dtor_type={:?}" ,
1304- tcx. dtor_type( ) ) ;
1305- bcx
1306- }
1307- ) ) ;
1308- bcx = fold_variants ( bcx, r, val, |variant_cx, st, value| {
1309- let ptr = struct_field_ptr ( & variant_cx. build ( ) , st,
1310- MaybeSizedValue :: sized ( value) ,
1311- ( st. fields . len ( ) - 1 ) , false ) ;
1312- datum:: Datum :: new ( ptr, ptr_ty, datum:: Lvalue :: new ( "adt::trans_drop_flag_ptr" ) )
1313- . store_to ( variant_cx, scratch. val )
1314- } ) ;
1315- let expr_datum = scratch. to_expr_datum ( ) ;
1316- fcx. pop_custom_cleanup_scope ( custom_cleanup_scope) ;
1317- datum:: DatumBlock :: new ( bcx, expr_datum)
1318- }
1319- _ => bug ! ( "tried to get drop flag of non-droppable type" )
1320- }
1321- }
1322-
13231146/// Construct a constant value, suitable for initializing a
13241147/// GlobalVariable, given a case and constant values for its fields.
13251148/// Note that this may have a different LLVM type (and different
@@ -1458,28 +1281,6 @@ fn padding(ccx: &CrateContext, size: u64) -> ValueRef {
14581281#[ inline]
14591282fn roundup ( x : u64 , a : u32 ) -> u64 { let a = a as u64 ; ( ( x + ( a - 1 ) ) / a) * a }
14601283
1461- /// Get the discriminant of a constant value.
1462- pub fn const_get_discrim ( r : & Repr , val : ValueRef ) -> Disr {
1463- match * r {
1464- CEnum ( ity, _, _) => {
1465- match ity {
1466- attr:: SignedInt ( ..) => Disr ( const_to_int ( val) as u64 ) ,
1467- attr:: UnsignedInt ( ..) => Disr ( const_to_uint ( val) ) ,
1468- }
1469- }
1470- General ( ity, _, _) => {
1471- match ity {
1472- attr:: SignedInt ( ..) => Disr ( const_to_int ( const_get_elt ( val, & [ 0 ] ) ) as u64 ) ,
1473- attr:: UnsignedInt ( ..) => Disr ( const_to_uint ( const_get_elt ( val, & [ 0 ] ) ) )
1474- }
1475- }
1476- Univariant ( ..) => Disr ( 0 ) ,
1477- RawNullablePointer { .. } | StructWrappedNullablePointer { .. } => {
1478- bug ! ( "const discrim access of non c-like enum" )
1479- }
1480- }
1481- }
1482-
14831284/// Extract a field of a constant value, as appropriate for its
14841285/// representation.
14851286///
0 commit comments