Skip to content

Commit 319156c

Browse files
committed
Begin tidying up name-mangling rules.
1 parent ee54fa5 commit 319156c

File tree

2 files changed

+72
-58
lines changed

2 files changed

+72
-58
lines changed

src/comp/middle/trans.rs

+66-58
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ state type crate_ctxt = rec(session::session sess,
118118
hashmap[ast::def_id,
119119
@ast::native_item] native_items,
120120
hashmap[ast::def_id, str] item_symbols,
121+
mutable option::t[ValueRef] main_fn,
121122
// TODO: hashmap[tup(tag_id,subtys), @tag_info]
122123
hashmap[ty::t, uint] tag_sizes,
123124
hashmap[ast::def_id, ValueRef] discrims,
@@ -308,19 +309,10 @@ tag block_parent {
308309
state type result = rec(@block_ctxt bcx,
309310
ValueRef val);
310311

311-
fn sep() -> str {
312-
ret "_";
313-
}
314-
315312
fn extend_path(@local_ctxt cx, &str name) -> @local_ctxt {
316313
ret @rec(path = cx.path + [name] with *cx);
317314
}
318315

319-
fn path_name(&vec[str] path) -> str {
320-
ret str::connect(path, sep());
321-
}
322-
323-
324316
fn get_type_sha1(&@crate_ctxt ccx, &ty::t t) -> str {
325317
auto hash = "";
326318
alt (ccx.type_sha1s.find(t)) {
@@ -336,15 +328,31 @@ fn get_type_sha1(&@crate_ctxt ccx, &ty::t t) -> str {
336328

337329
ccx.sha.input_str(metadata::Encode::ty_str(cx, t));
338330
hash = str::substr(ccx.sha.result_str(), 0u, 16u);
331+
// Prefix with _ so that it never blends into adjacent digits
332+
hash = "_" + hash;
339333
ccx.type_sha1s.insert(t, hash);
340334
}
341335
}
342336
ret hash;
343337
}
344338

339+
fn mangle(&vec[str] ss) -> str {
340+
341+
// Follow C++ namespace-mangling style
342+
343+
auto n = "_ZN"; // Begin name-sequence.
344+
345+
for (str s in ss) {
346+
n += #fmt("%u%s", str::byte_len(s), s);
347+
}
348+
349+
n += "E"; // End name-sequence.
350+
ret n;
351+
}
352+
345353
fn mangle_name_by_type(&@crate_ctxt ccx, &vec[str] path, &ty::t t) -> str {
346354
auto hash = get_type_sha1(ccx, t);
347-
ret sep() + "rust" + sep() + hash + sep() + path_name(path);
355+
ret mangle(path + [hash]);
348356
}
349357

350358
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 {
353361
auto s = ty::ty_to_short_str(ccx.tcx, t);
354362

355363
auto hash = get_type_sha1(ccx, t);
356-
ret sep() + "rust" + sep() + hash + sep() + name + "_" + s;
364+
ret mangle([name, s, hash]);
365+
}
366+
367+
fn mangle_name_by_path_and_seq(&@crate_ctxt ccx, &vec[str] path,
368+
&str flav) -> str {
369+
ret mangle(path + [ccx.names.next(flav)]);
370+
}
371+
372+
fn mangle_name_by_path(&@crate_ctxt ccx, &vec[str] path) -> str {
373+
ret mangle(path);
357374
}
358375

359-
fn mangle_name_by_seq(&@crate_ctxt ccx, &vec[str] path,
360-
&str flav) -> str {
361-
ret sep() + "rust" + sep()
362-
+ ccx.names.next(flav) + sep()
363-
+ path_name(path);
376+
fn mangle_name_by_seq(&@crate_ctxt ccx, &str flav) -> str {
377+
ret ccx.names.next(flav);
364378
}
365379

366380
fn res(@block_ctxt bcx, ValueRef val) -> result {
@@ -1903,7 +1917,7 @@ fn declare_tydesc(&@local_ctxt cx, &span sp, &ty::t t,
19031917
name = mangle_name_by_type_only(cx.ccx, t, "tydesc");
19041918
name = sanitize(name);
19051919
} else {
1906-
name = mangle_name_by_seq(cx.ccx, cx.path, "tydesc");
1920+
name = mangle_name_by_seq(cx.ccx, "tydesc");
19071921
}
19081922

19091923
auto gvar = llvm::LLVMAddGlobal(ccx.llmod, T_tydesc(ccx.tn),
@@ -1937,7 +1951,7 @@ fn declare_generic_glue(&@local_ctxt cx,
19371951
fn_nm = mangle_name_by_type_only(cx.ccx, t, "glue_" + name);
19381952
fn_nm = sanitize(fn_nm);
19391953
} else {
1940-
fn_nm = mangle_name_by_seq(cx.ccx, cx.path, "glue_" + name);
1954+
fn_nm = mangle_name_by_seq(cx.ccx, "glue_" + name);
19411955
}
19421956
auto llfn = decl_fastcall_fn(cx.ccx.llmod, fn_nm, llfnty);
19431957
set_glue_inlining(cx, llfn, t);
@@ -4093,7 +4107,7 @@ fn trans_for_each(&@block_ctxt cx,
40934107

40944108
// Step 2: Declare foreach body function.
40954109

4096-
let str s = mangle_name_by_seq(lcx.ccx, lcx.path, "foreach");
4110+
let str s = mangle_name_by_path_and_seq(lcx.ccx, lcx.path, "foreach");
40974111

40984112
// The 'env' arg entering the body function is a fake env member (as in
40994113
// the env-part of the normal rust calling convention) that actually
@@ -4792,7 +4806,7 @@ fn trans_bind_thunk(&@local_ctxt cx,
47924806
// Construct a thunk-call with signature incoming_fty, and that copies
47934807
// args forward into a call to outgoing_fty:
47944808

4795-
let str s = mangle_name_by_seq(cx.ccx, cx.path, "thunk");
4809+
let str s = mangle_name_by_path_and_seq(cx.ccx, cx.path, "thunk");
47964810
let TypeRef llthunk_ty = get_pair_fn_ty(type_of(cx.ccx, sp,
47974811
incoming_fty));
47984812
let ValueRef llthunk = decl_internal_fastcall_fn(cx.ccx.llmod,
@@ -6225,9 +6239,10 @@ fn mk_spawn_wrapper(&@block_ctxt cx,
62256239
0u);
62266240

62276241
// TODO: construct a name based on tname
6228-
let str wrap_name = mangle_name_by_seq(cx.fcx.lcx.ccx,
6229-
[""],
6230-
"spawn_wrapper");
6242+
let str wrap_name =
6243+
mangle_name_by_path_and_seq(cx.fcx.lcx.ccx,
6244+
cx.fcx.lcx.path,
6245+
"spawn_wrapper");
62316246
auto llfndecl = decl_fastcall_fn(llmod, wrap_name,
62326247
wrapper_fn_type);
62336248

@@ -7078,8 +7093,9 @@ fn create_vtbl(@local_ctxt cx,
70787093
}
70797094
}
70807095

7081-
let @local_ctxt mcx = extend_path(cx, m.node.ident);
7082-
let str s = mangle_name_by_seq(mcx.ccx, mcx.path, "method");
7096+
let @local_ctxt mcx = @rec(path = cx.path + ["method",
7097+
m.node.ident] with *cx);
7098+
let str s = mangle_name_by_path(mcx.ccx, mcx.path);
70837099
let ValueRef llfn = decl_internal_fastcall_fn(cx.ccx.llmod, s,
70847100
llfnty);
70857101
cx.ccx.item_ids.insert(m.node.id, llfn);
@@ -7091,7 +7107,7 @@ fn create_vtbl(@local_ctxt cx,
70917107
methods += [llfn];
70927108
}
70937109
auto vtbl = C_struct(methods);
7094-
auto vtbl_name = mangle_name_by_seq(cx.ccx, cx.path, "vtbl");
7110+
auto vtbl_name = mangle_name_by_path(cx.ccx, cx.path + ["vtbl"]);
70957111
auto gvar = llvm::LLVMAddGlobal(cx.ccx.llmod, val_ty(vtbl),
70967112
str::buf(vtbl_name));
70977113
llvm::LLVMSetInitializer(gvar, vtbl);
@@ -7108,13 +7124,12 @@ fn trans_dtor(@local_ctxt cx,
71087124
&@ast::method dtor) -> ValueRef {
71097125

71107126
auto llfnty = T_dtor(cx.ccx, dtor.span, llself_ty);
7111-
let @local_ctxt dcx = extend_path(cx, "drop");
7112-
let str s = mangle_name_by_seq(dcx.ccx, dcx.path, "drop");
7127+
let str s = mangle_name_by_path(cx.ccx, cx.path + ["drop"]);
71137128
let ValueRef llfn = decl_internal_fastcall_fn(cx.ccx.llmod, s, llfnty);
71147129
cx.ccx.item_ids.insert(dtor.node.id, llfn);
71157130
cx.ccx.item_symbols.insert(dtor.node.id, s);
71167131

7117-
trans_fn(dcx, dtor.span, dtor.node.meth, dtor.node.id,
7132+
trans_fn(cx, dtor.span, dtor.node.meth, dtor.node.id,
71187133
some[ty_self_pair](tup(llself_ty, self_ty)),
71197134
ty_params, dtor.node.ann);
71207135

@@ -7503,13 +7518,22 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp,
75037518
}
75047519

75057520
// Declare the function itself.
7506-
let str s = mangle_name_by_seq(ccx, path, flav);
7521+
let str s = mangle_name_by_path(ccx, path);
75077522
let ValueRef llfn = decl_internal_fastcall_fn(ccx.llmod, s, llfty);
75087523

75097524
// Declare the global constant pair that points to it.
75107525
let str ps = mangle_name_by_type(ccx, path, node_ann_type(ccx, ann));
75117526

75127527
register_fn_pair(ccx, ps, llpairty, llfn, id);
7528+
7529+
if (str::eq(vec::top(path), "main") &&
7530+
!ccx.sess.get_opts().shared) {
7531+
if (ccx.main_fn != none[ValueRef]) {
7532+
ccx.sess.span_err(sp, "multiple 'main' functions");
7533+
}
7534+
log #fmt("registering %s as main function for crate", ps);
7535+
ccx.main_fn = some(llfn);
7536+
}
75137537
}
75147538

75157539
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,
75697593
// Declare the wrapper.
75707594
auto t = node_ann_type(ccx, ann);
75717595
auto wrapper_type = native_fn_wrapper_type(ccx, sp, num_ty_param, t);
7572-
let str s = mangle_name_by_seq(ccx, path, "wrapper");
7596+
let str s = mangle_name_by_path(ccx, path);
75737597
let ValueRef wrapper_fn = decl_internal_fastcall_fn(ccx.llmod, s,
75747598
wrapper_type);
75757599

@@ -7912,9 +7936,8 @@ fn trans_constant(&@crate_ctxt ccx, @walk_ctxt wcx, &@ast::item it) {
79127936

79137937
auto discrim_val = C_int(i as int);
79147938

7915-
auto s = mangle_name_by_seq(ccx, wcx.path,
7916-
#fmt("_rust_tag_discrim_%s_%u",
7917-
ident, i));
7939+
auto p = wcx.path + [ident, variant.node.name, "discrim"];
7940+
auto s = mangle_name_by_type(ccx, p, ty::mk_int(ccx.tcx));
79187941
auto discrim_gvar = llvm::LLVMAddGlobal(ccx.llmod, T_int(),
79197942
str::buf(s));
79207943

@@ -7973,29 +7996,6 @@ fn create_typedefs(&@crate_ctxt cx) {
79737996
llvm::LLVMAddTypeName(cx.llmod, str::buf("tydesc"), T_tydesc(cx.tn));
79747997
}
79757998

7976-
fn find_main_fn(&@crate_ctxt cx) -> ValueRef {
7977-
auto e = sep() + "main";
7978-
let ValueRef v = C_nil();
7979-
let uint n = 0u;
7980-
for each (@tup(ast::def_id, str) i in cx.item_symbols.items()) {
7981-
if (str::ends_with(i._1, e)) {
7982-
n += 1u;
7983-
v = cx.item_ids.get(i._0);
7984-
}
7985-
}
7986-
alt (n) {
7987-
case (0u) {
7988-
cx.sess.err("main fn not found");
7989-
}
7990-
case (1u) {
7991-
ret v;
7992-
}
7993-
case (_) {
7994-
cx.sess.err("multiple main fns found");
7995-
}
7996-
}
7997-
}
7998-
79997999
fn trans_main_fn(@local_ctxt cx, ValueRef crate_map) {
80008000
auto T_main_args = [T_int(), T_int()];
80018001
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) {
80158015

80168016
auto llargc = llvm::LLVMGetParam(llmain, 0u);
80178017
auto llargv = llvm::LLVMGetParam(llmain, 1u);
8018-
auto llrust_main = find_main_fn(cx.ccx);
8018+
auto llrust_main = alt (cx.ccx.main_fn) {
8019+
case (none) {
8020+
cx.ccx.sess.err("missing 'main' function");
8021+
// FIXME: shouldn't sess.err's ! result unify with f?
8022+
C_nil()
8023+
}
8024+
case (some(?f)) { f }
8025+
};
80198026

80208027
//
80218028
// Emit the moral equivalent of:
@@ -8283,6 +8290,7 @@ fn trans_crate(&session::session sess, &@ast::crate crate,
82838290
items = new_def_hash[@ast::item](),
82848291
native_items = new_def_hash[@ast::native_item](),
82858292
item_symbols = new_def_hash[str](),
8293+
mutable main_fn = none[ValueRef],
82868294
tag_sizes = tag_sizes,
82878295
discrims = new_def_hash[ValueRef](),
82888296
discrim_symbols = new_def_hash[str](),

src/lib/vec.rs

+6
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ fn pop[T](&mutable array[T] v) -> T {
193193
ret e;
194194
}
195195

196+
fn top[T](&array[T] v) -> T {
197+
auto ln = len[T](v);
198+
assert (ln > 0u);
199+
ret v.(ln-1u);
200+
}
201+
196202
fn push[T](&mutable array[T] v, &T t) {
197203
v += [t];
198204
}

0 commit comments

Comments
 (0)