@@ -327,6 +327,14 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
327
327
fail;
328
328
}
329
329
330
+ fn type_of_arg ( @crate_ctxt cx , & typeck . arg arg) -> TypeRef {
331
+ auto ty = type_of ( cx, arg. ty ) ;
332
+ if ( arg. mode == ast. alias ) {
333
+ ty = T_ptr ( ty) ;
334
+ }
335
+ ret ty;
336
+ }
337
+
330
338
// LLVM constant constructors.
331
339
332
340
fn C_null ( TypeRef t) -> ValueRef {
@@ -1823,7 +1831,7 @@ fn copy_args_to_allocas(@block_ctxt cx, vec[ast.arg] args,
1823
1831
let uint arg_n = 0 u;
1824
1832
1825
1833
for ( ast. arg aarg in args) {
1826
- auto arg_t = type_of ( cx. fcx. ccx, arg_tys. ( arg_n) . ty ) ;
1834
+ auto arg_t = type_of_arg ( cx. fcx. ccx, arg_tys. ( arg_n) ) ;
1827
1835
auto alloca = cx. build. Alloca ( arg_t) ;
1828
1836
auto argval = cx. fcx. llargs. get( aarg. id) ;
1829
1837
cx. build. Store ( argval, alloca) ;
@@ -1864,12 +1872,73 @@ impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
1864
1872
}
1865
1873
1866
1874
fn trans_tag_variant( @crate_ctxt cx, ast. def_id tag_id,
1867
- & ast. variant variant) {
1875
+ & ast. variant variant, int index ) {
1868
1876
if ( _vec. len[ ast. variant_arg] ( variant. args) == 0 u) {
1869
1877
ret; // nullary constructors are just constants
1870
1878
}
1871
1879
1872
- // TODO
1880
+ // Translate variant arguments to function arguments.
1881
+ let vec[ ast. arg] fn_args = vec( ) ;
1882
+ auto i = 0 u;
1883
+ for ( ast. variant_arg varg in variant. args) {
1884
+ fn_args += vec( rec( mode=ast. alias,
1885
+ ty=varg. ty,
1886
+ ident="arg" + _uint. to_str( i, 10 u) ,
1887
+ id=varg. id) ) ;
1888
+ }
1889
+
1890
+ auto var_ty = typeck. ann_to_type( variant. ann) ;
1891
+ auto llfnty = type_of( cx, var_ty) ;
1892
+
1893
+ let str s = cx. names. next( "_rust_tag" ) + "." + cx. path;
1894
+ let ValueRef llfn = decl_fastcall_fn( cx. llmod, s, llfnty) ;
1895
+ cx. item_ids. insert( variant. id, llfn) ;
1896
+
1897
+ auto fcx = new_fn_ctxt( cx, cx. path, fn_args, variant. id) ;
1898
+ auto bcx = new_top_block_ctxt( fcx) ;
1899
+
1900
+ auto arg_tys = arg_tys_of_fn( variant. ann) ;
1901
+ copy_args_to_allocas( bcx, fn_args, arg_tys) ;
1902
+
1903
+ auto info = cx. tags. get( tag_id) ;
1904
+
1905
+ auto lltagty = T_struct ( vec( T_int ( ) , T_array ( T_i8 ( ) , info. size) ) ) ;
1906
+
1907
+ // FIXME: better name.
1908
+ llvm. LLVMAddTypeName ( cx. llmod, _str. buf( "tag" ) , lltagty) ;
1909
+
1910
+ auto lltagptr = bcx. build. Alloca ( lltagty) ;
1911
+ auto lldiscrimptr = bcx. build. GEP ( lltagptr, vec( C_int ( 0 ) , C_int ( 0 ) ) ) ;
1912
+ bcx. build. Store ( C_int ( index) , lldiscrimptr) ;
1913
+
1914
+ auto llblobptr = bcx. build. GEP ( lltagptr, vec( C_int ( 0 ) , C_int ( 1 ) ) ) ;
1915
+
1916
+ // First, generate the union type.
1917
+ let vec[ TypeRef ] llargtys = vec( ) ;
1918
+ for ( typeck. arg arg in arg_tys) {
1919
+ llargtys += vec( type_of( cx, arg. ty) ) ;
1920
+ }
1921
+
1922
+ auto llunionty = T_struct ( llargtys) ;
1923
+ auto llunionptr = bcx. build. TruncOrBitCast ( llblobptr, T_ptr ( llunionty) ) ;
1924
+
1925
+ i = 0 u;
1926
+ for ( ast. variant_arg va in variant. args) {
1927
+ auto llargalias = bcx. build. Load ( fcx. llargs. get( va. id) ) ;
1928
+ auto llargval = bcx. build. Load ( llargalias) ;
1929
+
1930
+ llvm. LLVMDumpValue ( llunionptr) ;
1931
+
1932
+ auto lldestptr = bcx. build. GEP ( llunionptr,
1933
+ vec( C_int ( 0 ) , C_int ( i as int) ) ) ;
1934
+
1935
+ bcx. build. Store ( llargval, lldestptr) ;
1936
+ i += 1 u;
1937
+ }
1938
+
1939
+ auto lltagval = bcx. build. Load ( lltagptr) ;
1940
+ bcx = trans_block_cleanups( bcx, find_scope_cx( bcx) ) ;
1941
+ bcx. build. Ret ( lltagval) ;
1873
1942
}
1874
1943
1875
1944
impure fn trans_item( @crate_ctxt cx, & ast. item item) {
@@ -1884,8 +1953,10 @@ impure fn trans_item(@crate_ctxt cx, &ast.item item) {
1884
1953
}
1885
1954
case ( ast. item_tag( ?name, ?variants, _, ?tag_id) ) {
1886
1955
auto sub_cx = @rec( path=cx. path + "." + name with * cx) ;
1956
+ auto i = 0 ;
1887
1957
for ( ast. variant variant in variants) {
1888
- trans_tag_variant( sub_cx, tag_id, variant) ;
1958
+ trans_tag_variant( sub_cx, tag_id, variant, i) ;
1959
+ i += 1 ;
1889
1960
}
1890
1961
}
1891
1962
case ( _) { /* fall through */ }
0 commit comments