objdiff_core/diff/
demangler.rs1use alloc::string::String;
2
3use crate::diff::Demangler;
4
5#[cfg(feature = "demangler")]
6impl Demangler {
7 pub fn demangle(&self, name: &str) -> Option<String> {
8 match self {
9 Demangler::None => None,
10 Demangler::Codewarrior => Self::demangle_codewarrior(name),
11 Demangler::Msvc => Self::demangle_msvc(name),
12 Demangler::Itanium => Self::demangle_itanium(name),
13 Demangler::GnuLegacy => Self::demangle_gnu_legacy(name),
14 Demangler::Auto => {
15 if name.starts_with('?') {
17 Self::demangle_msvc(name)
18 } else {
19 Self::demangle_codewarrior(name)
20 .or_else(|| Self::demangle_gnu_legacy(name))
21 .or_else(|| Self::demangle_itanium(name))
22 }
23 }
24 }
25 }
26
27 fn demangle_codewarrior(name: &str) -> Option<String> {
28 cwdemangle::demangle(name, &cwdemangle::DemangleOptions::default())
29 }
30
31 fn demangle_msvc(name: &str) -> Option<String> {
32 msvc_demangler::demangle(name, msvc_demangler::DemangleFlags::llvm()).ok()
33 }
34
35 fn demangle_itanium(name: &str) -> Option<String> {
36 let name = name.trim_start_matches('.');
37 cpp_demangle::Symbol::new(name).ok().and_then(|s| s.demangle().ok())
38 }
39
40 fn demangle_gnu_legacy(name: &str) -> Option<String> {
41 let name = name.trim_start_matches('.');
42 gnuv2_demangle::demangle(name, &gnuv2_demangle::DemangleConfig::new()).ok()
43 }
44}
45
46#[cfg(not(feature = "demangler"))]
47impl Demangler {
48 pub fn demangle(&self, _name: &str) -> Option<String> { None }
49}