auto merge of #12875 : alexcrichton/rust/demangle-more-things, r=brson

Add some more infrastructure support for demangling `$`-sequences, as well as fixing demangling of closure symbol names if there's more than one closure in a function.
This commit is contained in:
bors 2014-03-14 06:41:26 -07:00
commit 339f8163d6
2 changed files with 60 additions and 8 deletions

View file

@ -103,8 +103,13 @@ pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx, ty)
}
/// Generates a unique symbol based off the name given. This is used to create
/// unique symbols for things like closures.
pub fn gensym_name(name: &str) -> PathElem {
PathName(token::gensym(name))
let num = token::gensym(name);
// use one colon which will get translated to a period by the mangler, and
// we're guaranteed that `num` is globally unique for this crate.
PathName(token::gensym(format!("{}:{}", name, num)))
}
pub struct tydesc_info {

View file

@ -91,8 +91,47 @@ fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
rest = rest.slice_from(1);
}
let i: uint = from_str(s.slice_to(s.len() - rest.len())).unwrap();
try!(writer.write_str(rest.slice_to(i)));
s = rest.slice_from(i);
rest = rest.slice_to(i);
loop {
if rest.starts_with("$") {
macro_rules! demangle(
($($pat:expr => $demangled:expr),*) => ({
$(if rest.starts_with($pat) {
try!(writer.write_str($demangled));
rest = rest.slice_from($pat.len());
} else)*
{
try!(writer.write_str(rest));
break;
}
})
)
// see src/librustc/back/link.rs for these mappings
demangle! (
"$SP$" => "@",
"$UP$" => "~",
"$RP$" => "*",
"$BP$" => "&",
"$LT$" => "<",
"$GT$" => ">",
"$LP$" => "(",
"$RP$" => ")",
"$C$" => ",",
// in theory we can demangle any unicode code point, but
// for simplicity we just catch the common ones.
"$x20" => " ",
"$x27" => "'",
"$x5b" => "[",
"$x5d" => "]"
)
} else {
try!(writer.write_str(rest));
break;
}
}
}
}
@ -698,17 +737,25 @@ mod test {
use io::MemWriter;
use str;
macro_rules! t( ($a:expr, $b:expr) => ({
let mut m = MemWriter::new();
super::demangle(&mut m, $a).unwrap();
assert_eq!(str::from_utf8_owned(m.unwrap()).unwrap(), $b.to_owned());
}) )
#[test]
fn demangle() {
macro_rules! t( ($a:expr, $b:expr) => ({
let mut m = MemWriter::new();
super::demangle(&mut m, $a);
assert_eq!(str::from_utf8_owned(m.unwrap()).unwrap(), $b.to_owned());
}) )
t!("test", "test");
t!("_ZN4testE", "test");
t!("_ZN4test", "_ZN4test");
t!("_ZN4test1a2bcE", "test::a::bc");
}
#[test]
fn demangle_dollars() {
t!("_ZN4$UP$E", "~");
t!("_ZN8$UP$testE", "~test");
t!("_ZN8$UP$test4foobE", "~test::foob");
t!("_ZN8$x20test4foobE", " test::foob");
}
}