Skip to content

Commit

Permalink
Support multiple clone suffixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-auer committed Apr 15, 2020
1 parent af7465f commit d6225c6
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 27 deletions.
1 change: 1 addition & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ use std::fmt::Write;
s.extend(149..154);
s.extend(158..168);
s.extend(169..175);
s.extend(175..177);
s.extend(177..180);
s.extend(181..183);
s.extend(184..186);
Expand Down
58 changes: 31 additions & 27 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,7 @@ macro_rules! define_vocabulary {
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum MangledName {
/// The encoding of the mangled symbol name.
Encoding(Encoding, Option<CloneSuffix>),
Encoding(Encoding, Vec<CloneSuffix>),

/// A top-level type. Technically not allowed by the standard, however in
/// practice this can happen, and is tested for by libiberty.
Expand All @@ -1325,12 +1325,8 @@ impl Parse for MangledName {

if let Ok(tail) = consume(b"_Z", input).or_else(|_| consume(b"__Z", input)) {
let (encoding, tail) = Encoding::parse(ctx, subs, tail)?;
if let Ok((clone_suffix, tail)) = CloneSuffix::parse(ctx, subs, tail) {
return Ok((MangledName::Encoding(encoding, Some(clone_suffix)), tail));
}
else {
return Ok((MangledName::Encoding(encoding, None), tail));
}
let (clone_suffixes, tail) = zero_or_more(ctx, subs, tail)?;
return Ok((MangledName::Encoding(encoding, clone_suffixes), tail));
}

if let Ok(tail) = consume(b"_GLOBAL_", input) {
Expand Down Expand Up @@ -1359,8 +1355,10 @@ where
match *self {
MangledName::Encoding(ref enc, ref cs) => {
enc.demangle(ctx, scope)?;
if let Some(clone_suffix) = cs {
clone_suffix.demangle(ctx, scope)?;
if !cs.is_empty() {
for clone_suffix in cs {
clone_suffix.demangle(ctx, scope)?;
}
}
Ok(())
},
Expand Down Expand Up @@ -1514,7 +1512,7 @@ where
/// <clone-suffix> ::= [ . <clone-type-identifier> ] [ . <nonnegative number> ]*

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CloneSuffix(CloneTypeIdentifier, isize);
pub struct CloneSuffix(CloneTypeIdentifier, Vec<isize>);

impl Parse for CloneSuffix {
fn parse<'a, 'b>(
Expand All @@ -1525,16 +1523,18 @@ impl Parse for CloneSuffix {
try_begin_parse!("CloneSuffix", ctx, input);

let tail = consume(b".", input)?;
let (identifier, tail) = CloneTypeIdentifier::parse(ctx, subs, tail)?;
let (identifier, mut tail) = CloneTypeIdentifier::parse(ctx, subs, tail)?;
if tail.is_empty() {
return Err(error::Error::UnexpectedText);
}

let tail = consume(b".", tail)?;

let (nonnegative, tail) = parse_number(10, false, tail)?;
let mut numbers = Vec::with_capacity(1);
while let Ok((n, t)) = consume(b".", tail).and_then(|t| parse_number(10, false, t)) {
numbers.push(n);
tail = t;
}

let clone_suffix = CloneSuffix(identifier, nonnegative);
let clone_suffix = CloneSuffix(identifier, numbers);
Ok((clone_suffix, tail))
}
}
Expand All @@ -1549,8 +1549,12 @@ where
scope: Option<ArgScopeStack<'prev, 'subs>>,
) -> fmt::Result {
let ctx = try_begin_demangle!(self, ctx, scope);
write!(ctx, " [clone")?;
self.0.demangle(ctx, scope)?;
write!(ctx, ".{}]", self.1)?;
for nonnegative in &self.1 {
write!(ctx, ".{}", nonnegative)?;
}
write!(ctx, "]")?;
Ok(())
}
}
Expand Down Expand Up @@ -2799,7 +2803,7 @@ where

let source_name = String::from_utf8_lossy(ident);
ctx.set_source_name(self.start, self.end);
write!(ctx, " [clone .{}", source_name)?;
write!(ctx, " .{}", source_name)?;
Ok(())
}
}
Expand Down Expand Up @@ -7791,7 +7795,7 @@ mod tests {
SourceName(Identifier {
start: 3,
end: 6,
}))))), None),
}))))), Vec::new()),
b"..."
}
b"_GLOBAL__I__Z3foo..." => {
Expand All @@ -7807,7 +7811,7 @@ mod tests {
Identifier {
start: 14,
end: 17,
}))))), None)))),
}))))), Vec::new())))),
b"..."
}
}
Expand Down Expand Up @@ -7891,7 +7895,7 @@ mod tests {
Identifier {
start: 6,
end: 9,
}))))), None))),
}))))), Vec::new()))),
b"..."
}
b".I__Z3foo..." => {
Expand All @@ -7906,7 +7910,7 @@ mod tests {
Identifier {
start: 6,
end: 9,
}))))), None))),
}))))), Vec::new()))),
b"..."
}
b"$I__Z3foo..." => {
Expand All @@ -7921,7 +7925,7 @@ mod tests {
Identifier {
start: 6,
end: 9,
}))))), None))),
}))))), Vec::new()))),
b"..."
}
b"_D__Z3foo..." => {
Expand All @@ -7936,7 +7940,7 @@ mod tests {
Identifier {
start: 6,
end: 9,
}))))), None))),
}))))), Vec::new()))),
b"..."
}
b".D__Z3foo..." => {
Expand All @@ -7951,7 +7955,7 @@ mod tests {
Identifier {
start: 6,
end: 9,
}))))), None))),
}))))), Vec::new()))),
b"..."
}
b"$D__Z3foo..." => {
Expand All @@ -7966,7 +7970,7 @@ mod tests {
Identifier {
start: 6,
end: 9,
}))))), None))),
}))))), Vec::new()))),
b"..."
}
}
Expand Down Expand Up @@ -9597,7 +9601,7 @@ mod tests {
SourceName(Identifier {
start: 4,
end: 7,
}))))), None))),
}))))), Vec::new()))),
b"...",
[]
}
Expand Down Expand Up @@ -9979,7 +9983,7 @@ mod tests {
SourceName(Identifier {
start: 4,
end: 7,
}))))), None)),
}))))), Vec::new())),
b"...",
[]
}
Expand Down
11 changes: 11 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,17 @@ demangles!(
"_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag.isra.90",
"void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) [clone .isra.90]"
);
demangles!(
multiple_clone_suffixes,
"_ZN15google_breakpad17ProcCpuInfoReader14GetValueAndLenEPm.isra.20.part.21",
"google_breakpad::ProcCpuInfoReader::GetValueAndLen(unsigned long*) [clone .isra.20] [clone .part.21]"
);
// Taken from https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40831
demangles!(
multiple_clone_numbers,
"_Z3fooi.part.9.165493.constprop.775.31805",
"foo(int) [clone .part.9.165493] [clone .constprop.775.31805]"
);
demangles!(
_Z1fDpDv1_c,
"f(char __vector(1)...)"
Expand Down

0 comments on commit d6225c6

Please sign in to comment.