@@ -20,9 +20,12 @@ import util.common.new_str_hash;
20
20
21
21
import lib. llvm . llvm ;
22
22
import lib. llvm . builder ;
23
+ import lib. llvm . type_handle ;
24
+ import lib. llvm . mk_type_handle ;
23
25
import lib. llvm . llvm . ModuleRef ;
24
26
import lib. llvm . llvm . ValueRef ;
25
27
import lib. llvm . llvm . TypeRef ;
28
+ import lib. llvm . llvm . TypeHandleRef ;
26
29
import lib. llvm . llvm . BuilderRef ;
27
30
import lib. llvm . llvm . BasicBlockRef ;
28
31
@@ -41,13 +44,18 @@ type glue_fns = rec(ValueRef activate_glue,
41
44
ValueRef exit_task_glue ,
42
45
vec[ ValueRef ] upcall_glues ) ;
43
46
47
+ type tag_info = rec ( type_handle th,
48
+ hashmap[ ast. def_id, uint] variant_indices ,
49
+ hashmap[ ast. def_id, uint] n_ary_variant_indices ) ;
50
+
44
51
state type crate_ctxt = rec ( session. session sess,
45
52
ModuleRef llmod,
46
53
hashmap[ str, ValueRef ] upcalls,
47
54
hashmap[ str, ValueRef ] intrinsics,
48
55
hashmap[ str, ValueRef ] fn_names,
49
56
hashmap[ ast. def_id , ValueRef ] fn_ids,
50
57
hashmap[ ast. def_id , @ast. item ] items,
58
+ hashmap[ ast. def_id , tag_info] tags,
51
59
@glue_fns glues,
52
60
namegen names,
53
61
str path) ;
@@ -177,6 +185,11 @@ fn T_struct(vec[TypeRef] elts) -> TypeRef {
177
185
False ) ;
178
186
}
179
187
188
+ fn T_union ( vec[ TypeRef ] elts ) -> TypeRef {
189
+ ret llvm. LLVMUnionType ( _vec. buf [ TypeRef ] ( elts) ,
190
+ _vec. len [ TypeRef ] ( elts) ) ;
191
+ }
192
+
180
193
fn T_opaque ( ) -> TypeRef {
181
194
ret llvm. LLVMOpaqueType ( ) ;
182
195
}
@@ -267,6 +280,9 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
267
280
}
268
281
case ( typeck. ty_char ) { ret T_char ( ) ; }
269
282
case ( typeck. ty_str ) { ret T_ptr ( T_str ( ) ) ; }
283
+ case ( typeck. ty_tag ( ?tag_id) ) {
284
+ ret llvm. LLVMResolveTypeHandle ( cx. tags . get ( tag_id) . th . llth ) ;
285
+ }
270
286
case ( typeck. ty_box ( ?t) ) {
271
287
ret T_ptr ( T_box ( type_of ( cx, t) ) ) ;
272
288
}
@@ -1114,6 +1130,19 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt)
1114
1130
ret tup( res ( cx, cx. fcx . ccx . fn_ids . get ( did) ) ,
1115
1131
false ) ;
1116
1132
}
1133
+ case ( ast. def_variant ( ?tid, ?vid) ) {
1134
+ check ( cx. fcx . ccx . tags . contains_key ( tid) ) ;
1135
+ auto info = cx. fcx . ccx . tags . get ( tid) ;
1136
+ if ( info. n_ary_variant_indices . contains_key ( vid) ) {
1137
+ cx. fcx . ccx . sess . unimpl ( "n-ary tag constructors in " +
1138
+ "trans" ) ;
1139
+ } else {
1140
+ // Nullary tag variant case.
1141
+ auto idx = info. variant_indices . get ( vid) ;
1142
+ auto elems = vec ( C_int ( idx as int ) ) ;
1143
+ ret tup( res ( cx, C_struct ( elems) ) , false ) ;
1144
+ }
1145
+ }
1117
1146
case ( _) {
1118
1147
cx. fcx . ccx . sess . unimpl ( "def variant in trans" ) ;
1119
1148
}
@@ -1645,6 +1674,15 @@ impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
1645
1674
}
1646
1675
}
1647
1676
1677
+ fn trans_tag_variant ( @crate_ctxt cx , ast. def_id tag_id ,
1678
+ & ast. variant variant ) {
1679
+ if ( _vec. len [ @ast. ty ] ( variant. args ) == 0 u) {
1680
+ ret; // nullary constructors are just constants
1681
+ }
1682
+
1683
+ // TODO
1684
+ }
1685
+
1648
1686
impure fn trans_item ( @crate_ctxt cx , & ast . item item) {
1649
1687
alt ( item. node ) {
1650
1688
case ( ast. item_fn ( ?name, ?f, _, ?fid, ?ann) ) {
@@ -1655,6 +1693,12 @@ impure fn trans_item(@crate_ctxt cx, &ast.item item) {
1655
1693
auto sub_cx = @rec ( path=cx. path + "." + name with * cx) ;
1656
1694
trans_mod ( sub_cx, m) ;
1657
1695
}
1696
+ case ( ast. item_tag ( ?name, ?variants, _, ?tag_id) ) {
1697
+ auto sub_cx = @rec ( path=cx. path + "." + name with * cx) ;
1698
+ for ( ast. variant variant in variants) {
1699
+ trans_tag_variant ( sub_cx, tag_id, variant) ;
1700
+ }
1701
+ }
1658
1702
case ( _) { /* fall through */ }
1659
1703
}
1660
1704
}
@@ -1666,6 +1710,60 @@ impure fn trans_mod(@crate_ctxt cx, &ast._mod m) {
1666
1710
}
1667
1711
1668
1712
1713
+ fn resolve_tag_types_for_item ( & @crate_ctxt cx , @ast. item i ) -> @crate_ctxt {
1714
+ alt ( i. node ) {
1715
+ case ( ast. item_tag ( _, ?variants, _, ?tag_id) ) {
1716
+ let vec[ TypeRef ] variant_tys = vec ( ) ;
1717
+
1718
+ auto info = cx. tags . get ( tag_id) ;
1719
+ auto variant_indices = info. variant_indices ;
1720
+ auto n_ary_variant_indices = info. n_ary_variant_indices ;
1721
+
1722
+ auto tag_ty;
1723
+ if ( _vec. len [ ast. variant ] ( variants) == 0 u) {
1724
+ tag_ty = T_struct ( vec ( T_int ( ) ) ) ;
1725
+ } else {
1726
+ auto variant_idx = 0 u;
1727
+ auto n_ary_variant_idx = 0 u;
1728
+
1729
+ for ( ast. variant variant in variants) {
1730
+ if ( _vec. len [ @ast. ty ] ( variant. args ) > 0 u) {
1731
+ let vec[ TypeRef ] lltys = vec ( ) ;
1732
+
1733
+ alt ( typeck. ann_to_type ( variant. ann ) . struct ) {
1734
+ case ( typeck. ty_fn ( ?args, _) ) {
1735
+ for ( typeck. arg arg in args) {
1736
+ lltys += vec ( type_of ( cx, arg. ty ) ) ;
1737
+ }
1738
+ }
1739
+ case ( _) { fail; }
1740
+ }
1741
+
1742
+ variant_tys += vec ( T_struct ( lltys) ) ;
1743
+
1744
+ n_ary_variant_indices. insert ( variant. id ,
1745
+ n_ary_variant_idx) ;
1746
+ n_ary_variant_idx += 1 u;
1747
+ }
1748
+
1749
+ variant_indices. insert ( variant. id , variant_idx) ;
1750
+ variant_idx += 1 u;
1751
+ }
1752
+
1753
+ tag_ty = T_struct ( vec ( T_int ( ) , T_union ( variant_tys) ) ) ;
1754
+ }
1755
+
1756
+ auto th = cx. tags . get ( tag_id) . th . llth ;
1757
+ llvm. LLVMRefineType ( llvm. LLVMResolveTypeHandle ( th) , tag_ty) ;
1758
+ }
1759
+ case ( _) {
1760
+ // fall through
1761
+ }
1762
+ }
1763
+
1764
+ ret cx;
1765
+ }
1766
+
1669
1767
fn collect_item ( & @crate_ctxt cx , @ast. item i ) -> @crate_ctxt {
1670
1768
alt ( i. node ) {
1671
1769
case ( ast. item_fn ( ?name, ?f, _, ?fid, ?ann) ) {
@@ -1680,6 +1778,15 @@ fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
1680
1778
case ( ast. item_mod ( ?name, ?m, ?mid) ) {
1681
1779
cx. items . insert ( mid, i) ;
1682
1780
}
1781
+
1782
+ case ( ast. item_tag ( _, ?variants, _, ?tag_id) ) {
1783
+ auto vi = new_def_hash[ uint] ( ) ;
1784
+ auto navi = new_def_hash[ uint] ( ) ;
1785
+ cx. tags . insert ( tag_id, rec ( th=mk_type_handle ( ) ,
1786
+ variant_indices=vi,
1787
+ n_ary_variant_indices=navi) ) ;
1788
+ }
1789
+
1683
1790
case ( _) { /* fall through */ }
1684
1791
}
1685
1792
ret cx;
@@ -1697,6 +1804,16 @@ fn collect_items(@crate_ctxt cx, @ast.crate crate) {
1697
1804
fold. fold_crate [ @crate_ctxt] ( cx, fld, crate ) ;
1698
1805
}
1699
1806
1807
+ fn resolve_tag_types ( @crate_ctxt cx , @ast. crate crate) {
1808
+ let fold. ast_fold[ @crate_ctxt] fld =
1809
+ fold. new_identity_fold [ @crate_ctxt] ( ) ;
1810
+
1811
+ fld = @rec ( update_env_for_item = bind resolve_tag_types_for_item ( _, _)
1812
+ with * fld ) ;
1813
+
1814
+ fold. fold_crate [ @crate_ctxt] ( cx, fld, crate ) ;
1815
+ }
1816
+
1700
1817
fn p2i ( ValueRef v) -> ValueRef {
1701
1818
ret llvm. LLVMConstPtrToInt ( v, T_int ( ) ) ;
1702
1819
}
@@ -1856,11 +1973,14 @@ fn trans_crate(session.session sess, @ast.crate crate, str output) {
1856
1973
fn_names = new_str_hash[ ValueRef ] ( ) ,
1857
1974
fn_ids = new_def_hash[ ValueRef ] ( ) ,
1858
1975
items = new_def_hash[ @ast. item ] ( ) ,
1976
+ tags = new_def_hash[ tag_info] ( ) ,
1859
1977
glues = glues,
1860
1978
names = namegen ( 0 ) ,
1861
1979
path = "_rust" ) ;
1862
1980
1863
1981
collect_items ( cx, crate ) ;
1982
+ resolve_tag_types ( cx, crate ) ;
1983
+
1864
1984
trans_mod ( cx, crate . node. module ) ;
1865
1985
trans_exit_task_glue ( cx) ;
1866
1986
trans_main_fn ( cx, crate_constant ( cx) ) ;
0 commit comments