Skip to content

Commit

Permalink
make the mangling state explicit in the Name constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
Swatinem committed Oct 13, 2020
1 parent 7ee8ea7 commit 33177b0
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 66 deletions.
10 changes: 8 additions & 2 deletions examples/addr2line/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::borrow::Borrow;
use anyhow::{Context, Result};
use clap::{clap_app, ArgMatches};

use symbolic::common::{ByteView, Name};
use symbolic::common::{ByteView, Name, NameMangling};
use symbolic::debuginfo::{Function, Object};
use symbolic::demangle::{Demangle, DemangleOptions};

Expand Down Expand Up @@ -92,7 +92,13 @@ fn execute(matches: &ArgMatches<'_>) -> Result<()> {

if matches.is_present("functions") {
if let Some(symbol) = symbol_map.lookup(addr) {
print_name(symbol.name.as_ref().map(|n| Name::new(n.as_ref())), matches);
print_name(
symbol
.name
.as_ref()
.map(|n| Name::new(n.as_ref(), NameMangling::Unknown)),
matches,
);
print_range(symbol.address, Some(symbol.size), matches);
print!("\n at ");
}
Expand Down
4 changes: 2 additions & 2 deletions symbolic-cabi/src/demangle.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use symbolic::common::Name;
use symbolic::common::{Name, NameMangling};
use symbolic::demangle::{Demangle, DemangleOptions};

use crate::core::SymbolicStr;

/// Creates a name from a string passed via FFI.
unsafe fn get_name(ident: *const SymbolicStr, lang: *const SymbolicStr) -> Name<'static> {
if lang.is_null() {
Name::new((*ident).as_str())
Name::new((*ident).as_str(), NameMangling::Unknown)
} else {
let lang = (*lang).as_str().parse().unwrap_or_default();
Name::with_language((*ident).as_str(), lang)
Expand Down
63 changes: 18 additions & 45 deletions symbolic-common/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,9 +679,9 @@ impl Default for NameMangling {
/// Create a name and print it:
///
/// ```
/// use symbolic_common::Name;
/// use symbolic_common::{Name, NameMangling};
///
/// let name = Name::new("_ZN3foo3barEv");
/// let name = Name::new("_ZN3foo3barEv", NameMangling::Unknown);
/// assert_eq!(name.to_string(), "_ZN3foo3barEv");
/// ```
///
Expand Down Expand Up @@ -717,45 +717,20 @@ impl<'a> Name<'a> {
/// # Example
///
/// ```
/// use symbolic_common::Name;
/// use symbolic_common::{Name, NameMangling};
///
/// let name = Name::new("_ZN3foo3barEv");
/// let name = Name::new("_ZN3foo3barEv", NameMangling::Unknown);
/// assert_eq!(name.to_string(), "_ZN3foo3barEv");
/// ```
#[inline]
pub fn new<S>(string: S) -> Self
pub fn new<S>(string: S, mangling: NameMangling) -> Self
where
S: Into<Cow<'a, str>>,
{
Name {
string: string.into(),
lang: Language::Unknown,
mangling: NameMangling::Unknown,
}
}

/// Constructs a new unmangled Name.
///
/// The language of this name is [`Language::Unknown`],
/// and its mangling state is `NameMangling::Unmangled`.
///
/// # Example
///
/// ```
/// use symbolic_common::Name;
///
/// let name = Name::unmangled("foo::bar");
/// assert_eq!(name.to_string(), "foo::bar");
/// ```
#[inline]
pub fn unmangled<S>(string: S) -> Self
where
S: Into<Cow<'a, str>>,
{
Name {
string: string.into(),
lang: Language::Unknown,
mangling: NameMangling::Unmangled,
mangling,
}
}

Expand Down Expand Up @@ -788,18 +763,18 @@ impl<'a> Name<'a> {
/// # Example
///
/// ```
/// use symbolic_common::Name;
/// use symbolic_common::{Name, NameMangling};
///
/// let name = Name::new("_ZN3foo3barEv");
/// let name = Name::new("_ZN3foo3barEv", NameMangling::Unknown);
/// assert_eq!(name.as_str(), "_ZN3foo3barEv");
/// ```
///
/// This is also available as an `AsRef<str>` implementation:
///
/// ```
/// use symbolic_common::Name;
/// use symbolic_common::{Name, NameMangling};
///
/// let name = Name::new("_ZN3foo3barEv");
/// let name = Name::new("_ZN3foo3barEv", NameMangling::Unknown);
/// assert_eq!(name.as_ref(), "_ZN3foo3barEv");
/// ```
pub fn as_str(&self) -> &str {
Expand All @@ -815,9 +790,9 @@ impl<'a> Name<'a> {
/// # Example
///
/// ```
/// use symbolic_common::{Language, Name};
/// use symbolic_common::{Language, Name, NameMangling};
///
/// let name = Name::new("_ZN3foo3barEv");
/// let name = Name::new("_ZN3foo3barEv", NameMangling::Unknown);
/// assert_eq!(name.language(), Language::Unknown);
/// ```
pub fn language(&self) -> Language {
Expand All @@ -831,10 +806,8 @@ impl<'a> Name<'a> {
/// ```
/// use symbolic_common::{Name, NameMangling};
///
/// let unmangled = Name::unmangled("foo::bar");
/// let unmangled = Name::new("foo::bar", NameMangling::Unmangled);
/// assert_eq!(unmangled.mangling(), NameMangling::Unmangled);
/// let unknown = Name::new("_ZN3foo3barEv");
/// assert_eq!(unknown.mangling(), NameMangling::Unknown);
/// ```
pub fn mangling(&self) -> NameMangling {
self.mangling
Expand All @@ -845,9 +818,9 @@ impl<'a> Name<'a> {
/// # Example
///
/// ```
/// use symbolic_common::Name;
/// use symbolic_common::{Name, NameMangling};
///
/// let name = Name::new("_ZN3foo3barEv");
/// let name = Name::new("_ZN3foo3barEv", NameMangling::Unknown);
/// assert_eq!(name.into_cow(), "_ZN3foo3barEv");
/// ```
pub fn into_cow(self) -> Cow<'a, str> {
Expand All @@ -859,9 +832,9 @@ impl<'a> Name<'a> {
/// # Example
///
/// ```
/// use symbolic_common::Name;
/// use symbolic_common::{Name, NameMangling};
///
/// let name = Name::new("_ZN3foo3barEv");
/// let name = Name::new("_ZN3foo3barEv", NameMangling::Unknown);
/// assert_eq!(name.into_string(), "_ZN3foo3barEv");
/// ```
pub fn into_string(self) -> String {
Expand All @@ -886,7 +859,7 @@ where
S: Into<Cow<'a, str>>,
{
fn from(string: S) -> Self {
Self::new(string)
Self::new(string, NameMangling::Unknown)
}
}

Expand Down
11 changes: 8 additions & 3 deletions symbolic-debuginfo/src/pdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ use pdb::{
use smallvec::SmallVec;
use thiserror::Error;

use symbolic_common::{Arch, AsSelf, CodeId, CpuFamily, DebugId, Name, SelfCell, Uuid};
use symbolic_common::{
Arch, AsSelf, CodeId, CpuFamily, DebugId, Name, NameMangling, SelfCell, Uuid,
};

use crate::base::*;
use crate::private::{FunctionStack, Parse};
Expand Down Expand Up @@ -932,7 +934,7 @@ impl<'s> Unit<'s> {
// Names from the private symbol table are generally demangled. They contain the path of the
// scope and name of the function itself, including type parameters, but do not contain
// parameter lists or return types. This is good enough for us at the moment.
let name = Name::new(proc.name.to_string());
let name = Name::new(proc.name.to_string(), NameMangling::Unmangled);

let line_iter = program.lines_at_offset(proc.offset);
let lines = self.collect_lines(line_iter, program)?;
Expand Down Expand Up @@ -976,7 +978,10 @@ impl<'s> Unit<'s> {
};

let mut formatter = TypeFormatter::new(self);
let name = Name::new(formatter.format_id(inline_site.inlinee)?);
let name = Name::new(
formatter.format_id(inline_site.inlinee)?,
NameMangling::Unmangled,
);

Ok(Some(Function {
address: start,
Expand Down
24 changes: 12 additions & 12 deletions symbolic-demangle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
//!
//! ```rust
//! # #[cfg(feature = "cpp")] {
//! use symbolic_common::{Language, Name};
//! use symbolic_common::{Language, Name, NameMangling};
//! use symbolic_demangle::{Demangle, DemangleOptions};
//!
//! let name = Name::new("__ZN3std2io4Read11read_to_end17hb85a0f6802e14499E");
//! let name = Name::new("__ZN3std2io4Read11read_to_end17hb85a0f6802e14499E", NameMangling::Unknown);
//! assert_eq!(name.detect_language(), Language::Rust);
//! assert_eq!(name.try_demangle(DemangleOptions::complete()), "std::io::Read::read_to_end");
//! # }
Expand Down Expand Up @@ -280,11 +280,11 @@ pub trait Demangle {
/// # Examples
///
/// ```
/// use symbolic_common::{Name, Language};
/// use symbolic_common::{Name, NameMangling, Language};
/// use symbolic_demangle::{Demangle, DemangleOptions};
///
/// assert_eq!(Name::new("_ZN3foo3barEv").detect_language(), Language::Cpp);
/// assert_eq!(Name::new("unknown").detect_language(), Language::Unknown);
/// assert_eq!(Name::new("_ZN3foo3barEv", NameMangling::Unknown).detect_language(), Language::Cpp);
/// assert_eq!(Name::new("unknown", NameMangling::Unknown).detect_language(), Language::Unknown);
/// ```
///
/// [module level documentation]: index.html
Expand All @@ -301,11 +301,11 @@ pub trait Demangle {
///
/// ```
/// # #[cfg(feature = "cpp")] {
/// use symbolic_common::Name;
/// use symbolic_common::{Name, NameMangling};
/// use symbolic_demangle::{Demangle, DemangleOptions};
///
/// assert_eq!(Name::new("_ZN3foo3barEv").demangle(DemangleOptions::name_only()), Some("foo::bar".to_string()));
/// assert_eq!(Name::new("unknown").demangle(DemangleOptions::name_only()), None);
/// assert_eq!(Name::new("_ZN3foo3barEv", NameMangling::Unknown).demangle(DemangleOptions::name_only()), Some("foo::bar".to_string()));
/// assert_eq!(Name::new("unknown", NameMangling::Unknown).demangle(DemangleOptions::name_only()), None);
/// # }
/// ```
fn demangle(&self, opts: DemangleOptions) -> Option<String>;
Expand All @@ -319,11 +319,11 @@ pub trait Demangle {
///
/// ```
/// # #[cfg(feature = "cpp")] {
/// use symbolic_common::Name;
/// use symbolic_common::{Name, NameMangling};
/// use symbolic_demangle::{Demangle, DemangleOptions};
///
/// assert_eq!(Name::new("_ZN3foo3barEv").try_demangle(DemangleOptions::name_only()), "foo::bar");
/// assert_eq!(Name::new("unknown").try_demangle(DemangleOptions::name_only()), "unknown");
/// assert_eq!(Name::new("_ZN3foo3barEv", NameMangling::Unknown).try_demangle(DemangleOptions::name_only()), "foo::bar");
/// assert_eq!(Name::new("unknown", NameMangling::Unknown).try_demangle(DemangleOptions::name_only()), "unknown");
/// # }
/// ```
///
Expand Down Expand Up @@ -398,7 +398,7 @@ impl<'a> Demangle for Name<'a> {
///
/// [`Demangle::try_demangle`]: trait.Demangle.html#tymethod.try_demangle
pub fn demangle(ident: &str) -> Cow<'_, str> {
match Name::new(ident).demangle(DemangleOptions::complete()) {
match Name::new(ident, NameMangling::Unknown).demangle(DemangleOptions::complete()) {
Some(demangled) => Cow::Owned(demangled),
None => Cow::Borrowed(ident),
}
Expand Down
4 changes: 2 additions & 2 deletions symbolic-demangle/tests/test_detection.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//! Language auto-detection tests
use symbolic_common::{Language, Name};
use symbolic_common::{Language, Name, NameMangling};
use symbolic_demangle::Demangle;

fn assert_language(input: &str, lang: Language) {
let name = Name::new(input);
let name = Name::new(input, NameMangling::Unknown);
assert_eq!(name.detect_language(), lang);
}

Expand Down

0 comments on commit 33177b0

Please sign in to comment.