Skip to content

Commit 5312a2d

Browse files
committed
---
yaml --- r: 1502 b: refs/heads/master c: f44fea8 h: refs/heads/master v: v3
1 parent 4a8b4f5 commit 5312a2d

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 5c7db0cde15adfda5b43112ee86d4bfe3bd9ee82
2+
refs/heads/master: f44fea8b6d77c24785fc351c5ca334df47b804b3

trunk/src/comp/middle/trans.rs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,16 @@ fn T_opaque_closure_ptr(type_names tn) -> TypeRef {
397397
ret t;
398398
}
399399

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+
400410
fn T_captured_tydescs(type_names tn, uint n) -> TypeRef {
401411
ret T_struct(_vec.init_elt[TypeRef](T_ptr(T_tydesc(tn)), n));
402412
}
@@ -4576,27 +4586,41 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
45764586
auto arg_tys = arg_tys_of_fn(variant.ann);
45774587
copy_args_to_allocas(bcx, none[TypeRef], fn_args, arg_tys);
45784588

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,
45804602
vec(C_int(0), C_int(0)));
45814603
bcx.build.Store(C_int(index), lldiscrimptr);
45824604

4583-
auto llblobptr = bcx.build.GEP(fcx.llretptr,
4605+
auto llblobptr = bcx.build.GEP(lltagptr,
45844606
vec(C_int(0), C_int(1)));
45854607

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;
45904616
}
45914617

4592-
auto llunionty = T_struct(llargtys);
4593-
auto llunionptr = bcx.build.TruncOrBitCast(llblobptr, T_ptr(llunionty));
4594-
45954618
i = 0u;
45964619
for (ast.variant_arg va in variant.args) {
45974620
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;
46004624

46014625
bcx.build.Store(llargval, lldestptr);
46024626
i += 1u;

0 commit comments

Comments
 (0)