@@ -151,6 +151,7 @@ use middle::const_eval;
151
151
use middle:: borrowck:: root_map_key;
152
152
use middle:: pat_util:: * ;
153
153
use middle:: resolve:: DefMap ;
154
+ use middle:: trans:: adt;
154
155
use middle:: trans:: base:: * ;
155
156
use middle:: trans:: build:: * ;
156
157
use middle:: trans:: callee;
@@ -191,15 +192,15 @@ pub enum Lit {
191
192
// range)
192
193
pub enum Opt {
193
194
lit( Lit ) ,
194
- var( /* disr val */ int , /* variant dids (enm, var) */ ( def_id , def_id ) ) ,
195
+ var( /* disr val */ int , adt :: Repr ) ,
195
196
range( @ast:: expr , @ast:: expr ) ,
196
197
vec_len_eq( uint ) ,
197
198
vec_len_ge( uint )
198
199
}
199
200
200
201
pub fn opt_eq( tcx : ty:: ctxt , a : & Opt , b : & Opt ) -> bool {
201
- match ( * a, * b) {
202
- ( lit( a) , lit( b) ) => {
202
+ match ( a, b) {
203
+ ( & lit( a) , & lit( b) ) => {
203
204
match ( a, b) {
204
205
( UnitLikeStructLit ( a) , UnitLikeStructLit ( b) ) => a == b,
205
206
_ => {
@@ -233,13 +234,13 @@ pub fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool {
233
234
}
234
235
}
235
236
}
236
- (range(a1, a2), range(b1, b2)) => {
237
+ (& range(a1, a2), & range(b1, b2)) => {
237
238
const_eval::compare_lit_exprs(tcx, a1, b1) == 0 &&
238
239
const_eval::compare_lit_exprs(tcx, a2, b2) == 0
239
240
}
240
- (var(a, _), var(b, _)) => a == b,
241
- (vec_len_eq(a), vec_len_eq(b)) => a == b,
242
- (vec_len_ge(a), vec_len_ge(b)) => a == b,
241
+ (& var(a, _), & var(b, _)) => a == b,
242
+ (& vec_len_eq(a), & vec_len_eq(b)) => a == b,
243
+ (& vec_len_ge(a), & vec_len_ge(b)) => a == b,
243
244
_ => false
244
245
}
245
246
}
@@ -267,8 +268,8 @@ pub fn trans_opt(bcx: block, o: &Opt) -> opt_result {
267
268
let llval = consts::get_const_val(bcx.ccx(), lit_id);
268
269
return single_result(rslt(bcx, llval));
269
270
}
270
- var(disr_val, _ ) => {
271
- return single_result(rslt( bcx, C_int(ccx , disr_val)) );
271
+ var(disr_val, ref repr ) => {
272
+ return adt::trans_case( bcx, repr , disr_val);
272
273
}
273
274
range(l1, l2) => {
274
275
return range_result(rslt(bcx, consts::const_expr(ccx, l1)),
@@ -283,13 +284,16 @@ pub fn trans_opt(bcx: block, o: &Opt) -> opt_result {
283
284
}
284
285
}
285
286
286
- pub fn variant_opt(tcx: ty::ctxt, pat_id: ast::node_id) -> Opt {
287
- match tcx.def_map.get(&pat_id) {
287
+ pub fn variant_opt(bcx: block, pat_id: ast::node_id)
288
+ -> Opt {
289
+ let ccx = bcx.ccx();
290
+ match ccx.tcx.def_map.get(&pat_id) {
288
291
ast::def_variant(enum_id, var_id) => {
289
- let variants = ty::enum_variants(tcx, enum_id);
292
+ let variants = ty::enum_variants(ccx. tcx, enum_id);
290
293
for vec::each(*variants) |v| {
291
294
if var_id == v.id {
292
- return var(v.disr_val, (enum_id, var_id));
295
+ return var(v.disr_val,
296
+ adt::represent_node(bcx, pat_id))
293
297
}
294
298
}
295
299
::core::util::unreachable();
@@ -298,7 +302,7 @@ pub fn variant_opt(tcx: ty::ctxt, pat_id: ast::node_id) -> Opt {
298
302
return lit(UnitLikeStructLit(pat_id));
299
303
}
300
304
_ => {
301
- tcx .sess.bug(~" non-variant or struct in variant_opt( ) ");
305
+ ccx .sess.bug(~" non-variant or struct in variant_opt( ) ");
302
306
}
303
307
}
304
308
}
@@ -505,7 +509,7 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
505
509
do enter_match(bcx, tcx.def_map, m, col, val) |p| {
506
510
match /*bad*/copy p.node {
507
511
ast::pat_enum(_, subpats) => {
508
- if opt_eq(tcx, &variant_opt(tcx , p.id), opt) {
512
+ if opt_eq(tcx, &variant_opt(bcx , p.id), opt) {
509
513
Some(option::get_or_default(subpats,
510
514
vec::from_elem(variant_size,
511
515
dummy)))
@@ -515,7 +519,7 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
515
519
}
516
520
ast::pat_ident(_, _, None)
517
521
if pat_is_variant_or_struct(tcx.def_map, p) => {
518
- if opt_eq(tcx, &variant_opt(tcx , p.id), opt) {
522
+ if opt_eq(tcx, &variant_opt(bcx , p.id), opt) {
519
523
Some(~[])
520
524
} else {
521
525
None
@@ -537,7 +541,7 @@ pub fn enter_opt(bcx: block, m: &[@Match/&r], opt: &Opt, col: uint,
537
541
if opt_eq(tcx, &range(l1, l2), opt) {Some(~[])} else {None}
538
542
}
539
543
ast::pat_struct(_, field_pats, _) => {
540
- if opt_eq(tcx, &variant_opt(tcx , p.id), opt) {
544
+ if opt_eq(tcx, &variant_opt(bcx , p.id), opt) {
541
545
// Look up the struct variant ID.
542
546
let struct_id;
543
547
match tcx.def_map.get(&p.id) {
@@ -762,8 +766,9 @@ pub fn enter_region(bcx: block,
762
766
// Returns the options in one column of matches. An option is something that
763
767
// needs to be conditionally matched at runtime; for example, the discriminant
764
768
// on a set of enum variants or a literal.
765
- pub fn get_options(ccx: @CrateContext, m: &[@Match], col: uint) -> ~[Opt] {
766
- fn add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, val: Opt) {
769
+ pub fn get_options(bcx: block, m: &[@Match], col: uint) -> ~[Opt] {
770
+ let ccx = bcx.ccx();
771
+ fn add_to_set(tcx: ty::ctxt, set: &DVec<Opt>, +val: Opt) {
767
772
if set.any(|l| opt_eq(tcx, l, &val)) {return;}
768
773
set.push(val);
769
774
}
@@ -781,7 +786,7 @@ pub fn get_options(ccx: @CrateContext, m: &[@Match], col: uint) -> ~[Opt] {
781
786
match ccx.tcx.def_map.find(&cur.id) {
782
787
Some(ast::def_variant(*)) => {
783
788
add_to_set(ccx.tcx, &found,
784
- variant_opt(ccx.tcx , cur.id));
789
+ variant_opt(bcx , cur.id));
785
790
}
786
791
Some(ast::def_struct(*)) => {
787
792
add_to_set(ccx.tcx, &found,
@@ -800,7 +805,7 @@ pub fn get_options(ccx: @CrateContext, m: &[@Match], col: uint) -> ~[Opt] {
800
805
match ccx.tcx.def_map.find(&cur.id) {
801
806
Some(ast::def_variant(*)) => {
802
807
add_to_set(ccx.tcx, &found,
803
- variant_opt(ccx.tcx , cur.id));
808
+ variant_opt(bcx , cur.id));
804
809
}
805
810
_ => {}
806
811
}
@@ -827,34 +832,13 @@ pub struct ExtractedBlock {
827
832
}
828
833
829
834
pub fn extract_variant_args(bcx: block,
830
- pat_id: ast::node_id ,
831
- vdefs: (def_id, def_id) ,
835
+ repr: &adt::Repr ,
836
+ disr_val: int ,
832
837
val: ValueRef)
833
- -> ExtractedBlock {
834
- let (enm, evar) = vdefs;
838
+ -> ExtractedBlock {
835
839
let _icx = bcx.insn_ctxt(" match :: extract_variant_args");
836
- let ccx = *bcx.fcx.ccx;
837
- let enum_ty_substs = match ty::get(node_id_type(bcx, pat_id)).sty {
838
- ty::ty_enum(id, ref substs) => {
839
- assert id == enm;
840
- /*bad*/copy (*substs).tps
841
- }
842
- _ => bcx.sess().bug(~" extract_variant_args: pattern has non-enum type ")
843
- };
844
- let mut blobptr = val;
845
- let variants = ty::enum_variants(ccx.tcx, enm);
846
- let size = ty::enum_variant_with_id(ccx.tcx, enm,
847
- evar).args.len();
848
- if size > 0u && (*variants).len() != 1u {
849
- let enumptr =
850
- PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
851
- blobptr = GEPi(bcx, enumptr, [0u, 1u]);
852
- }
853
- let vdefs_tg = enm;
854
- let vdefs_var = evar;
855
- let args = do vec::from_fn(size) |i| {
856
- GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var,
857
- /*bad*/copy enum_ty_substs, i)
840
+ let args = do vec::from_fn(adt::num_args(repr, disr_val)) |i| {
841
+ adt::trans_GEP(bcx, repr, val, disr_val, i)
858
842
};
859
843
860
844
ExtractedBlock { vals: args, bcx: bcx }
@@ -1365,37 +1349,15 @@ pub fn compile_submatch(bcx: block,
1365
1349
}
1366
1350
1367
1351
// Decide what kind of branch we need
1368
- let opts = get_options(ccx , m, col);
1352
+ let opts = get_options(bcx , m, col);
1369
1353
let mut kind = no_branch;
1370
1354
let mut test_val = val;
1371
1355
if opts.len() > 0u {
1372
1356
match opts[0] {
1373
- var(_, (enm, _)) => {
1374
- let variants = ty::enum_variants(tcx, enm);
1375
- if variants.len() == 1 {
1376
- kind = single;
1377
- } else {
1378
- let enumptr =
1379
- PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
1380
- let discrimptr = GEPi(bcx, enumptr, [0u, 0u]);
1381
-
1382
-
1383
- assert variants.len() > 1;
1384
- let min_discrim = do variants.foldr(0) |&x, y| {
1385
- int::min(x.disr_val, y)
1386
- };
1387
- let max_discrim = do variants.foldr(0) |&x, y| {
1388
- int::max(x.disr_val, y)
1389
- };
1390
-
1391
- test_val = LoadRangeAssert(bcx, discrimptr,
1392
- min_discrim as c_ulonglong,
1393
- (max_discrim + 1)
1394
- as c_ulonglong,
1395
- lib::llvm::True);
1396
-
1397
- kind = switch;
1398
- }
1357
+ var(_, ref repr) => {
1358
+ let (the_kind, val_opt) = adt::trans_switch(bcx, repr, val);
1359
+ kind = the_kind;
1360
+ for val_opt.each |&tval| { test_val = tval; }
1399
1361
}
1400
1362
lit(_) => {
1401
1363
let pty = node_id_type(bcx, pat_id);
@@ -1544,11 +1506,12 @@ pub fn compile_submatch(bcx: block,
1544
1506
let mut size = 0u;
1545
1507
let mut unpacked = ~[];
1546
1508
match *opt {
1547
- var(_, vdef) => {
1548
- let args = extract_variant_args(opt_cx, pat_id, vdef, val);
1549
- size = args.vals.len();
1550
- unpacked = /*bad*/copy args.vals;
1551
- opt_cx = args.bcx;
1509
+ var(disr_val, ref repr) => {
1510
+ let ExtractedBlock {vals: argvals, bcx: new_bcx} =
1511
+ extract_variant_args(opt_cx, repr, disr_val, val);
1512
+ size = argvals.len();
1513
+ unpacked = argvals;
1514
+ opt_cx = new_bcx;
1552
1515
}
1553
1516
vec_len_eq(n) | vec_len_ge(n) => {
1554
1517
let tail = match *opt {
@@ -1757,10 +1720,15 @@ pub fn bind_irrefutable_pat(bcx: block,
1757
1720
}
1758
1721
ast:: pat_enum( _, sub_pats) => {
1759
1722
match bcx. tcx ( ) . def_map . find ( & pat. id ) {
1760
- Some ( ast:: def_variant( * ) ) => {
1761
- let pat_def = ccx. tcx . def_map . get ( & pat. id ) ;
1762
- let vdefs = ast_util:: variant_def_ids ( pat_def) ;
1763
- let args = extract_variant_args ( bcx, pat. id , vdefs, val) ;
1723
+ Some ( ast:: def_variant( enum_id, var_id) ) => {
1724
+ let repr = adt:: represent_node ( bcx, pat. id ) ;
1725
+ let vinfo = ty:: enum_variant_with_id ( ccx. tcx ,
1726
+ enum_id,
1727
+ var_id) ;
1728
+ let args = extract_variant_args ( bcx,
1729
+ & repr,
1730
+ vinfo. disr_val ,
1731
+ val) ;
1764
1732
for sub_pats. each |sub_pat| {
1765
1733
for vec:: eachi( args. vals) |i, argval| {
1766
1734
bcx = bind_irrefutable_pat ( bcx,
0 commit comments