Skip to content

Commit bee114d

Browse files
committed
---
yaml --- r: 79401 b: refs/heads/snap-stage3 c: 3c3ae1d h: refs/heads/master i: 79399: 3e5e5c8 v: v3
1 parent bf30ca7 commit bee114d

File tree

15 files changed

+263
-84
lines changed

15 files changed

+263
-84
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 124eb2119c78651cfaaa7a046a101fa2e20f83ca
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 6b7b8f2682780306860a38cdc7138f603e859fde
4+
refs/heads/snap-stage3: 3c3ae1d0e26c9ae0906dc57daa14bb9e4627e3c8
55
refs/heads/try: ac820906c0e53eab79a98ee64f7231f57c3887b4
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/back/link.rs

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use std::run;
3535
use std::str;
3636
use std::vec;
3737
use syntax::ast;
38-
use syntax::ast_map::{path, path_mod, path_name};
38+
use syntax::ast_map::{path, path_mod, path_name, path_pretty_name};
3939
use syntax::attr;
4040
use syntax::attr::{AttrMetaMethods};
4141
use syntax::print::pprust;
@@ -667,8 +667,7 @@ pub fn truncated_hash_result(symbol_hasher: &mut hash::State) -> ~str {
667667
pub fn symbol_hash(tcx: ty::ctxt,
668668
symbol_hasher: &mut hash::State,
669669
t: ty::t,
670-
link_meta: LinkMeta)
671-
-> @str {
670+
link_meta: LinkMeta) -> @str {
672671
// NB: do *not* use abbrevs here as we want the symbol names
673672
// to be independent of one another in the crate.
674673

@@ -723,7 +722,7 @@ pub fn sanitize(s: &str) -> ~str {
723722
'a' .. 'z'
724723
| 'A' .. 'Z'
725724
| '0' .. '9'
726-
| '_' => result.push_char(c),
725+
| '_' | '.' => result.push_char(c),
727726

728727
_ => {
729728
let mut tstr = ~"";
@@ -744,19 +743,65 @@ pub fn sanitize(s: &str) -> ~str {
744743
return result;
745744
}
746745

747-
pub fn mangle(sess: Session, ss: path) -> ~str {
748-
// Follow C++ namespace-mangling style
746+
pub fn mangle(sess: Session, ss: path,
747+
hash: Option<&str>, vers: Option<&str>) -> ~str {
748+
// Follow C++ namespace-mangling style, see
749+
// http://en.wikipedia.org/wiki/Name_mangling for more info.
750+
//
751+
// It turns out that on OSX you can actually have arbitrary symbols in
752+
// function names (at least when given to LLVM), but this is not possible
753+
// when using unix's linker. Perhaps one day when we just a linker from LLVM
754+
// we won't need to do this name mangling. The problem with name mangling is
755+
// that it seriously limits the available characters. For example we can't
756+
// have things like @T or ~[T] in symbol names when one would theoretically
757+
// want them for things like impls of traits on that type.
758+
//
759+
// To be able to work on all platforms and get *some* reasonable output, we
760+
// use C++ name-mangling.
761+
762+
let mut n = ~"_ZN"; // _Z == Begin name-sequence, N == nested
763+
764+
let push = |s: &str| {
765+
let sani = sanitize(s);
766+
n.push_str(fmt!("%u%s", sani.len(), sani));
767+
};
749768

750-
let mut n = ~"_ZN"; // Begin name-sequence.
769+
// First, connect each component with <len, name> pairs.
770+
for s in ss.iter() {
771+
match *s {
772+
path_name(s) | path_mod(s) | path_pretty_name(s, _) => {
773+
push(sess.str_of(s))
774+
}
775+
}
776+
}
751777

778+
// next, if any identifiers are "pretty" and need extra information tacked
779+
// on, then use the hash to generate two unique characters. For now
780+
// hopefully 2 characters is enough to avoid collisions.
781+
static EXTRA_CHARS: &'static str =
782+
"abcdefghijklmnopqrstuvwxyz\
783+
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
784+
0123456789";
785+
let mut hash = match hash { Some(s) => s.to_owned(), None => ~"" };
752786
for s in ss.iter() {
753787
match *s {
754-
path_name(s) | path_mod(s) => {
755-
let sani = sanitize(sess.str_of(s));
756-
n.push_str(fmt!("%u%s", sani.len(), sani));
788+
path_pretty_name(_, extra) => {
789+
let hi = (extra >> 32) as u32 as uint;
790+
let lo = extra as u32 as uint;
791+
hash.push_char(EXTRA_CHARS[hi % EXTRA_CHARS.len()] as char);
792+
hash.push_char(EXTRA_CHARS[lo % EXTRA_CHARS.len()] as char);
757793
}
794+
_ => {}
758795
}
759796
}
797+
if hash.len() > 0 {
798+
push(hash);
799+
}
800+
match vers {
801+
Some(s) => push(s),
802+
None => {}
803+
}
804+
760805
n.push_char('E'); // End name-sequence.
761806
n
762807
}
@@ -765,10 +810,15 @@ pub fn exported_name(sess: Session,
765810
path: path,
766811
hash: &str,
767812
vers: &str) -> ~str {
768-
mangle(sess,
769-
vec::append_one(
770-
vec::append_one(path, path_name(sess.ident_of(hash))),
771-
path_name(sess.ident_of(vers))))
813+
// The version will get mangled to have a leading '_', but it makes more
814+
// sense to lead with a 'v' b/c this is a version...
815+
let vers = if vers.len() > 0 && !char::is_XID_start(vers.char_at(0)) {
816+
"v" + vers
817+
} else {
818+
vers.to_owned()
819+
};
820+
821+
mangle(sess, path, Some(hash), Some(vers.as_slice()))
772822
}
773823

774824
pub fn mangle_exported_name(ccx: &mut CrateContext,
@@ -786,31 +836,33 @@ pub fn mangle_internal_name_by_type_only(ccx: &mut CrateContext,
786836
let s = ppaux::ty_to_short_str(ccx.tcx, t);
787837
let hash = get_symbol_hash(ccx, t);
788838
return mangle(ccx.sess,
789-
~[path_name(ccx.sess.ident_of(name)),
790-
path_name(ccx.sess.ident_of(s)),
791-
path_name(ccx.sess.ident_of(hash))]);
839+
~[path_name(ccx.sess.ident_of(name)),
840+
path_name(ccx.sess.ident_of(s))],
841+
Some(hash.as_slice()),
842+
None);
792843
}
793844

794845
pub fn mangle_internal_name_by_type_and_seq(ccx: &mut CrateContext,
795-
t: ty::t,
796-
name: &str) -> ~str {
846+
t: ty::t,
847+
name: &str) -> ~str {
797848
let s = ppaux::ty_to_str(ccx.tcx, t);
798849
let hash = get_symbol_hash(ccx, t);
799850
return mangle(ccx.sess,
800-
~[path_name(ccx.sess.ident_of(s)),
801-
path_name(ccx.sess.ident_of(hash)),
802-
path_name(gensym_name(name))]);
851+
~[path_name(ccx.sess.ident_of(s)),
852+
path_name(gensym_name(name))],
853+
Some(hash.as_slice()),
854+
None);
803855
}
804856

805857
pub fn mangle_internal_name_by_path_and_seq(ccx: &mut CrateContext,
806858
mut path: path,
807859
flav: &str) -> ~str {
808860
path.push(path_name(gensym_name(flav)));
809-
mangle(ccx.sess, path)
861+
mangle(ccx.sess, path, None, None)
810862
}
811863

812864
pub fn mangle_internal_name_by_path(ccx: &mut CrateContext, path: path) -> ~str {
813-
mangle(ccx.sess, path)
865+
mangle(ccx.sess, path, None, None)
814866
}
815867

816868
pub fn mangle_internal_name_by_seq(_ccx: &mut CrateContext, flav: &str) -> ~str {

branches/snap-stage3/src/librustc/metadata/common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ pub static tag_impls_impl: uint = 0x84;
188188
pub static tag_items_data_item_inherent_impl: uint = 0x85;
189189
pub static tag_items_data_item_extension_impl: uint = 0x86;
190190

191+
pub static tag_path_elt_pretty_name: uint = 0x87;
192+
pub static tag_path_elt_pretty_name_ident: uint = 0x88;
193+
pub static tag_path_elt_pretty_name_extra: uint = 0x89;
194+
191195
pub struct LinkMeta {
192196
name: @str,
193197
vers: @str,

branches/snap-stage3/src/librustc/metadata/decoder.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,15 @@ fn item_path(item_doc: ebml::Doc) -> ast_map::path {
303303
} else if tag == tag_path_elt_name {
304304
let str = elt_doc.as_str_slice();
305305
result.push(ast_map::path_name(token::str_to_ident(str)));
306+
} else if tag == tag_path_elt_pretty_name {
307+
let name_doc = reader::get_doc(elt_doc,
308+
tag_path_elt_pretty_name_ident);
309+
let extra_doc = reader::get_doc(elt_doc,
310+
tag_path_elt_pretty_name_extra);
311+
let str = name_doc.as_str_slice();
312+
let extra = reader::doc_as_u64(extra_doc);
313+
result.push(ast_map::path_pretty_name(token::str_to_ident(str),
314+
extra));
306315
} else {
307316
// ignore tag_path_len element
308317
}

branches/snap-stage3/src/librustc/metadata/encoder.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -359,12 +359,21 @@ fn encode_path(ecx: &EncodeContext,
359359
fn encode_path_elt(ecx: &EncodeContext,
360360
ebml_w: &mut writer::Encoder,
361361
elt: ast_map::path_elt) {
362-
let (tag, name) = match elt {
363-
ast_map::path_mod(name) => (tag_path_elt_mod, name),
364-
ast_map::path_name(name) => (tag_path_elt_name, name)
365-
};
366-
367-
ebml_w.wr_tagged_str(tag, ecx.tcx.sess.str_of(name));
362+
match elt {
363+
ast_map::path_mod(n) => {
364+
ebml_w.wr_tagged_str(tag_path_elt_mod, ecx.tcx.sess.str_of(n));
365+
}
366+
ast_map::path_name(n) => {
367+
ebml_w.wr_tagged_str(tag_path_elt_name, ecx.tcx.sess.str_of(n));
368+
}
369+
ast_map::path_pretty_name(n, extra) => {
370+
ebml_w.start_tag(tag_path_elt_pretty_name);
371+
ebml_w.wr_tagged_str(tag_path_elt_pretty_name_ident,
372+
ecx.tcx.sess.str_of(n));
373+
ebml_w.wr_tagged_u64(tag_path_elt_pretty_name_extra, extra);
374+
ebml_w.end_tag();
375+
}
376+
}
368377
}
369378

370379
ebml_w.start_tag(tag_path);

branches/snap-stage3/src/librustc/middle/trans/base.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use std::local_data;
7777
use extra::time;
7878
use extra::sort;
7979
use syntax::ast::Ident;
80-
use syntax::ast_map::{path, path_elt_to_str, path_name};
80+
use syntax::ast_map::{path, path_elt_to_str, path_name, path_pretty_name};
8181
use syntax::ast_util::{local_def};
8282
use syntax::attr;
8383
use syntax::attr::AttrMetaMethods;
@@ -2627,8 +2627,7 @@ pub fn register_method(ccx: @mut CrateContext,
26272627
let mty = ty::node_id_to_type(ccx.tcx, id);
26282628

26292629
let mut path = (*path).clone();
2630-
path.push(path_name(gensym_name("meth")));
2631-
path.push(path_name(m.ident));
2630+
path.push(path_pretty_name(m.ident, token::gensym("meth") as u64));
26322631

26332632
let sym = exported_name(ccx, path, mty, m.attrs);
26342633

branches/snap-stage3/src/librustc/middle/trans/common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,8 @@ pub fn path_str(sess: session::Session, p: &[path_elt]) -> ~str {
948948
let mut first = true;
949949
for e in p.iter() {
950950
match *e {
951-
ast_map::path_name(s) | ast_map::path_mod(s) => {
951+
ast_map::path_name(s) | ast_map::path_mod(s) |
952+
ast_map::path_pretty_name(s, _) => {
952953
if first {
953954
first = false
954955
} else {

branches/snap-stage3/src/librustc/middle/trans/meth.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use middle::trans::type_::Type;
3434

3535
use std::c_str::ToCStr;
3636
use std::vec;
37-
use syntax::ast_map::{path, path_mod, path_name};
37+
use syntax::ast_map::{path, path_mod, path_name, path_pretty_name};
3838
use syntax::ast_util;
3939
use syntax::{ast, ast_map};
4040
use syntax::visit;
@@ -254,7 +254,7 @@ pub fn trans_static_method_callee(bcx: @mut Block,
254254
} else {
255255
let path = csearch::get_item_path(bcx.tcx(), method_id);
256256
match path[path.len()-1] {
257-
path_name(s) => { s }
257+
path_pretty_name(s, _) | path_name(s) => { s }
258258
path_mod(_) => { fail!("path doesn't have a name?") }
259259
}
260260
};

branches/snap-stage3/src/librustc/util/ppaux.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,8 @@ impl Repr for ast_map::path_elt {
799799
fn repr(&self, tcx: ctxt) -> ~str {
800800
match *self {
801801
ast_map::path_mod(id) => id.repr(tcx),
802-
ast_map::path_name(id) => id.repr(tcx)
802+
ast_map::path_name(id) => id.repr(tcx),
803+
ast_map::path_pretty_name(id, _) => id.repr(tcx),
803804
}
804805
}
805806
}

0 commit comments

Comments
 (0)