ghostscope_dwarf/core/
demangle.rs1use gimli::DwLang;
4
5pub fn demangle_by_lang(lang: Option<DwLang>, s: &str) -> Option<String> {
8 match lang {
9 Some(gimli::DW_LANG_Rust) => demangle_rust(s),
10 Some(gimli::DW_LANG_C_plus_plus)
11 | Some(gimli::DW_LANG_C_plus_plus_11)
12 | Some(gimli::DW_LANG_C_plus_plus_14)
13 | Some(gimli::DW_LANG_C_plus_plus_17)
14 | Some(gimli::DW_LANG_C_plus_plus_20) => demangle_cpp(s),
15 _ => {
16 if is_rust_mangled(s) {
18 demangle_rust(s)
19 } else if is_itanium_cpp_mangled(s) {
20 demangle_cpp(s)
21 } else {
22 None
23 }
24 }
25 }
26}
27
28pub fn demangled_leaf(full: &str) -> String {
31 let trimmed = match full.rfind("::h") {
35 Some(pos) => {
36 let start = pos + 3; if start < full.len() {
38 let suffix = &full[start..];
39 if suffix.len() >= 8 && suffix.chars().all(|c| c.is_ascii_hexdigit()) {
40 &full[..pos]
41 } else {
42 full
43 }
44 } else {
45 full
46 }
47 }
48 None => full,
49 };
50 trimmed.rsplit("::").next().unwrap_or(trimmed).to_string()
52}
53
54pub fn is_rust_mangled(s: &str) -> bool {
56 s.starts_with("_R")
57}
58
59pub fn is_itanium_cpp_mangled(s: &str) -> bool {
61 s.starts_with("_Z")
62}
63
64fn demangle_rust(s: &str) -> Option<String> {
65 match rustc_demangle::try_demangle(s) {
66 Ok(sym) => Some(sym.to_string()),
67 Err(_) => None,
68 }
69}
70
71fn demangle_cpp(s: &str) -> Option<String> {
72 match cpp_demangle::Symbol::new(s) {
73 Ok(sym) => Some(sym.to_string()),
74 Err(_) => None,
75 }
76}