@@ -397,6 +397,16 @@ fn T_opaque_closure_ptr(type_names tn) -> TypeRef {
397
397
ret t;
398
398
}
399
399
400
+ fn T_opaque_tag_ptr ( type_names tn) -> TypeRef {
401
+ auto s = "*tag" ;
402
+ if ( tn. name_has_type ( s) ) {
403
+ ret tn. get_type ( s) ;
404
+ }
405
+ auto t = T_ptr ( T_struct ( vec ( T_int ( ) , T_i8 ( ) ) ) ) ;
406
+ tn. associate ( s, t) ;
407
+ ret t;
408
+ }
409
+
400
410
fn T_captured_tydescs ( type_names tn, uint n) -> TypeRef {
401
411
ret T_struct ( _vec. init_elt [ TypeRef ] ( T_ptr ( T_tydesc ( tn) ) , n) ) ;
402
412
}
@@ -4576,27 +4586,41 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
4576
4586
auto arg_tys = arg_tys_of_fn( variant. ann) ;
4577
4587
copy_args_to_allocas( bcx, none[ TypeRef ] , fn_args, arg_tys) ;
4578
4588
4579
- auto lldiscrimptr = bcx. build. GEP ( fcx. llretptr,
4589
+ // Now synthesize a tuple type for the arguments, so that GEP_tup_like()
4590
+ // will know what the data part of the variant looks like.
4591
+ let vec[ @ty. t] true_arg_tys = vec( ) ;
4592
+ for ( ty. arg a in arg_tys) {
4593
+ true_arg_tys += vec( a. ty) ;
4594
+ }
4595
+ auto tup_ty = ty. plain_ty( ty. ty_tup( true_arg_tys) ) ;
4596
+
4597
+ // Cast the tag to a type we can GEP into.
4598
+ auto lltagptr = bcx. build. PointerCast ( fcx. llretptr,
4599
+ T_opaque_tag_ptr ( fcx. ccx. tn) ) ;
4600
+
4601
+ auto lldiscrimptr = bcx. build. GEP ( lltagptr,
4580
4602
vec( C_int ( 0 ) , C_int ( 0 ) ) ) ;
4581
4603
bcx. build. Store ( C_int ( index) , lldiscrimptr) ;
4582
4604
4583
- auto llblobptr = bcx. build. GEP ( fcx . llretptr ,
4605
+ auto llblobptr = bcx. build. GEP ( lltagptr ,
4584
4606
vec( C_int ( 0 ) , C_int ( 1 ) ) ) ;
4585
4607
4586
- // First, generate the union type.
4587
- let vec[ TypeRef ] llargtys = vec( ) ;
4588
- for ( ty. arg arg in arg_tys) {
4589
- llargtys += vec( type_of( cx, arg. ty) ) ;
4608
+ // Cast the blob pointer to the appropriate type, if we need to (i.e. if
4609
+ // the blob pointer isn't dynamically sized).
4610
+ let ValueRef llunionptr;
4611
+ if ( !ty. type_has_dynamic_size( tup_ty) ) {
4612
+ auto llty = type_of( cx, tup_ty) ;
4613
+ llunionptr = bcx. build. TruncOrBitCast ( llblobptr, T_ptr ( llty) ) ;
4614
+ } else {
4615
+ llunionptr = llblobptr;
4590
4616
}
4591
4617
4592
- auto llunionty = T_struct ( llargtys) ;
4593
- auto llunionptr = bcx. build. TruncOrBitCast ( llblobptr, T_ptr ( llunionty) ) ;
4594
-
4595
4618
i = 0 u;
4596
4619
for ( ast. variant_arg va in variant. args) {
4597
4620
auto llargval = bcx. build. Load ( fcx. llargs. get( va. id) ) ;
4598
- auto lldestptr = bcx. build. GEP ( llunionptr,
4599
- vec( C_int ( 0 ) , C_int ( i as int) ) ) ;
4621
+ auto rslt = GEP_tup_like ( bcx, tup_ty, llunionptr, vec( 0 , i as int) ) ;
4622
+ bcx = rslt. bcx;
4623
+ auto lldestptr = rslt. val;
4600
4624
4601
4625
bcx. build. Store ( llargval, lldestptr) ;
4602
4626
i += 1 u;
0 commit comments