rustc: Add stub support for tag constructors in trans
This commit is contained in:
parent
98a63bd1f9
commit
eeecc8d061
3 changed files with 139 additions and 1 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue