diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/middle/trans.rs | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index de3f99ba..61da7f53 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -59,7 +59,11 @@ type glue_fns = rec(ValueRef activate_glue, ValueRef memcpy_glue, ValueRef bzero_glue); -type tag_info = rec(type_handle th, mutable uint size); +type tag_info = rec( + type_handle th, + mutable uint size, + mutable @hashmap[ast.def_id,ValueRef] lldiscrims +); state type crate_ctxt = rec(session.session sess, ModuleRef llmod, @@ -2774,9 +2778,23 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt, } ret lval_generic_fn(cx, tup(params, fty), vid, ann); } else { - // Nullary variants are just scalar constants. - check (cx.fcx.ccx.item_ids.contains_key(vid)); - ret lval_val(cx, cx.fcx.ccx.item_ids.get(vid)); + // Nullary variant. + auto tag_ty = node_ann_type(cx.fcx.ccx, ann); + auto info = cx.fcx.ccx.tags.get(tag_ty); + check (info.lldiscrims.contains_key(vid)); + auto lldiscrim_gv = info.lldiscrims.get(vid); + auto lldiscrim = cx.build.Load(lldiscrim_gv); + + auto alloc_result = alloc_ty(cx, tag_ty); + auto lltagblob = alloc_result.val; + auto lltagptr = alloc_result.bcx.build.PointerCast( + lltagblob, T_ptr(type_of(cx.fcx.ccx, tag_ty))); + + auto lldiscrimptr = alloc_result.bcx.build.GEP( + lltagptr, vec(C_int(0), C_int(0))); + alloc_result.bcx.build.Store(lldiscrim, lldiscrimptr); + + ret lval_val(alloc_result.bcx, lltagptr); } } case (ast.def_const(?did)) { @@ -4637,8 +4655,14 @@ fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt { case (ast.item_tag(_, ?variants, ?tps, ?tag_id)) { auto vi = new_def_hash[uint](); auto navi = new_def_hash[uint](); - cx.tags.insert(mk_plain_tag(tag_id), @rec(th=mk_type_handle(), - mutable size=0u)); + + auto info = @rec( + th=mk_type_handle(), + mutable size=0u, + mutable lldiscrims=@new_def_hash[ValueRef]() + ); + + cx.tags.insert(mk_plain_tag(tag_id), info); cx.items.insert(tag_id, i); } @@ -4772,22 +4796,7 @@ fn trans_constant(&@crate_ctxt cx, @ast.item it) -> @crate_ctxt { llvm.LLVMSetLinkage(discrim_gvar, lib.llvm.LLVMPrivateLinkage as llvm.Linkage); - if (_vec.len[ast.variant_arg](variant.args) == 0u) { - // Nullary tags become constants. (N-ary tags are treated - // as functions and generated later.) - - auto union_val = C_zero_byte_arr(info.size as uint); - auto val = C_struct(vec(discrim_val, union_val)); - - // FIXME: better name - auto gvar = llvm.LLVMAddGlobal(cx.llmod, val_ty(val), - _str.buf("tag")); - llvm.LLVMSetInitializer(gvar, val); - llvm.LLVMSetGlobalConstant(gvar, True); - llvm.LLVMSetLinkage(gvar, lib.llvm.LLVMPrivateLinkage - as llvm.Linkage); - cx.item_ids.insert(variant.id, gvar); - } + info.lldiscrims.insert(variant.id, discrim_gvar); i += 1u; } |