Skip to content

Commit 2375135

Browse files
committed
---
yaml --- r: 989 b: refs/heads/master c: eeecc8d h: refs/heads/master i: 987: ef739f1 v: v3
1 parent b504a36 commit 2375135

File tree

4 files changed

+140
-2
lines changed

4 files changed

+140
-2
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 98a63bd1f9fda47fc34b16d9f0782022e1022277
2+
refs/heads/master: eeecc8d0617b547520083b9db94ec05f84fbca64

trunk/src/comp/lib/llvm.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,19 @@ obj builder(BuilderRef B) {
11061106
}
11071107
}
11081108

1109+
/* Memory-managed object interface to type handles. */
1110+
1111+
obj type_handle_dtor(TypeHandleRef TH) {
1112+
drop { llvm.LLVMDisposeTypeHandle(TH); }
1113+
}
1114+
1115+
type type_handle = rec(TypeHandleRef llth, type_handle_dtor dtor);
1116+
1117+
fn mk_type_handle() -> type_handle {
1118+
auto th = llvm.LLVMCreateTypeHandle(llvm.LLVMOpaqueType());
1119+
ret rec(llth=th, dtor=type_handle_dtor(th));
1120+
}
1121+
11091122
fn type_to_str(TypeRef ty) -> str {
11101123
let int kind = llvm.LLVMGetTypeKind(ty);
11111124

trunk/src/comp/middle/trans.rs

+120
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@ import util.common.new_str_hash;
2020

2121
import lib.llvm.llvm;
2222
import lib.llvm.builder;
23+
import lib.llvm.type_handle;
24+
import lib.llvm.mk_type_handle;
2325
import lib.llvm.llvm.ModuleRef;
2426
import lib.llvm.llvm.ValueRef;
2527
import lib.llvm.llvm.TypeRef;
28+
import lib.llvm.llvm.TypeHandleRef;
2629
import lib.llvm.llvm.BuilderRef;
2730
import lib.llvm.llvm.BasicBlockRef;
2831

@@ -41,13 +44,18 @@ type glue_fns = rec(ValueRef activate_glue,
4144
ValueRef exit_task_glue,
4245
vec[ValueRef] upcall_glues);
4346

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+
4451
state type crate_ctxt = rec(session.session sess,
4552
ModuleRef llmod,
4653
hashmap[str, ValueRef] upcalls,
4754
hashmap[str, ValueRef] intrinsics,
4855
hashmap[str, ValueRef] fn_names,
4956
hashmap[ast.def_id, ValueRef] fn_ids,
5057
hashmap[ast.def_id, @ast.item] items,
58+
hashmap[ast.def_id, tag_info] tags,
5159
@glue_fns glues,
5260
namegen names,
5361
str path);
@@ -177,6 +185,11 @@ fn T_struct(vec[TypeRef] elts) -> TypeRef {
177185
False);
178186
}
179187

188+
fn T_union(vec[TypeRef] elts) -> TypeRef {
189+
ret llvm.LLVMUnionType(_vec.buf[TypeRef](elts),
190+
_vec.len[TypeRef](elts));
191+
}
192+
180193
fn T_opaque() -> TypeRef {
181194
ret llvm.LLVMOpaqueType();
182195
}
@@ -267,6 +280,9 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
267280
}
268281
case (typeck.ty_char) { ret T_char(); }
269282
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+
}
270286
case (typeck.ty_box(?t)) {
271287
ret T_ptr(T_box(type_of(cx, t)));
272288
}
@@ -1114,6 +1130,19 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt)
11141130
ret tup(res(cx, cx.fcx.ccx.fn_ids.get(did)),
11151131
false);
11161132
}
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+
}
11171146
case (_) {
11181147
cx.fcx.ccx.sess.unimpl("def variant in trans");
11191148
}
@@ -1645,6 +1674,15 @@ impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
16451674
}
16461675
}
16471676

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) == 0u) {
1680+
ret; // nullary constructors are just constants
1681+
}
1682+
1683+
// TODO
1684+
}
1685+
16481686
impure fn trans_item(@crate_ctxt cx, &ast.item item) {
16491687
alt (item.node) {
16501688
case (ast.item_fn(?name, ?f, _, ?fid, ?ann)) {
@@ -1655,6 +1693,12 @@ impure fn trans_item(@crate_ctxt cx, &ast.item item) {
16551693
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
16561694
trans_mod(sub_cx, m);
16571695
}
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+
}
16581702
case (_) { /* fall through */ }
16591703
}
16601704
}
@@ -1666,6 +1710,60 @@ impure fn trans_mod(@crate_ctxt cx, &ast._mod m) {
16661710
}
16671711

16681712

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) == 0u) {
1724+
tag_ty = T_struct(vec(T_int()));
1725+
} else {
1726+
auto variant_idx = 0u;
1727+
auto n_ary_variant_idx = 0u;
1728+
1729+
for (ast.variant variant in variants) {
1730+
if (_vec.len[@ast.ty](variant.args) > 0u) {
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 += 1u;
1747+
}
1748+
1749+
variant_indices.insert(variant.id, variant_idx);
1750+
variant_idx += 1u;
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+
16691767
fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
16701768
alt (i.node) {
16711769
case (ast.item_fn(?name, ?f, _, ?fid, ?ann)) {
@@ -1680,6 +1778,15 @@ fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
16801778
case (ast.item_mod(?name, ?m, ?mid)) {
16811779
cx.items.insert(mid, i);
16821780
}
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+
16831790
case (_) { /* fall through */ }
16841791
}
16851792
ret cx;
@@ -1697,6 +1804,16 @@ fn collect_items(@crate_ctxt cx, @ast.crate crate) {
16971804
fold.fold_crate[@crate_ctxt](cx, fld, crate);
16981805
}
16991806

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+
17001817
fn p2i(ValueRef v) -> ValueRef {
17011818
ret llvm.LLVMConstPtrToInt(v, T_int());
17021819
}
@@ -1856,11 +1973,14 @@ fn trans_crate(session.session sess, @ast.crate crate, str output) {
18561973
fn_names = new_str_hash[ValueRef](),
18571974
fn_ids = new_def_hash[ValueRef](),
18581975
items = new_def_hash[@ast.item](),
1976+
tags = new_def_hash[tag_info](),
18591977
glues = glues,
18601978
names = namegen(0),
18611979
path = "_rust");
18621980

18631981
collect_items(cx, crate);
1982+
resolve_tag_types(cx, crate);
1983+
18641984
trans_mod(cx, crate.node.module);
18651985
trans_exit_task_glue(cx);
18661986
trans_main_fn(cx, crate_constant(cx));

trunk/src/comp/middle/typeck.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ fn ty_to_str(&@ty typ) -> str {
203203
s = "rec(" + _str.connect(strs, ",") + ")";
204204
}
205205

206+
case (ty_tag(_)) {
207+
// The user should never see this if the cname is set properly!
208+
s = "<tag>";
209+
}
210+
206211
case (ty_fn(?inputs, ?output)) {
207212
auto f = fn_input_to_str;
208213
s = "fn(" + _str.connect(_vec.map[arg,str](f, inputs),
@@ -550,9 +555,9 @@ fn type_is_nil(@ty t) -> bool {
550555

551556
fn type_is_structural(@ty t) -> bool {
552557
alt (t.struct) {
553-
// FIXME: cover tag when we support it.
554558
case (ty_tup(_)) { ret true; }
555559
case (ty_rec(_)) { ret true; }
560+
case (ty_tag(_)) { ret true; }
556561
case (_) { ret false; }
557562
}
558563
fail;

0 commit comments

Comments
 (0)