Teach trans and llvm to cooperate on producing tidier diagnostic names in trans.ty_str.

This commit is contained in:
Graydon Hoare 2011-02-17 18:16:51 -08:00
parent 10befcd9a4
commit 0ddb832a4e
2 changed files with 227 additions and 114 deletions

View file

@ -1151,18 +1151,70 @@ fn mk_type_handle() -> type_handle {
ret rec(llth=th, dtor=type_handle_dtor(th)); ret rec(llth=th, dtor=type_handle_dtor(th));
} }
fn type_to_str(TypeRef ty) -> str {
let vec[TypeRef] v = vec(); state obj type_names(std.map.hashmap[TypeRef, str] type_names,
ret type_to_str_inner(v, ty); std.map.hashmap[str, TypeRef] named_types) {
fn associate(str s, TypeRef t) {
check (!named_types.contains_key(s));
check (!type_names.contains_key(t));
type_names.insert(t, s);
named_types.insert(s, t);
}
fn type_has_name(TypeRef t) -> bool {
ret type_names.contains_key(t);
}
fn get_name(TypeRef t) -> str {
ret type_names.get(t);
}
fn name_has_type(str s) -> bool {
ret named_types.contains_key(s);
}
fn get_type(str s) -> TypeRef {
ret named_types.get(s);
}
} }
fn type_to_str_inner(vec[TypeRef] outer0, TypeRef ty) -> str { fn mk_type_names() -> type_names {
auto nt = util.common.new_str_hash[TypeRef]();
fn hash(&TypeRef t) -> uint {
ret t as uint;
}
fn eq(&TypeRef a, &TypeRef b) -> bool {
ret (a as uint) == (b as uint);
}
let std.map.hashfn[TypeRef] hasher = hash;
let std.map.eqfn[TypeRef] eqer = eq;
auto tn = std.map.mk_hashmap[TypeRef,str](hasher, eqer);
ret type_names(tn, nt);
}
fn type_to_str(type_names names, TypeRef ty) -> str {
let vec[TypeRef] v = vec();
ret type_to_str_inner(names, v, ty);
}
fn type_to_str_inner(type_names names,
vec[TypeRef] outer0, TypeRef ty) -> str {
if (names.type_has_name(ty)) {
ret names.get_name(ty);
}
auto outer = outer0 + vec(ty); auto outer = outer0 + vec(ty);
let int kind = llvm.LLVMGetTypeKind(ty); let int kind = llvm.LLVMGetTypeKind(ty);
fn tys_str(vec[TypeRef] outer, vec[TypeRef] tys) -> str { fn tys_str(type_names names,
vec[TypeRef] outer, vec[TypeRef] tys) -> str {
let str s = ""; let str s = "";
let bool first = true; let bool first = true;
for (TypeRef t in tys) { for (TypeRef t in tys) {
@ -1171,7 +1223,7 @@ fn type_to_str_inner(vec[TypeRef] outer0, TypeRef ty) -> str {
} else { } else {
s += ", "; s += ", ";
} }
s += type_to_str_inner(outer, t); s += type_to_str_inner(names, outer, t);
} }
ret s; ret s;
} }
@ -1200,9 +1252,9 @@ fn type_to_str_inner(vec[TypeRef] outer0, TypeRef ty) -> str {
let vec[TypeRef] args = let vec[TypeRef] args =
_vec.init_elt[TypeRef](0 as TypeRef, n_args); _vec.init_elt[TypeRef](0 as TypeRef, n_args);
llvm.LLVMGetParamTypes(ty, _vec.buf[TypeRef](args)); llvm.LLVMGetParamTypes(ty, _vec.buf[TypeRef](args));
s += tys_str(outer, args); s += tys_str(names, outer, args);
s += ") -> "; s += ") -> ";
s += type_to_str_inner(outer, out_ty); s += type_to_str_inner(names, outer, out_ty);
ret s; ret s;
} }
@ -1212,7 +1264,7 @@ fn type_to_str_inner(vec[TypeRef] outer0, TypeRef ty) -> str {
let vec[TypeRef] elts = let vec[TypeRef] elts =
_vec.init_elt[TypeRef](0 as TypeRef, n_elts); _vec.init_elt[TypeRef](0 as TypeRef, n_elts);
llvm.LLVMGetStructElementTypes(ty, _vec.buf[TypeRef](elts)); llvm.LLVMGetStructElementTypes(ty, _vec.buf[TypeRef](elts));
s += tys_str(outer, elts); s += tys_str(names, outer, elts);
s += "}"; s += "}";
ret s; ret s;
} }
@ -1228,7 +1280,8 @@ fn type_to_str_inner(vec[TypeRef] outer0, TypeRef ty) -> str {
ret "*\\" + util.common.istr(n as int); ret "*\\" + util.common.istr(n as int);
} }
} }
ret "*" + type_to_str_inner(outer, llvm.LLVMGetElementType(ty)); ret "*" + type_to_str_inner(names, outer,
llvm.LLVMGetElementType(ty));
} }
case (12) { ret "Opaque"; } case (12) { ret "Opaque"; }

