mod legacy;
mod v0;
#[derive(Clone, Copy, PartialEq)]
pub enum Kind {
Unknown,
Legacy,
V0,
}
pub struct SymbolData {
pub name: SymbolName,
pub address: u64,
pub size: u64,
}
pub struct SymbolName {
pub complete: String,
pub trimmed: String,
pub crate_name: Option<String>,
pub kind: Kind,
}
impl SymbolName {
pub fn demangle(name: &str) -> Self {
let d = demangle(name);
match d.style {
Some(DemangleStyle::Legacy(ref d)) => {
let complete = d.to_string();
let mut trimmed = complete.clone();
if let Some(pos) = trimmed.bytes().rposition(|b| b == b':') {
trimmed.drain((pos - 1)..);
}
SymbolName {
complete,
trimmed,
crate_name: None, kind: Kind::Legacy,
}
}
Some(DemangleStyle::V0(ref d)) => {
d.demangle()
}
None => {
SymbolName {
complete: name.to_string(),
trimmed: name.to_string(),
crate_name: None, kind: Kind::Unknown,
}
}
}
}
}
pub struct Demangle<'a> {
style: Option<DemangleStyle<'a>>,
}
enum DemangleStyle<'a> {
Legacy(legacy::Demangle<'a>),
V0(v0::Demangle<'a>),
}
pub fn demangle(mut s: &str) -> Demangle {
let llvm = ".llvm.";
if let Some(i) = s.find(llvm) {
let candidate = &s[i + llvm.len()..];
let all_hex = candidate.chars().all(|c| {
match c {
'A' ..= 'F' | '0' ..= '9' | '@' => true,
_ => false,
}
});
if all_hex {
s = &s[..i];
}
}
let mut suffix = "";
let mut style = match legacy::demangle(s) {
Ok((d, s)) => {
suffix = s;
Some(DemangleStyle::Legacy(d))
}
Err(()) => match v0::demangle(s) {
Ok((d, s)) => {
suffix = s;
Some(DemangleStyle::V0(d))
}
Err(v0::Invalid) => None,
},
};
if !suffix.is_empty() {
if suffix.starts_with(".") && is_symbol_like(suffix) {
} else {
style = None;
}
}
Demangle { style }
}
fn is_symbol_like(s: &str) -> bool {
s.chars().all(|c| {
is_ascii_alphanumeric(c) || is_ascii_punctuation(c)
})
}
fn is_ascii_alphanumeric(c: char) -> bool {
match c {
'\u{0041}' ..= '\u{005A}' |
'\u{0061}' ..= '\u{007A}' |
'\u{0030}' ..= '\u{0039}' => true,
_ => false,
}
}
fn is_ascii_punctuation(c: char) -> bool {
match c {
'\u{0021}' ..= '\u{002F}' |
'\u{003A}' ..= '\u{0040}' |
'\u{005B}' ..= '\u{0060}' |
'\u{007B}' ..= '\u{007E}' => true,
_ => false,
}
}