@@ -53,14 +53,9 @@ use rustc::ty::{self, Ty, TyCtxt};
53
53
use syntax:: ast;
54
54
use syntax:: attr;
55
55
use syntax:: attr:: IntType ;
56
- use _match;
57
56
use abi:: FAT_PTR_ADDR ;
58
- use base:: InitAlloca ;
59
57
use build:: * ;
60
- use cleanup;
61
- use cleanup:: CleanupMethods ;
62
58
use common:: * ;
63
- use datum;
64
59
use debuginfo:: DebugLoc ;
65
60
use glue;
66
61
use machine;
@@ -69,6 +64,12 @@ use type_::Type;
69
64
use type_of;
70
65
use value:: Value ;
71
66
67
+ #[ derive( Copy , Clone , PartialEq ) ]
68
+ pub enum BranchKind {
69
+ Switch ,
70
+ Single
71
+ }
72
+
72
73
type Hint = attr:: ReprAttr ;
73
74
74
75
// Representation of the context surrounding an unsized type. I want
@@ -178,14 +179,6 @@ impl MaybeSizedValue {
178
179
}
179
180
}
180
181
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
-
189
182
/// Decides how to represent a given type.
190
183
pub fn represent_type < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > ,
191
184
t : Ty < ' tcx > )
@@ -201,49 +194,15 @@ pub fn represent_type<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
201
194
repr
202
195
}
203
196
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
-
234
197
fn dtor_to_init_u8 ( dtor : bool ) -> u8 {
235
- if dtor { DTOR_NEEDED } else { 0 }
198
+ if dtor { 1 } else { 0 }
236
199
}
237
200
238
201
pub trait GetDtorType < ' tcx > { fn dtor_type ( self ) -> Ty < ' tcx > ; }
239
202
impl < ' a , ' tcx > GetDtorType < ' tcx > for TyCtxt < ' a , ' tcx , ' tcx > {
240
203
fn dtor_type ( self ) -> Ty < ' tcx > { self . types . u8 }
241
204
}
242
205
243
- fn dtor_active ( flag : u8 ) -> bool {
244
- flag != 0
245
- }
246
-
247
206
fn represent_type_uncached < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > ,
248
207
t : Ty < ' tcx > ) -> Repr < ' tcx > {
249
208
match t. sty {
@@ -873,22 +832,19 @@ fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, st: &Struct<'tcx>,
873
832
874
833
/// Obtain a representation of the discriminant sufficient to translate
875
834
/// destructuring; this may or may not involve the actual discriminant.
876
- ///
877
- /// This should ideally be less tightly tied to `_match`.
878
835
pub fn trans_switch < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > ,
879
836
r : & Repr < ' tcx > ,
880
837
scrutinee : ValueRef ,
881
838
range_assert : bool )
882
- -> ( _match :: BranchKind , Option < ValueRef > ) {
839
+ -> ( BranchKind , Option < ValueRef > ) {
883
840
match * r {
884
841
CEnum ( ..) | General ( ..) |
885
842
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) ) )
888
844
}
889
845
Univariant ( ..) => {
890
846
// N.B.: Univariant means <= 1 enum variants (*not* == 1 variants).
891
- ( _match :: Single , None )
847
+ ( BranchKind :: Single , None )
892
848
}
893
849
}
894
850
}
@@ -1001,21 +957,12 @@ pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
1001
957
Store ( bcx, C_integral ( ll_inttype ( bcx. ccx ( ) , ity) , discr. 0 , true ) ,
1002
958
val) ;
1003
959
}
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, _, _) => {
1010
961
Store ( bcx, C_integral ( ll_inttype ( bcx. ccx ( ) , ity) , discr. 0 , true ) ,
1011
962
StructGEP ( bcx, val, 0 ) ) ;
1012
963
}
1013
- Univariant ( ref st , dtor ) => {
964
+ Univariant ( _ , _ ) => {
1014
965
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
- }
1019
966
}
1020
967
RawNullablePointer { nndiscr, nnty, ..} => {
1021
968
if discr != nndiscr {
@@ -1046,28 +993,6 @@ fn assert_discr_in_range(ity: IntType, min: Disr, max: Disr, discr: Disr) {
1046
993
}
1047
994
}
1048
995
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
-
1071
996
/// Access a field, at a point when the value's case is known.
1072
997
pub fn trans_field_ptr < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > , r : & Repr < ' tcx > ,
1073
998
val : MaybeSizedValue , discr : Disr , ix : usize ) -> ValueRef {
@@ -1218,108 +1143,6 @@ fn struct_field_ptr<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
1218
1143
bcx. pointercast ( byte_ptr, ll_fty. ptr_to ( ) )
1219
1144
}
1220
1145
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
-
1323
1146
/// Construct a constant value, suitable for initializing a
1324
1147
/// GlobalVariable, given a case and constant values for its fields.
1325
1148
/// Note that this may have a different LLVM type (and different
@@ -1458,28 +1281,6 @@ fn padding(ccx: &CrateContext, size: u64) -> ValueRef {
1458
1281
#[ inline]
1459
1282
fn roundup ( x : u64 , a : u32 ) -> u64 { let a = a as u64 ; ( ( x + ( a - 1 ) ) / a) * a }
1460
1283
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
-
1483
1284
/// Extract a field of a constant value, as appropriate for its
1484
1285
/// representation.
1485
1286
///
0 commit comments