View file

@ -28,9 +28,11 @@ import lib.llvm.llvm;
import lib.llvm.builder; import lib.llvm.builder;
import lib.llvm.target_data; import lib.llvm.target_data;
import lib.llvm.type_handle; import lib.llvm.type_handle;
import lib.llvm.type_names;
import lib.llvm.mk_pass_manager; import lib.llvm.mk_pass_manager;
import lib.llvm.mk_target_data; import lib.llvm.mk_target_data;
import lib.llvm.mk_type_handle; import lib.llvm.mk_type_handle;
import lib.llvm.mk_type_names;
import lib.llvm.llvm.ModuleRef; import lib.llvm.llvm.ModuleRef;
import lib.llvm.llvm.ValueRef; import lib.llvm.llvm.ValueRef;
import lib.llvm.llvm.TypeRef; import lib.llvm.llvm.TypeRef;
@ -64,6 +66,7 @@ type tag_info = rec(type_handle th,
state type crate_ctxt = rec(session.session sess, state type crate_ctxt = rec(session.session sess,
ModuleRef llmod, ModuleRef llmod,
target_data td, target_data td,
type_names tn,
ValueRef crate_ptr, ValueRef crate_ptr,
hashmap[str, ValueRef] upcalls, hashmap[str, ValueRef] upcalls,
hashmap[str, ValueRef] intrinsics, hashmap[str, ValueRef] intrinsics,
@ -133,16 +136,16 @@ fn res(@block_ctxt bcx, ValueRef val) -> result {
mutable val = val); mutable val = val);
} }
fn ty_str(TypeRef t) -> str { fn ty_str(type_names tn, TypeRef t) -> str {
ret lib.llvm.type_to_str(t); ret lib.llvm.type_to_str(tn, t);
} }
fn val_ty(ValueRef v) -> TypeRef { fn val_ty(ValueRef v) -> TypeRef {
ret llvm.LLVMTypeOf(v); ret llvm.LLVMTypeOf(v);
} }
fn val_str(ValueRef v) -> str { fn val_str(type_names tn, ValueRef v) -> str {
ret ty_str(val_ty(v)); ret ty_str(tn, val_ty(v));
} }
@ -215,9 +218,9 @@ fn T_fn(vec[TypeRef] inputs, TypeRef output) -> TypeRef {
False); False);
} }
fn T_fn_pair(TypeRef tfn) -> TypeRef { fn T_fn_pair(type_names tn, TypeRef tfn) -> TypeRef {
ret T_struct(vec(T_ptr(tfn), ret T_struct(vec(T_ptr(tfn),
T_opaque_closure_ptr())); T_opaque_closure_ptr(tn)));
} }
fn T_ptr(TypeRef t) -> TypeRef { fn T_ptr(TypeRef t) -> TypeRef {
@ -234,34 +237,55 @@ fn T_opaque() -> TypeRef {
ret llvm.LLVMOpaqueType(); ret llvm.LLVMOpaqueType();
} }
fn T_task() -> TypeRef { fn T_task(type_names tn) -> TypeRef {
ret T_struct(vec(T_int(), // Refcount auto s = "task";
T_int(), // Delegate pointer if (tn.name_has_type(s)) {
T_int(), // Stack segment pointer ret tn.get_type(s);
T_int(), // Runtime SP }
T_int(), // Rust SP
T_int(), // GC chain auto t = T_struct(vec(T_int(), // Refcount
T_int(), // Domain pointer T_int(), // Delegate pointer
T_int() // Crate cache pointer T_int(), // Stack segment pointer
)); T_int(), // Runtime SP
T_int(), // Rust SP
T_int(), // GC chain
T_int(), // Domain pointer
T_int() // Crate cache pointer
));
tn.associate(s, t);
ret t;
} }
fn T_glue_fn() -> TypeRef { fn T_glue_fn(type_names tn) -> TypeRef {
auto s = "glue_fn";
if (tn.name_has_type(s)) {
ret tn.get_type(s);
}
// Bit of a kludge: pick the fn typeref out of the tydesc.. // Bit of a kludge: pick the fn typeref out of the tydesc..
let vec[TypeRef] tydesc_elts = _vec.init_elt[TypeRef](T_nil(), 10u); let vec[TypeRef] tydesc_elts = _vec.init_elt[TypeRef](T_nil(), 10u);
llvm.LLVMGetStructElementTypes(T_tydesc(), llvm.LLVMGetStructElementTypes(T_tydesc(tn),
_vec.buf[TypeRef](tydesc_elts)); _vec.buf[TypeRef](tydesc_elts));
ret llvm.LLVMGetElementType(tydesc_elts.(abi.tydesc_field_drop_glue_off)); auto t =
llvm.LLVMGetElementType
(tydesc_elts.(abi.tydesc_field_drop_glue_off));
tn.associate(s, t);
ret t;
} }
fn T_tydesc() -> TypeRef { fn T_tydesc(type_names tn) -> TypeRef {
auto s = "tydesc";
if (tn.name_has_type(s)) {
ret tn.get_type(s);
}
auto th = mk_type_handle(); auto th = mk_type_handle();
auto abs_tydesc = llvm.LLVMResolveTypeHandle(th.llth); auto abs_tydesc = llvm.LLVMResolveTypeHandle(th.llth);
auto tydescpp = T_ptr(T_ptr(abs_tydesc)); auto tydescpp = T_ptr(T_ptr(abs_tydesc));
auto pvoid = T_ptr(T_i8()); auto pvoid = T_ptr(T_i8());
auto glue_fn_ty = T_ptr(T_fn(vec(T_ptr(T_nil()), auto glue_fn_ty = T_ptr(T_fn(vec(T_ptr(T_nil()),
T_taskptr(), T_taskptr(tn),
T_ptr(T_nil()), T_ptr(T_nil()),
tydescpp, tydescpp,
pvoid), T_void())); pvoid), T_void()));
@ -277,7 +301,9 @@ fn T_tydesc() -> TypeRef {
glue_fn_ty)); // is_stateful glue_fn_ty)); // is_stateful
llvm.LLVMRefineType(abs_tydesc, tydesc); llvm.LLVMRefineType(abs_tydesc, tydesc);
ret llvm.LLVMResolveTypeHandle(th.llth); auto t = llvm.LLVMResolveTypeHandle(th.llth);
tn.associate(s, t);
ret t;
} }
fn T_array(TypeRef t, uint n) -> TypeRef { fn T_array(TypeRef t, uint n) -> TypeRef {
@ -300,67 +326,90 @@ fn T_box(TypeRef t) -> TypeRef {
ret T_struct(vec(T_int(), t)); ret T_struct(vec(T_int(), t));
} }
fn T_crate() -> TypeRef { fn T_crate(type_names tn) -> TypeRef {
ret T_struct(vec(T_int(), // ptrdiff_t image_base_off auto s = "crate";
T_int(), // uintptr_t self_addr if (tn.name_has_type(s)) {
T_int(), // ptrdiff_t debug_abbrev_off ret tn.get_type(s);
T_int(), // size_t debug_abbrev_sz }
T_int(), // ptrdiff_t debug_info_off
T_int(), // size_t debug_info_sz auto t = T_struct(vec(T_int(), // ptrdiff_t image_base_off
T_int(), // size_t activate_glue_off T_int(), // uintptr_t self_addr
T_int(), // size_t yield_glue_off T_int(), // ptrdiff_t debug_abbrev_off
T_int(), // size_t unwind_glue_off T_int(), // size_t debug_abbrev_sz
T_int(), // size_t gc_glue_off T_int(), // ptrdiff_t debug_info_off
T_int(), // size_t main_exit_task_glue_off T_int(), // size_t debug_info_sz
T_int(), // int n_rust_syms T_int(), // size_t activate_glue_off
T_int(), // int n_c_syms T_int(), // size_t yield_glue_off
T_int() // int n_libs T_int(), // size_t unwind_glue_off
)); T_int(), // size_t gc_glue_off
T_int(), // size_t main_exit_task_glue_off
T_int(), // int n_rust_syms
T_int(), // int n_c_syms
T_int() // int n_libs
));
tn.associate(s, t);
ret t;
} }
fn T_double() -> TypeRef { fn T_double() -> TypeRef {
ret llvm.LLVMDoubleType(); ret llvm.LLVMDoubleType();
} }
fn T_taskptr() -> TypeRef { fn T_taskptr(type_names tn) -> TypeRef {
ret T_ptr(T_task()); ret T_ptr(T_task(tn));
} }
fn T_typaram_ptr() -> TypeRef { fn T_typaram_ptr(type_names tn) -> TypeRef {
ret T_ptr(T_i8()); auto s = "typaram";
if (tn.name_has_type(s)) {
ret tn.get_type(s);
}
auto t = T_ptr(T_i8());
tn.associate(s, t);
ret t;
} }
fn T_closure_ptr(TypeRef lltarget_ty, fn T_closure_ptr(type_names tn,
TypeRef lltarget_ty,
TypeRef llbindings_ty) -> TypeRef { TypeRef llbindings_ty) -> TypeRef {
ret T_ptr(T_box(T_struct(vec(T_ptr(T_tydesc()), ret T_ptr(T_box(T_struct(vec(T_ptr(T_tydesc(tn)),
lltarget_ty, lltarget_ty,
llbindings_ty) llbindings_ty)
// FIXME: add captured typarams. // FIXME: add captured typarams.
))); )));
} }
fn T_opaque_closure_ptr() -> TypeRef { fn T_opaque_closure_ptr(type_names tn) -> TypeRef {
ret T_closure_ptr(T_struct(vec(T_ptr(T_nil()), auto s = "*closure";
T_ptr(T_nil()))), if (tn.name_has_type(s)) {
T_nil()); ret tn.get_type(s);
}
auto t = T_closure_ptr(tn, T_struct(vec(T_ptr(T_nil()),
T_ptr(T_nil()))),
T_nil());
tn.associate(s, t);
ret t;
} }
fn T_captured_tydescs(uint n) -> TypeRef { fn T_captured_tydescs(type_names tn, uint n) -> TypeRef {
ret T_struct(_vec.init_elt[TypeRef](T_ptr(T_tydesc()), n)); ret T_struct(_vec.init_elt[TypeRef](T_ptr(T_tydesc(tn)), n));
} }
fn T_obj(uint n_captured_tydescs, TypeRef llfields_ty) -> TypeRef { fn T_obj(type_names tn, uint n_captured_tydescs,
ret T_struct(vec(T_ptr(T_tydesc()), TypeRef llfields_ty) -> TypeRef {
T_captured_tydescs(n_captured_tydescs), ret T_struct(vec(T_ptr(T_tydesc(tn)),
T_captured_tydescs(tn, n_captured_tydescs),
llfields_ty)); llfields_ty));
} }
fn T_obj_ptr(uint n_captured_tydescs, TypeRef llfields_ty) -> TypeRef { fn T_obj_ptr(type_names tn, uint n_captured_tydescs,
ret T_ptr(T_box(T_obj(n_captured_tydescs, llfields_ty))); TypeRef llfields_ty) -> TypeRef {
ret T_ptr(T_box(T_obj(tn, n_captured_tydescs, llfields_ty)));
} }
fn T_opaque_obj_ptr() -> TypeRef { fn T_opaque_obj_ptr(type_names tn) -> TypeRef {
ret T_obj_ptr(0u, T_nil()); ret T_obj_ptr(tn, 0u, T_nil());
} }
@ -377,7 +426,7 @@ fn type_of_explicit_args(@crate_ctxt cx,
for (ty.arg arg in inputs) { for (ty.arg arg in inputs) {
if (ty.type_has_dynamic_size(arg.ty)) { if (ty.type_has_dynamic_size(arg.ty)) {
check (arg.mode == ast.alias); check (arg.mode == ast.alias);
atys += T_typaram_ptr(); atys += T_typaram_ptr(cx.tn);
} else { } else {
let TypeRef t = type_of(cx, arg.ty); let TypeRef t = type_of(cx, arg.ty);
alt (arg.mode) { alt (arg.mode) {
@ -409,13 +458,13 @@ fn type_of_fn_full(@crate_ctxt cx,
// Arg 0: Output pointer. // Arg 0: Output pointer.
if (ty.type_has_dynamic_size(output)) { if (ty.type_has_dynamic_size(output)) {
atys += T_typaram_ptr(); atys += T_typaram_ptr(cx.tn);
} else { } else {
atys += T_ptr(type_of(cx, output)); atys += T_ptr(type_of(cx, output));
} }
// Arg 1: Task pointer. // Arg 1: Task pointer.
atys += T_taskptr(); atys += T_taskptr(cx.tn);
// Arg 2: Env (closure-bindings / self-obj) // Arg 2: Env (closure-bindings / self-obj)
alt (obj_self) { alt (obj_self) {
@ -424,7 +473,7 @@ fn type_of_fn_full(@crate_ctxt cx,
atys += t; atys += t;
} }
case (_) { case (_) {
atys += T_opaque_closure_ptr(); atys += T_opaque_closure_ptr(cx.tn);
} }
} }
@ -434,7 +483,7 @@ fn type_of_fn_full(@crate_ctxt cx,
ty.count_ty_params(plain_ty(ty.ty_fn(inputs, output))); ty.count_ty_params(plain_ty(ty.ty_fn(inputs, output)));
auto i = 0u; auto i = 0u;
while (i < ty_param_count) { while (i < ty_param_count) {
atys += T_ptr(T_tydesc()); atys += T_ptr(T_tydesc(cx.tn));
i += 1u; i += 1u;
} }
} }
@ -443,7 +492,8 @@ fn type_of_fn_full(@crate_ctxt cx,
// If it's an iter, the 'output' type of the iter is actually the // If it's an iter, the 'output' type of the iter is actually the
// *input* type of the function we're given as our iter-block // *input* type of the function we're given as our iter-block
// argument. // argument.
atys += T_fn_pair(type_of_fn_full(cx, false, none[TypeRef], atys += T_fn_pair(cx.tn,
type_of_fn_full(cx, false, none[TypeRef],
vec(rec(mode=ast.val, ty=output)), vec(rec(mode=ast.val, ty=output)),
plain_ty(ty.ty_nil))); plain_ty(ty.ty_nil)));
} }
@ -515,10 +565,10 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
} }
case (ty.ty_fn(?args, ?out)) { case (ty.ty_fn(?args, ?out)) {
// FIXME: put iter in ty_fn. // FIXME: put iter in ty_fn.
ret T_fn_pair(type_of_fn(cx, false, args, out)); ret T_fn_pair(cx.tn, type_of_fn(cx, false, args, out));
} }
case (ty.ty_native_fn(?args, ?out)) { case (ty.ty_native_fn(?args, ?out)) {
ret T_fn_pair(type_of_native_fn(cx, args, out)); ret T_fn_pair(cx.tn, type_of_native_fn(cx, args, out));
} }
case (ty.ty_obj(?meths)) { case (ty.ty_obj(?meths)) {
auto th = mk_type_handle(); auto th = mk_type_handle();
@ -536,7 +586,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
} }
let TypeRef vtbl = T_struct(mtys); let TypeRef vtbl = T_struct(mtys);
let TypeRef pair = T_struct(vec(T_ptr(vtbl), let TypeRef pair = T_struct(vec(T_ptr(vtbl),
T_opaque_obj_ptr())); T_opaque_obj_ptr(cx.tn)));
auto abs_pair = llvm.LLVMResolveTypeHandle(th.llth); auto abs_pair = llvm.LLVMResolveTypeHandle(th.llth);
llvm.LLVMRefineType(abs_pair, pair); llvm.LLVMRefineType(abs_pair, pair);
@ -548,9 +598,9 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
fail; fail;
} }
case (ty.ty_param(_)) { case (ty.ty_param(_)) {
ret T_typaram_ptr(); ret T_typaram_ptr(cx.tn);
} }
case (ty.ty_type) { ret T_ptr(T_tydesc()); } case (ty.ty_type) { ret T_ptr(T_tydesc(cx.tn)); }
} }
fail; fail;
} }
@ -686,11 +736,11 @@ fn decl_fastcall_fn(ModuleRef llmod, str name, TypeRef llty) -> ValueRef {
ret decl_fn(llmod, name, lib.llvm.LLVMFastCallConv, llty); ret decl_fn(llmod, name, lib.llvm.LLVMFastCallConv, llty);
} }
fn decl_glue(ModuleRef llmod, str s) -> ValueRef { fn decl_glue(ModuleRef llmod, type_names tn, str s) -> ValueRef {
ret decl_cdecl_fn(llmod, s, T_fn(vec(T_taskptr()), T_void())); ret decl_cdecl_fn(llmod, s, T_fn(vec(T_taskptr(tn)), T_void()));
} }
fn decl_upcall_glue(ModuleRef llmod, uint _n) -> ValueRef { fn decl_upcall_glue(ModuleRef llmod, type_names tn, uint _n) -> ValueRef {
// It doesn't actually matter what type we come up with here, at the // It doesn't actually matter what type we come up with here, at the
// moment, as we cast the upcall function pointers to int before passing // moment, as we cast the upcall function pointers to int before passing
// them to the indirect upcall-invocation glue. But eventually we'd like // them to the indirect upcall-invocation glue. But eventually we'd like
@ -698,7 +748,7 @@ fn decl_upcall_glue(ModuleRef llmod, uint _n) -> ValueRef {
let int n = _n as int; let int n = _n as int;
let str s = abi.upcall_glue_name(n); let str s = abi.upcall_glue_name(n);
let vec[TypeRef] args = let vec[TypeRef] args =
vec(T_taskptr(), // taskptr vec(T_taskptr(tn), // taskptr
T_int()) // callee T_int()) // callee
+ _vec.init_elt[TypeRef](T_int(), n as uint); + _vec.init_elt[TypeRef](T_int(), n as uint);
@ -709,7 +759,7 @@ fn get_upcall(@crate_ctxt cx, str name, int n_args) -> ValueRef {
if (cx.upcalls.contains_key(name)) { if (cx.upcalls.contains_key(name)) {
ret cx.upcalls.get(name); ret cx.upcalls.get(name);
} }
auto inputs = vec(T_taskptr()); auto inputs = vec(T_taskptr(cx.tn));
inputs += _vec.init_elt[TypeRef](T_int(), n_args as uint); inputs += _vec.init_elt[TypeRef](T_int(), n_args as uint);
auto output = T_int(); auto output = T_int();
auto f = decl_cdecl_fn(cx.llmod, name, T_fn(inputs, output)); auto f = decl_cdecl_fn(cx.llmod, name, T_fn(inputs, output));
@ -1064,7 +1114,8 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
auto root = cx.fcx.ccx.tydescs.get(t); auto root = cx.fcx.ccx.tydescs.get(t);
auto tydescs = cx.build.Alloca(T_array(T_ptr(T_tydesc()), n_params)); auto tydescs = cx.build.Alloca(T_array(T_ptr(T_tydesc(cx.fcx.ccx.tn)),
n_params));
auto i = 0; auto i = 0;
auto tdp = cx.build.GEP(tydescs, vec(C_int(0), C_int(i))); auto tdp = cx.build.GEP(tydescs, vec(C_int(0), C_int(i)));
@ -1089,7 +1140,8 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
C_int((1u + n_params) as int), C_int((1u + n_params) as int),
bcx.build.PtrToInt(tydescs, T_int()))); bcx.build.PtrToInt(tydescs, T_int())));
ret res(v.bcx, v.bcx.build.IntToPtr(v.val, T_ptr(T_tydesc()))); ret res(v.bcx, v.bcx.build.IntToPtr(v.val,
T_ptr(T_tydesc(cx.fcx.ccx.tn))));
} }
// Otherwise, generate a tydesc if necessary, and return it. // Otherwise, generate a tydesc if necessary, and return it.
@ -1107,7 +1159,7 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
auto drop_glue = make_generic_glue(cx, t, "drop", dg, typaram_defs); auto drop_glue = make_generic_glue(cx, t, "drop", dg, typaram_defs);
auto llty = type_of(cx, t); auto llty = type_of(cx, t);
auto glue_fn_ty = T_ptr(T_glue_fn()); auto glue_fn_ty = T_ptr(T_glue_fn(cx.tn));
// FIXME: this adjustment has to do with the ridiculous encoding of // FIXME: this adjustment has to do with the ridiculous encoding of
// glue-pointer-constants in the tydesc records: They are tydesc-relative // glue-pointer-constants in the tydesc records: They are tydesc-relative
@ -1120,8 +1172,9 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
} }
auto name = sanitize(cx.names.next("tydesc_" + ty.ty_to_str(t))); auto name = sanitize(cx.names.next("tydesc_" + ty.ty_to_str(t)));
auto gvar = llvm.LLVMAddGlobal(cx.llmod, T_tydesc(), _str.buf(name)); auto gvar = llvm.LLVMAddGlobal(cx.llmod, T_tydesc(cx.tn),
auto tydesc = C_struct(vec(C_null(T_ptr(T_ptr(T_tydesc()))), _str.buf(name));
auto tydesc = C_struct(vec(C_null(T_ptr(T_ptr(T_tydesc(cx.tn)))),
llsize_of(llty), llsize_of(llty),
llalign_of(llty), llalign_of(llty),
off(gvar, take_glue), // take_glue_off off(gvar, take_glue), // take_glue_off
@ -1142,7 +1195,7 @@ fn make_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
fn make_generic_glue(@crate_ctxt cx, @ty.t t, str name, fn make_generic_glue(@crate_ctxt cx, @ty.t t, str name,
val_and_ty_fn helper, val_and_ty_fn helper,
vec[ast.def_id] typaram_defs) -> ValueRef { vec[ast.def_id] typaram_defs) -> ValueRef {
auto llfnty = T_glue_fn(); auto llfnty = T_glue_fn(cx.tn);
auto fn_name = cx.names.next("_rust_" + name) + sep() + ty.ty_to_str(t); auto fn_name = cx.names.next("_rust_" + name) + sep() + ty.ty_to_str(t);
fn_name = sanitize(fn_name); fn_name = sanitize(fn_name);
@ -2793,7 +2846,8 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
let @ty.t bindings_ty = plain_ty(ty.ty_tup(bound_tys)); let @ty.t bindings_ty = plain_ty(ty.ty_tup(bound_tys));
let TypeRef lltarget_ty = type_of(bcx.fcx.ccx, ty.expr_ty(f)); let TypeRef lltarget_ty = type_of(bcx.fcx.ccx, ty.expr_ty(f));
let TypeRef llbindings_ty = type_of(bcx.fcx.ccx, bindings_ty); let TypeRef llbindings_ty = type_of(bcx.fcx.ccx, bindings_ty);
let TypeRef llclosure_ty = T_closure_ptr(lltarget_ty, let TypeRef llclosure_ty = T_closure_ptr(cx.fcx.ccx.tn,
lltarget_ty,
llbindings_ty); llbindings_ty);
// Malloc a box for the body. // Malloc a box for the body.
@ -2854,9 +2908,11 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
auto pair_box = bcx.build.GEP(pair_v, auto pair_box = bcx.build.GEP(pair_v,
vec(C_int(0), vec(C_int(0),
C_int(abi.fn_field_box))); C_int(abi.fn_field_box)));
bcx.build.Store(bcx.build.PointerCast(box, bcx.build.Store
T_opaque_closure_ptr()), (bcx.build.PointerCast
pair_box); (box,
T_opaque_closure_ptr(bcx.fcx.ccx.tn)),
pair_box);
find_scope_cx(cx).cleanups += find_scope_cx(cx).cleanups +=
clean(bind drop_slot(_, pair_v, pair_ty)); clean(bind drop_slot(_, pair_v, pair_ty));
@ -2903,7 +2959,8 @@ fn trans_args(@block_ctxt cx,
} }
} }
if (ty.type_has_dynamic_size(retty)) { if (ty.type_has_dynamic_size(retty)) {
llargs += bcx.build.PointerCast(llretslot, T_typaram_ptr()); llargs += bcx.build.PointerCast(llretslot,
T_typaram_ptr(cx.fcx.ccx.tn));
} else if (ty.count_ty_params(retty) != 0u) { } else if (ty.count_ty_params(retty) != 0u) {
// It's possible that the callee has some generic-ness somewhere in // It's possible that the callee has some generic-ness somewhere in
// its return value -- say a method signature within an obj or a fn // its return value -- say a method signature within an obj or a fn
@ -2979,7 +3036,8 @@ fn trans_args(@block_ctxt cx,
} }
if (ty.type_has_dynamic_size(args.(i).ty)) { if (ty.type_has_dynamic_size(args.(i).ty)) {
val = bcx.build.PointerCast(val, T_typaram_ptr()); val = bcx.build.PointerCast(val,
T_typaram_ptr(cx.fcx.ccx.tn));
} }
llargs += val; llargs += val;
@ -2993,7 +3051,7 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
vec[@ast.expr] args, &ast.ann ann) -> result { vec[@ast.expr] args, &ast.ann ann) -> result {
auto f_res = trans_lval(cx, f); auto f_res = trans_lval(cx, f);
auto faddr = f_res.res.val; auto faddr = f_res.res.val;
auto llenv = C_null(T_opaque_closure_ptr()); auto llenv = C_null(T_opaque_closure_ptr(cx.fcx.ccx.tn));
alt (f_res.llobj) { alt (f_res.llobj) {
case (some[ValueRef](_)) { case (some[ValueRef](_)) {
@ -3036,7 +3094,6 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
find_scope_cx(cx).cleanups += clean(bind drop_ty(_, retval, ret_ty)); find_scope_cx(cx).cleanups += clean(bind drop_ty(_, retval, ret_ty));
} }
// log "call-result type: " + val_str(retval);
ret res(bcx, retval); ret res(bcx, retval);
} }
@ -3767,7 +3824,7 @@ fn populate_fn_ctxt_from_llself(@block_ctxt cx, ValueRef llself) {
} }
auto n_typarams = _vec.len[ast.ty_param](cx.fcx.ccx.obj_typarams); auto n_typarams = _vec.len[ast.ty_param](cx.fcx.ccx.obj_typarams);
let TypeRef llobj_box_ty = T_obj_ptr(n_typarams, let TypeRef llobj_box_ty = T_obj_ptr(cx.fcx.ccx.tn, n_typarams,
T_struct(llfield_tys)); T_struct(llfield_tys));
auto box_cell = auto box_cell =
@ -3925,7 +3982,7 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
C_int(abi.obj_field_box))); C_int(abi.obj_field_box)));
bcx.build.Store(vtbl, pair_vtbl); bcx.build.Store(vtbl, pair_vtbl);
let TypeRef llbox_ty = T_opaque_obj_ptr(); let TypeRef llbox_ty = T_opaque_obj_ptr(cx.tn);
if (_vec.len[ast.ty_param](ty_params) == 0u && if (_vec.len[ast.ty_param](ty_params) == 0u &&
_vec.len[ty.arg](arg_tys) == 0u) { _vec.len[ty.arg](arg_tys) == 0u) {
@ -4175,7 +4232,7 @@ fn decl_fn_and_pair(@crate_ctxt cx,
let ValueRef gvar = llvm.LLVMAddGlobal(cx.llmod, llpairty, let ValueRef gvar = llvm.LLVMAddGlobal(cx.llmod, llpairty,
_str.buf(ps)); _str.buf(ps));
auto pair = C_struct(vec(llfn, auto pair = C_struct(vec(llfn,
C_null(T_opaque_closure_ptr()))); C_null(T_opaque_closure_ptr(cx.tn))));
llvm.LLVMSetInitializer(gvar, pair); llvm.LLVMSetInitializer(gvar, pair);
llvm.LLVMSetGlobalConstant(gvar, True); llvm.LLVMSetGlobalConstant(gvar, True);
@ -4438,7 +4495,7 @@ fn trans_exit_task_glue(@crate_ctxt cx) {
let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 0u); let ValueRef lltaskptr = llvm.LLVMGetParam(llfn, 0u);
auto fcx = @rec(llfn=llfn, auto fcx = @rec(llfn=llfn,
lltaskptr=lltaskptr, lltaskptr=lltaskptr,
llenv=C_null(T_opaque_closure_ptr()), llenv=C_null(T_opaque_closure_ptr(cx.tn)),
llretptr=C_null(T_ptr(T_nil())), llretptr=C_null(T_ptr(T_nil())),
mutable llself=none[ValueRef], mutable llself=none[ValueRef],
mutable lliterbody=none[ValueRef], mutable lliterbody=none[ValueRef],
@ -4454,9 +4511,9 @@ fn trans_exit_task_glue(@crate_ctxt cx) {
} }
fn create_typedefs(@crate_ctxt cx) { fn create_typedefs(@crate_ctxt cx) {
llvm.LLVMAddTypeName(cx.llmod, _str.buf("rust_crate"), T_crate()); llvm.LLVMAddTypeName(cx.llmod, _str.buf("crate"), T_crate(cx.tn));
llvm.LLVMAddTypeName(cx.llmod, _str.buf("rust_task"), T_task()); llvm.LLVMAddTypeName(cx.llmod, _str.buf("task"), T_task(cx.tn));
llvm.LLVMAddTypeName(cx.llmod, _str.buf("rust_tydesc"), T_tydesc()); llvm.LLVMAddTypeName(cx.llmod, _str.buf("tydesc"), T_tydesc(cx.tn));
} }
fn create_crate_constant(@crate_ctxt cx) { fn create_crate_constant(@crate_ctxt cx) {
@ -4568,8 +4625,8 @@ fn check_module(ModuleRef llmod) {
// TODO: run the linter here also, once there are llvm-c bindings for it. // TODO: run the linter here also, once there are llvm-c bindings for it.
} }
fn make_no_op_type_glue(ModuleRef llmod) -> ValueRef { fn make_no_op_type_glue(ModuleRef llmod, type_names tn) -> ValueRef {
auto ty = T_fn(vec(T_taskptr(), T_ptr(T_i8())), T_void()); auto ty = T_fn(vec(T_taskptr(tn), T_ptr(T_i8())), T_void());
auto fun = decl_fastcall_fn(llmod, abi.no_op_type_glue_name(), ty); auto fun = decl_fastcall_fn(llmod, abi.no_op_type_glue_name(), ty);
auto bb_name = _str.buf("_rust_no_op_type_glue_bb"); auto bb_name = _str.buf("_rust_no_op_type_glue_bb");
auto llbb = llvm.LLVMAppendBasicBlock(fun, bb_name); auto llbb = llvm.LLVMAppendBasicBlock(fun, bb_name);
@ -4663,9 +4720,9 @@ fn make_bzero_glue(ModuleRef llmod) -> ValueRef {
ret fun; ret fun;
} }
fn make_glues(ModuleRef llmod) -> @glue_fns { fn make_glues(ModuleRef llmod, type_names tn) -> @glue_fns {
ret @rec(activate_glue = decl_glue(llmod, abi.activate_glue_name()), ret @rec(activate_glue = decl_glue(llmod, tn, abi.activate_glue_name()),
yield_glue = decl_glue(llmod, abi.yield_glue_name()), yield_glue = decl_glue(llmod, tn, abi.yield_glue_name()),
/* /*
* Note: the signature passed to decl_cdecl_fn here looks unusual * Note: the signature passed to decl_cdecl_fn here looks unusual
* because it is. It corresponds neither to an upcall signature * because it is. It corresponds neither to an upcall signature
@ -4677,12 +4734,13 @@ fn make_glues(ModuleRef llmod) -> @glue_fns {
* this is the signature required to retrieve it. * this is the signature required to retrieve it.
*/ */
exit_task_glue = decl_cdecl_fn(llmod, abi.exit_task_glue_name(), exit_task_glue = decl_cdecl_fn(llmod, abi.exit_task_glue_name(),
T_fn(vec(T_taskptr()), T_void())), T_fn(vec(T_taskptr(tn)),
T_void())),
upcall_glues = upcall_glues =
_vec.init_fn[ValueRef](bind decl_upcall_glue(llmod, _), _vec.init_fn[ValueRef](bind decl_upcall_glue(llmod, tn, _),
abi.n_upcall_glues as uint), abi.n_upcall_glues as uint),
no_op_type_glue = make_no_op_type_glue(llmod), no_op_type_glue = make_no_op_type_glue(llmod, tn),
memcpy_glue = make_memcpy_glue(llmod), memcpy_glue = make_memcpy_glue(llmod),
bzero_glue = make_bzero_glue(llmod)); bzero_glue = make_bzero_glue(llmod));
} }
@ -4696,14 +4754,15 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
llvm.LLVMSetDataLayout(llmod, _str.buf(x86.get_data_layout())); llvm.LLVMSetDataLayout(llmod, _str.buf(x86.get_data_layout()));
llvm.LLVMSetTarget(llmod, _str.buf(x86.get_target_triple())); llvm.LLVMSetTarget(llmod, _str.buf(x86.get_target_triple()));
auto td = mk_target_data(x86.get_data_layout()); auto td = mk_target_data(x86.get_data_layout());
auto tn = mk_type_names();
let ValueRef crate_ptr = let ValueRef crate_ptr =
llvm.LLVMAddGlobal(llmod, T_crate(), _str.buf("rust_crate")); llvm.LLVMAddGlobal(llmod, T_crate(tn), _str.buf("rust_crate"));
llvm.LLVMSetModuleInlineAsm(llmod, _str.buf(x86.get_module_asm())); llvm.LLVMSetModuleInlineAsm(llmod, _str.buf(x86.get_module_asm()));
auto intrinsics = declare_intrinsics(llmod); auto intrinsics = declare_intrinsics(llmod);
auto glues = make_glues(llmod); auto glues = make_glues(llmod, tn);
auto hasher = ty.hash_ty; auto hasher = ty.hash_ty;
auto eqer = ty.eq_ty; auto eqer = ty.eq_ty;
auto tydescs = map.mk_hashmap[@ty.t,ValueRef](hasher, eqer); auto tydescs = map.mk_hashmap[@ty.t,ValueRef](hasher, eqer);
@ -4713,6 +4772,7 @@ fn trans_crate(session.session sess, @ast.crate crate, str output,
auto cx = @rec(sess = sess, auto cx = @rec(sess = sess,
llmod = llmod, llmod = llmod,
td = td, td = td,
tn = tn,
crate_ptr = crate_ptr, crate_ptr = crate_ptr,
upcalls = new_str_hash[ValueRef](), upcalls = new_str_hash[ValueRef](),
intrinsics = intrinsics, intrinsics = intrinsics,