Skip to content

Commit 339f816

Browse files
committed
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.
2 parents a1c7ebe + a07149b commit 339f816

File tree

2 files changed

+60
-8
lines changed

2 files changed

+60
-8
lines changed

src/librustc/middle/trans/common.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,13 @@ pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
103103
ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx, ty)
104104
}
105105

106+
/// Generates a unique symbol based off the name given. This is used to create
107+
/// unique symbols for things like closures.
106108
pub fn gensym_name(name: &str) -> PathElem {
107-
PathName(token::gensym(name))
109+
let num = token::gensym(name);
110+
// use one colon which will get translated to a period by the mangler, and
111+
// we're guaranteed that `num` is globally unique for this crate.
112+
PathName(token::gensym(format!("{}:{}", name, num)))
108113
}
109114

110115
pub struct tydesc_info {

src/libstd/rt/backtrace.rs

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,47 @@ fn demangle(writer: &mut Writer, s: &str) -> IoResult<()> {
9191
rest = rest.slice_from(1);
9292
}
9393
let i: uint = from_str(s.slice_to(s.len() - rest.len())).unwrap();
94-
try!(writer.write_str(rest.slice_to(i)));
9594
s = rest.slice_from(i);
95+
rest = rest.slice_to(i);
96+
loop {
97+
if rest.starts_with("$") {
98+
macro_rules! demangle(
99+
($($pat:expr => $demangled:expr),*) => ({
100+
$(if rest.starts_with($pat) {
101+
try!(writer.write_str($demangled));
102+
rest = rest.slice_from($pat.len());
103+
} else)*
104+
{
105+
try!(writer.write_str(rest));
106+
break;
107+
}
108+
109+
})
110+
)
111+
// see src/librustc/back/link.rs for these mappings
112+
demangle! (
113+
"$SP$" => "@",
114+
"$UP$" => "~",
115+
"$RP$" => "*",
116+
"$BP$" => "&",
117+
"$LT$" => "<",
118+
"$GT$" => ">",
119+
"$LP$" => "(",
120+
"$RP$" => ")",
121+
"$C$" => ",",
122+
123+
// in theory we can demangle any unicode code point, but
124+
// for simplicity we just catch the common ones.
125+
"$x20" => " ",
126+
"$x27" => "'",
127+
"$x5b" => "[",
128+
"$x5d" => "]"
129+
)
130+
} else {
131+
try!(writer.write_str(rest));
132+
break;
133+
}
134+
}
96135
}
97136
}
98137

@@ -698,17 +737,25 @@ mod test {
698737
use io::MemWriter;
699738
use str;
700739

740+
macro_rules! t( ($a:expr, $b:expr) => ({
741+
let mut m = MemWriter::new();
742+
super::demangle(&mut m, $a).unwrap();
743+
assert_eq!(str::from_utf8_owned(m.unwrap()).unwrap(), $b.to_owned());
744+
}) )
745+
701746
#[test]
702747
fn demangle() {
703-
macro_rules! t( ($a:expr, $b:expr) => ({
704-
let mut m = MemWriter::new();
705-
super::demangle(&mut m, $a);
706-
assert_eq!(str::from_utf8_owned(m.unwrap()).unwrap(), $b.to_owned());
707-
}) )
708-
709748
t!("test", "test");
710749
t!("_ZN4testE", "test");
711750
t!("_ZN4test", "_ZN4test");
712751
t!("_ZN4test1a2bcE", "test::a::bc");
713752
}
753+
754+
#[test]
755+
fn demangle_dollars() {
756+
t!("_ZN4$UP$E", "~");
757+
t!("_ZN8$UP$testE", "~test");
758+
t!("_ZN8$UP$test4foobE", "~test::foob");
759+
t!("_ZN8$x20test4foobE", " test::foob");
760+
}
714761
}

0 commit comments

Comments
 (0)