提交 319156c8 编写于 作者: G Graydon Hoare

Begin tidying up name-mangling rules.

上级 ee54fa5c
......@@ -118,6 +118,7 @@ fn next(str prefix) -> str {
hashmap[ast::def_id,
@ast::native_item] native_items,
hashmap[ast::def_id, str] item_symbols,
mutable option::t[ValueRef] main_fn,
// TODO: hashmap[tup(tag_id,subtys), @tag_info]
hashmap[ty::t, uint] tag_sizes,
hashmap[ast::def_id, ValueRef] discrims,
......@@ -308,19 +309,10 @@ fn next(str prefix) -> str {
state type result = rec(@block_ctxt bcx,
ValueRef val);
fn sep() -> str {
ret "_";
}
fn extend_path(@local_ctxt cx, &str name) -> @local_ctxt {
ret @rec(path = cx.path + [name] with *cx);
}
fn path_name(&vec[str] path) -> str {
ret str::connect(path, sep());
}
fn get_type_sha1(&@crate_ctxt ccx, &ty::t t) -> str {
auto hash = "";
alt (ccx.type_sha1s.find(t)) {
......@@ -336,15 +328,31 @@ fn get_type_sha1(&@crate_ctxt ccx, &ty::t t) -> str {
ccx.sha.input_str(metadata::Encode::ty_str(cx, t));
hash = str::substr(ccx.sha.result_str(), 0u, 16u);
// Prefix with _ so that it never blends into adjacent digits
hash = "_" + hash;
ccx.type_sha1s.insert(t, hash);
}
}
ret hash;
}
fn mangle(&vec[str] ss) -> str {
// Follow C++ namespace-mangling style
auto n = "_ZN"; // Begin name-sequence.
for (str s in ss) {
n += #fmt("%u%s", str::byte_len(s), s);
}
n += "E"; // End name-sequence.
ret n;
}
fn mangle_name_by_type(&@crate_ctxt ccx, &vec[str] path, &ty::t t) -> str {
auto hash = get_type_sha1(ccx, t);
ret sep() + "rust" + sep() + hash + sep() + path_name(path);
ret mangle(path + [hash]);
}
fn mangle_name_by_type_only(&@crate_ctxt ccx, &ty::t t, &str name) -> str {
......@@ -353,14 +361,20 @@ fn mangle_name_by_type_only(&@crate_ctxt ccx, &ty::t t, &str name) -> str {
auto s = ty::ty_to_short_str(ccx.tcx, t);
auto hash = get_type_sha1(ccx, t);
ret sep() + "rust" + sep() + hash + sep() + name + "_" + s;
ret mangle([name, s, hash]);
}
fn mangle_name_by_path_and_seq(&@crate_ctxt ccx, &vec[str] path,
&str flav) -> str {
ret mangle(path + [ccx.names.next(flav)]);
}
fn mangle_name_by_path(&@crate_ctxt ccx, &vec[str] path) -> str {
ret mangle(path);
}
fn mangle_name_by_seq(&@crate_ctxt ccx, &vec[str] path,
&str flav) -> str {
ret sep() + "rust" + sep()
+ ccx.names.next(flav) + sep()
+ path_name(path);
fn mangle_name_by_seq(&@crate_ctxt ccx, &str flav) -> str {
ret ccx.names.next(flav);
}
fn res(@block_ctxt bcx, ValueRef val) -> result {
......@@ -1903,7 +1917,7 @@ fn declare_tydesc(&@local_ctxt cx, &span sp, &ty::t t,
name = mangle_name_by_type_only(cx.ccx, t, "tydesc");
name = sanitize(name);
} else {
name = mangle_name_by_seq(cx.ccx, cx.path, "tydesc");
name = mangle_name_by_seq(cx.ccx, "tydesc");
}
auto gvar = llvm::LLVMAddGlobal(ccx.llmod, T_tydesc(ccx.tn),
......@@ -1937,7 +1951,7 @@ fn declare_generic_glue(&@local_ctxt cx,
fn_nm = mangle_name_by_type_only(cx.ccx, t, "glue_" + name);
fn_nm = sanitize(fn_nm);
} else {
fn_nm = mangle_name_by_seq(cx.ccx, cx.path, "glue_" + name);
fn_nm = mangle_name_by_seq(cx.ccx, "glue_" + name);
}
auto llfn = decl_fastcall_fn(cx.ccx.llmod, fn_nm, llfnty);
set_glue_inlining(cx, llfn, t);
......@@ -4093,7 +4107,7 @@ fn trans_for_each(&@block_ctxt cx,
// Step 2: Declare foreach body function.
let str s = mangle_name_by_seq(lcx.ccx, lcx.path, "foreach");
let str s = mangle_name_by_path_and_seq(lcx.ccx, lcx.path, "foreach");
// The 'env' arg entering the body function is a fake env member (as in
// the env-part of the normal rust calling convention) that actually
......@@ -4792,7 +4806,7 @@ fn trans_bind_thunk(&@local_ctxt cx,
// Construct a thunk-call with signature incoming_fty, and that copies
// args forward into a call to outgoing_fty:
let str s = mangle_name_by_seq(cx.ccx, cx.path, "thunk");
let str s = mangle_name_by_path_and_seq(cx.ccx, cx.path, "thunk");
let TypeRef llthunk_ty = get_pair_fn_ty(type_of(cx.ccx, sp,
incoming_fty));
let ValueRef llthunk = decl_internal_fastcall_fn(cx.ccx.llmod,
......@@ -6225,9 +6239,10 @@ fn mk_spawn_wrapper(&@block_ctxt cx,
0u);
// TODO: construct a name based on tname
let str wrap_name = mangle_name_by_seq(cx.fcx.lcx.ccx,
[""],
"spawn_wrapper");
let str wrap_name =
mangle_name_by_path_and_seq(cx.fcx.lcx.ccx,
cx.fcx.lcx.path,
"spawn_wrapper");
auto llfndecl = decl_fastcall_fn(llmod, wrap_name,
wrapper_fn_type);
......@@ -7078,8 +7093,9 @@ fn meth_lteq(&@ast::method a, &@ast::method b) -> bool {
}
}
let @local_ctxt mcx = extend_path(cx, m.node.ident);
let str s = mangle_name_by_seq(mcx.ccx, mcx.path, "method");
let @local_ctxt mcx = @rec(path = cx.path + ["method",
m.node.ident] with *cx);
let str s = mangle_name_by_path(mcx.ccx, mcx.path);
let ValueRef llfn = decl_internal_fastcall_fn(cx.ccx.llmod, s,
llfnty);
cx.ccx.item_ids.insert(m.node.id, llfn);
......@@ -7091,7 +7107,7 @@ fn meth_lteq(&@ast::method a, &@ast::method b) -> bool {
methods += [llfn];
}
auto vtbl = C_struct(methods);
auto vtbl_name = mangle_name_by_seq(cx.ccx, cx.path, "vtbl");
auto vtbl_name = mangle_name_by_path(cx.ccx, cx.path + ["vtbl"]);
auto gvar = llvm::LLVMAddGlobal(cx.ccx.llmod, val_ty(vtbl),
str::buf(vtbl_name));
llvm::LLVMSetInitializer(gvar, vtbl);
......@@ -7108,13 +7124,12 @@ fn trans_dtor(@local_ctxt cx,
&@ast::method dtor) -> ValueRef {
auto llfnty = T_dtor(cx.ccx, dtor.span, llself_ty);
let @local_ctxt dcx = extend_path(cx, "drop");
let str s = mangle_name_by_seq(dcx.ccx, dcx.path, "drop");
let str s = mangle_name_by_path(cx.ccx, cx.path + ["drop"]);
let ValueRef llfn = decl_internal_fastcall_fn(cx.ccx.llmod, s, llfnty);
cx.ccx.item_ids.insert(dtor.node.id, llfn);
cx.ccx.item_symbols.insert(dtor.node.id, s);
trans_fn(dcx, dtor.span, dtor.node.meth, dtor.node.id,
trans_fn(cx, dtor.span, dtor.node.meth, dtor.node.id,
some[ty_self_pair](tup(llself_ty, self_ty)),
ty_params, dtor.node.ann);
......@@ -7503,13 +7518,22 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp,
}
// Declare the function itself.
let str s = mangle_name_by_seq(ccx, path, flav);
let str s = mangle_name_by_path(ccx, path);
let ValueRef llfn = decl_internal_fastcall_fn(ccx.llmod, s, llfty);
// Declare the global constant pair that points to it.
let str ps = mangle_name_by_type(ccx, path, node_ann_type(ccx, ann));
register_fn_pair(ccx, ps, llpairty, llfn, id);
if (str::eq(vec::top(path), "main") &&
!ccx.sess.get_opts().shared) {
if (ccx.main_fn != none[ValueRef]) {
ccx.sess.span_err(sp, "multiple 'main' functions");
}
log #fmt("registering %s as main function for crate", ps);
ccx.main_fn = some(llfn);
}
}
fn register_fn_pair(&@crate_ctxt cx, str ps, TypeRef llpairty, ValueRef llfn,
......@@ -7569,7 +7593,7 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx,
// Declare the wrapper.
auto t = node_ann_type(ccx, ann);
auto wrapper_type = native_fn_wrapper_type(ccx, sp, num_ty_param, t);
let str s = mangle_name_by_seq(ccx, path, "wrapper");
let str s = mangle_name_by_path(ccx, path);
let ValueRef wrapper_fn = decl_internal_fastcall_fn(ccx.llmod, s,
wrapper_type);
......@@ -7912,9 +7936,8 @@ fn trans_constant(&@crate_ctxt ccx, @walk_ctxt wcx, &@ast::item it) {
auto discrim_val = C_int(i as int);
auto s = mangle_name_by_seq(ccx, wcx.path,
#fmt("_rust_tag_discrim_%s_%u",
ident, i));
auto p = wcx.path + [ident, variant.node.name, "discrim"];
auto s = mangle_name_by_type(ccx, p, ty::mk_int(ccx.tcx));
auto discrim_gvar = llvm::LLVMAddGlobal(ccx.llmod, T_int(),
str::buf(s));
......@@ -7973,29 +7996,6 @@ fn create_typedefs(&@crate_ctxt cx) {
llvm::LLVMAddTypeName(cx.llmod, str::buf("tydesc"), T_tydesc(cx.tn));
}
fn find_main_fn(&@crate_ctxt cx) -> ValueRef {
auto e = sep() + "main";
let ValueRef v = C_nil();
let uint n = 0u;
for each (@tup(ast::def_id, str) i in cx.item_symbols.items()) {
if (str::ends_with(i._1, e)) {
n += 1u;
v = cx.item_ids.get(i._0);
}
}
alt (n) {
case (0u) {
cx.sess.err("main fn not found");
}
case (1u) {
ret v;
}
case (_) {
cx.sess.err("multiple main fns found");
}
}
}
fn trans_main_fn(@local_ctxt cx, ValueRef crate_map) {
auto T_main_args = [T_int(), T_int()];
auto T_rust_start_args = [T_int(), T_int(), T_int(), T_int()];
......@@ -8015,7 +8015,14 @@ fn trans_main_fn(@local_ctxt cx, ValueRef crate_map) {
auto llargc = llvm::LLVMGetParam(llmain, 0u);
auto llargv = llvm::LLVMGetParam(llmain, 1u);
auto llrust_main = find_main_fn(cx.ccx);
auto llrust_main = alt (cx.ccx.main_fn) {
case (none) {
cx.ccx.sess.err("missing 'main' function");
// FIXME: shouldn't sess.err's ! result unify with f?
C_nil()
}
case (some(?f)) { f }
};
//
// Emit the moral equivalent of:
......@@ -8283,6 +8290,7 @@ fn trans_crate(&session::session sess, &@ast::crate crate,
items = new_def_hash[@ast::item](),
native_items = new_def_hash[@ast::native_item](),
item_symbols = new_def_hash[str](),
mutable main_fn = none[ValueRef],
tag_sizes = tag_sizes,
discrims = new_def_hash[ValueRef](),
discrim_symbols = new_def_hash[str](),
......
......@@ -193,6 +193,12 @@ fn pop[T](&mutable array[T] v) -> T {
ret e;
}
fn top[T](&array[T] v) -> T {
auto ln = len[T](v);
assert (ln > 0u);
ret v.(ln-1u);
}
fn push[T](&mutable array[T] v, &T t) {
v += [t];
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册