rustc: Add stub support for tag constructors in trans

This commit is contained in:
Patrick Walton 2010-12-01 19:03:47 -08:00
parent 98a63bd1f9
commit eeecc8d061
3 changed files with 139 additions and 1 deletions

View file

@ -1106,6 +1106,19 @@ obj builder(BuilderRef B) {
}
}
/* Memory-managed object interface to type handles. */
obj type_handle_dtor(TypeHandleRef TH) {
drop { llvm.LLVMDisposeTypeHandle(TH); }
}
type type_handle = rec(TypeHandleRef llth, type_handle_dtor dtor);
fn mk_type_handle() -> type_handle {
auto th = llvm.LLVMCreateTypeHandle(llvm.LLVMOpaqueType());
ret rec(llth=th, dtor=type_handle_dtor(th));
}
fn type_to_str(TypeRef ty) -> str {
let int kind = llvm.LLVMGetTypeKind(ty);

View file

@ -20,9 +20,12 @@ import util.common.new_str_hash;
import lib.llvm.llvm;
import lib.llvm.builder;
import lib.llvm.type_handle;
import lib.llvm.mk_type_handle;
import lib.llvm.llvm.ModuleRef;
import lib.llvm.llvm.ValueRef;
import lib.llvm.llvm.TypeRef;
import lib.llvm.llvm.TypeHandleRef;
import lib.llvm.llvm.BuilderRef;
import lib.llvm.llvm.BasicBlockRef;
@ -41,6 +44,10 @@ type glue_fns = rec(ValueRef activate_glue,
ValueRef exit_task_glue,
vec[ValueRef] upcall_glues);
type tag_info = rec(type_handle th,
hashmap[ast.def_id, uint] variant_indices,
hashmap[ast.def_id, uint] n_ary_variant_indices);
state type crate_ctxt = rec(session.session sess,
ModuleRef llmod,
hashmap[str, ValueRef] upcalls,
@ -48,6 +55,7 @@ state type crate_ctxt = rec(session.session sess,
hashmap[str, ValueRef] fn_names,
hashmap[ast.def_id, ValueRef] fn_ids,
hashmap[ast.def_id, @ast.item] items,
hashmap[ast.def_id, tag_info] tags,
@glue_fns glues,
namegen names,
str path);
@ -177,6 +185,11 @@ fn T_struct(vec[TypeRef] elts) -> TypeRef {
False);
}
fn T_union(vec[TypeRef] elts) -> TypeRef {
ret llvm.LLVMUnionType(_vec.buf[TypeRef](elts),
_vec.len[TypeRef](elts));
}
fn T_opaque() -> TypeRef {
ret llvm.LLVMOpaqueType();
}
@ -267,6 +280,9 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
}
case (typeck.ty_char) { ret T_char(); }
case (typeck.ty_str) { ret T_ptr(T_str()); }
case (typeck.ty_tag(?tag_id)) {
ret llvm.LLVMResolveTypeHandle(cx.tags.get(tag_id).th.llth);
}
case (typeck.ty_box(?t)) {
ret T_ptr(T_box(type_of(cx, t)));
}
@ -1114,6 +1130,19 @@ fn trans_name(@block_ctxt cx, &ast.name n, &option.t[ast.def] dopt)
ret tup(res(cx, cx.fcx.ccx.fn_ids.get(did)),
false);
}
case (ast.def_variant(?tid, ?vid)) {
check (cx.fcx.ccx.tags.contains_key(tid));
auto info = cx.fcx.ccx.tags.get(tid);
if (info.n_ary_variant_indices.contains_key(vid)) {
cx.fcx.ccx.sess.unimpl("n-ary tag constructors in " +
"trans");
} else {
// Nullary tag variant case.
auto idx = info.variant_indices.get(vid);
auto elems = vec(C_int(idx as int));
ret tup(res(cx, C_struct(elems)), false);
}
}
case (_) {
cx.fcx.ccx.sess.unimpl("def variant in trans");
}
@ -1645,6 +1674,15 @@ impure fn trans_fn(@crate_ctxt cx, &ast._fn f, ast.def_id fid,
}
}
fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
&ast.variant variant) {
if (_vec.len[@ast.ty](variant.args) == 0u) {
ret; // nullary constructors are just constants
}
// TODO
}
impure fn trans_item(@crate_ctxt cx, &ast.item item) {
alt (item.node) {
case (ast.item_fn(?name, ?f, _, ?fid, ?ann)) {
@ -1655,6 +1693,12 @@ impure fn trans_item(@crate_ctxt cx, &ast.item item) {
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
trans_mod(sub_cx, m);
}
case (ast.item_tag(?name, ?variants, _, ?tag_id)) {
auto sub_cx = @rec(path=cx.path + "." + name with *cx);
for (ast.variant variant in variants) {
trans_tag_variant(sub_cx, tag_id, variant);
}
}
case (_) { /* fall through */ }
}
}
@ -1666,6 +1710,60 @@ impure fn trans_mod(@crate_ctxt cx, &ast._mod m) {
}
fn resolve_tag_types_for_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
alt (i.node) {
case (ast.item_tag(_, ?variants, _, ?tag_id)) {
let vec[TypeRef] variant_tys = vec();
auto info = cx.tags.get(tag_id);
auto variant_indices = info.variant_indices;
auto n_ary_variant_indices = info.n_ary_variant_indices;
auto tag_ty;
if (_vec.len[ast.variant](variants) == 0u) {
tag_ty = T_struct(vec(T_int()));
} else {
auto variant_idx = 0u;
auto n_ary_variant_idx = 0u;
for (ast.variant variant in variants) {
if (_vec.len[@ast.ty](variant.args) > 0u) {
let vec[TypeRef] lltys = vec();
alt (typeck.ann_to_type(variant.ann).struct) {
case (typeck.ty_fn(?args, _)) {
for (typeck.arg arg in args) {
lltys += vec(type_of(cx, arg.ty));
}
}
case (_) { fail; }
}
variant_tys += vec(T_struct(lltys));
n_ary_variant_indices.insert(variant.id,
n_ary_variant_idx);
n_ary_variant_idx += 1u;
}
variant_indices.insert(variant.id, variant_idx);
variant_idx += 1u;
}
tag_ty = T_struct(vec(T_int(), T_union(variant_tys)));
}
auto th = cx.tags.get(tag_id).th.llth;
llvm.LLVMRefineType(llvm.LLVMResolveTypeHandle(th), tag_ty);
}
case (_) {
// fall through
}
}
ret cx;
}
fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
alt (i.node) {
case (ast.item_fn(?name, ?f, _, ?fid, ?ann)) {
@ -1680,6 +1778,15 @@ fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
case (ast.item_mod(?name, ?m, ?mid)) {
cx.items.insert(mid, i);
}
case (ast.item_tag(_, ?variants, _, ?tag_id)) {
auto vi = new_def_hash[uint]();
auto navi = new_def_hash[uint]();
cx.tags.insert(tag_id, rec(th=mk_type_handle(),
variant_indices=vi,
n_ary_variant_indices=navi));
}
case (_) { /* fall through */ }
}
ret cx;
@ -1697,6 +1804,16 @@ fn collect_items(@crate_ctxt cx, @ast.crate crate) {
fold.fold_crate[@crate_ctxt](cx, fld, crate);
}
fn resolve_tag_types(@crate_ctxt cx, @ast.crate crate) {
let fold.ast_fold[@crate_ctxt] fld =
fold.new_identity_fold[@crate_ctxt]();
fld = @rec( update_env_for_item = bind resolve_tag_types_for_item(_,_)
with *fld );
fold.fold_crate[@crate_ctxt](cx, fld, crate);
}
fn p2i(ValueRef v) -> ValueRef {
ret llvm.LLVMConstPtrToInt(v, T_int());
}
@ -1856,11 +1973,14 @@ fn trans_crate(session.session sess, @ast.crate crate, str output) {
fn_names = new_str_hash[ValueRef](),
fn_ids = new_def_hash[ValueRef](),
items = new_def_hash[@ast.item](),
tags = new_def_hash[tag_info](),
glues = glues,
names = namegen(0),
path = "_rust");
collect_items(cx, crate);
resolve_tag_types(cx, crate);
trans_mod(cx, crate.node.module);
trans_exit_task_glue(cx);
trans_main_fn(cx, crate_constant(cx));

View file

@ -203,6 +203,11 @@ fn ty_to_str(&@ty typ) -> str {
s = "rec(" + _str.connect(strs, ",") + ")";
}
case (ty_tag(_)) {
// The user should never see this if the cname is set properly!
s = "<tag>";
}
case (ty_fn(?inputs, ?output)) {
auto f = fn_input_to_str;
s = "fn(" + _str.connect(_vec.map[arg,str](f, inputs),
@ -550,9 +555,9 @@ fn type_is_nil(@ty t) -> bool {
fn type_is_structural(@ty t) -> bool {
alt (t.struct) {
// FIXME: cover tag when we support it.
case (ty_tup(_)) { ret true; }
case (ty_rec(_)) { ret true; }
case (ty_tag(_)) { ret true; }
case (_) { ret false; }
}
fail;