@@ -3679,6 +3679,24 @@ fn lval_generic_fn(@block_ctxt cx,
3679
3679
ret lv;
3680
3680
}
3681
3681
3682
+ fn lookup_discriminant( @crate_ctxt ccx, ast. def_id tid, ast. def_id vid)
3683
+ -> ValueRef {
3684
+ alt ( ccx. discrims. find( vid) ) {
3685
+ case ( none[ ValueRef ] ) {
3686
+ // It's an external discriminant that we haven't seen yet.
3687
+ check ( ccx. sess. get_targ_crate_num( ) != vid. _0) ;
3688
+ auto sym = creader. get_symbol( ccx. sess, vid) ;
3689
+ auto gvar = llvm. LLVMAddGlobal ( ccx. llmod, T_int ( ) , _str. buf( sym) ) ;
3690
+ llvm. LLVMSetLinkage ( gvar,
3691
+ lib. llvm. LLVMExternalLinkage as llvm. Linkage ) ;
3692
+ llvm. LLVMSetGlobalConstant ( gvar, True ) ;
3693
+ ccx. discrims. insert( vid, gvar) ;
3694
+ ret gvar;
3695
+ }
3696
+ case ( some[ ValueRef ] ( ?llval) ) { ret llval; }
3697
+ }
3698
+ }
3699
+
3682
3700
fn trans_path( @block_ctxt cx, & ast. path p, & option. t[ ast. def] dopt,
3683
3701
& ast. ann ann) -> lval_result {
3684
3702
alt ( dopt) {
@@ -3725,46 +3743,39 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
3725
3743
ret lval_generic_fn( cx, tyt, did, ann) ;
3726
3744
}
3727
3745
case ( ast. def_variant( ?tid, ?vid) ) {
3728
- // TODO: externals
3729
- if ( cx. fcx. ccx. fn_pairs. contains_key( vid) ) {
3730
- check ( cx. fcx. ccx. items. contains_key( tid) ) ;
3731
- auto tag_item = cx. fcx. ccx. items. get( tid) ;
3732
- auto params = ty. item_ty( tag_item) . _0;
3733
- auto fty = plain_ty( ty. ty_nil) ;
3734
- alt ( tag_item. node) {
3735
- case ( ast. item_tag( _, ?variants, _, _, _) ) {
3736
- for ( ast. variant v in variants) {
3737
- if ( v. node. id == vid) {
3738
- fty = node_ann_type( cx. fcx. ccx,
3739
- v. node. ann) ;
3740
- }
3741
- }
3742
- }
3743
- }
3744
- ret lval_generic_fn( cx, tup( params, fty) , vid, ann) ;
3745
- } else {
3746
- // Nullary variant.
3747
- auto tag_ty = node_ann_type( cx. fcx. ccx, ann) ;
3748
- auto lldiscrim_gv = cx. fcx. ccx. discrims. get( vid) ;
3749
- auto lldiscrim = cx. build. Load ( lldiscrim_gv) ;
3750
-
3751
- auto alloc_result = alloc_ty( cx, tag_ty) ;
3752
- auto lltagblob = alloc_result. val;
3753
-
3754
- auto lltagty;
3755
- if ( ty. type_has_dynamic_size( tag_ty) ) {
3756
- lltagty = T_opaque_tag ( cx. fcx. ccx. tn) ;
3757
- } else {
3758
- lltagty = type_of( cx. fcx. ccx, tag_ty) ;
3746
+ auto v_tyt = ty. lookup_generic_item_type( cx. fcx. ccx. sess,
3747
+ cx. fcx. ccx. type_cache, vid) ;
3748
+ alt ( v_tyt. _1. struct ) {
3749
+ case ( ty. ty_fn( _, _, _) ) {
3750
+ // N-ary variant.
3751
+ ret lval_generic_fn( cx, v_tyt, vid, ann) ;
3759
3752
}
3760
- auto lltagptr = alloc_result. bcx. build. PointerCast (
3761
- lltagblob, T_ptr ( lltagty) ) ;
3753
+ case ( _) {
3754
+ // Nullary variant.
3755
+ auto tag_ty = node_ann_type( cx. fcx. ccx, ann) ;
3756
+ auto lldiscrim_gv =
3757
+ lookup_discriminant( cx. fcx. ccx, tid, vid) ;
3758
+ auto lldiscrim = cx. build. Load ( lldiscrim_gv) ;
3759
+
3760
+ auto alloc_result = alloc_ty( cx, tag_ty) ;
3761
+ auto lltagblob = alloc_result. val;
3762
+
3763
+ auto lltagty;
3764
+ if ( ty. type_has_dynamic_size( tag_ty) ) {
3765
+ lltagty = T_opaque_tag ( cx. fcx. ccx. tn) ;
3766
+ } else {
3767
+ lltagty = type_of( cx. fcx. ccx, tag_ty) ;
3768
+ }
3769
+ auto lltagptr = alloc_result. bcx. build. PointerCast (
3770
+ lltagblob, T_ptr ( lltagty) ) ;
3762
3771
3763
- auto lldiscrimptr = alloc_result. bcx. build. GEP (
3764
- lltagptr, vec( C_int ( 0 ) , C_int ( 0 ) ) ) ;
3765
- alloc_result. bcx. build. Store ( lldiscrim, lldiscrimptr) ;
3772
+ auto lldiscrimptr = alloc_result. bcx. build. GEP (
3773
+ lltagptr, vec( C_int ( 0 ) , C_int ( 0 ) ) ) ;
3774
+ alloc_result. bcx. build. Store ( lldiscrim,
3775
+ lldiscrimptr) ;
3766
3776
3767
- ret lval_val( alloc_result. bcx, lltagptr) ;
3777
+ ret lval_val( alloc_result. bcx, lltagptr) ;
3778
+ }
3768
3779
}
3769
3780
}
3770
3781
case ( ast. def_const( ?did) ) {
@@ -6378,25 +6389,22 @@ fn collect_tag_ctors(@crate_ctxt cx, @ast.crate crate) {
6378
6389
6379
6390
fn trans_constant ( & @crate_ctxt cx , @ast. item it ) -> @crate_ctxt {
6380
6391
alt ( it. node ) {
6381
- case ( ast. item_tag ( _ , ?variants, _, ?tag_id, _) ) {
6392
+ case ( ast. item_tag ( ?ident , ?variants, _, ?tag_id, _) ) {
6382
6393
auto i = 0 u;
6383
6394
auto n_variants = _vec. len [ ast. variant ] ( variants) ;
6384
6395
while ( i < n_variants) {
6385
6396
auto variant = variants. ( i) ;
6386
6397
6387
6398
auto discrim_val = C_int ( i as int ) ;
6388
6399
6389
- // FIXME: better name.
6390
- auto s = cx. names . next ( "_rust_tag_discrim" ) ;
6400
+ auto s = mangle_name_by_seq ( cx,
6401
+ #fmt ( "_rust_tag_discrim_%s_%u" ,
6402
+ ident, i) ) ;
6391
6403
auto discrim_gvar = llvm. LLVMAddGlobal ( cx. llmod , T_int ( ) ,
6392
6404
_str. buf ( s) ) ;
6393
6405
6394
- // FIXME: Eventually we do want to export these, but we need
6395
- // to figure out what name they get first!
6396
6406
llvm. LLVMSetInitializer ( discrim_gvar, discrim_val) ;
6397
6407
llvm. LLVMSetGlobalConstant ( discrim_gvar, True ) ;
6398
- llvm. LLVMSetLinkage ( discrim_gvar, lib. llvm . LLVMInternalLinkage
6399
- as llvm . Linkage ) ;
6400
6408
6401
6409
cx. discrims . insert ( variant. node . id , discrim_gvar) ;
6402
6410
cx. discrim_symbols . insert ( variant. node . id , s) ;
0 commit comments