diff options
Diffstat (limited to '3rdParty/Breakpad/src/common/language.cc')
-rw-r--r-- | 3rdParty/Breakpad/src/common/language.cc | 130 |
1 files changed, 122 insertions, 8 deletions
diff --git a/3rdParty/Breakpad/src/common/language.cc b/3rdParty/Breakpad/src/common/language.cc index c2fd81f..978fb85 100644 --- a/3rdParty/Breakpad/src/common/language.cc +++ b/3rdParty/Breakpad/src/common/language.cc @@ -34,18 +34,70 @@ #include "common/language.h" +#include <stdlib.h> + +#if !defined(__ANDROID__) +#include <cxxabi.h> +#endif + +#if defined(HAVE_RUST_DEMANGLE) +#include <rust_demangle.h> +#endif + +#include <limits> + +namespace { + +string MakeQualifiedNameWithSeparator(const string& parent_name, + const char* separator, + const string& name) { + if (parent_name.empty()) { + return name; + } + + return parent_name + separator + name; +} + +} // namespace + namespace google_breakpad { // C++ language-specific operations. class CPPLanguage: public Language { public: CPPLanguage() {} + string MakeQualifiedName(const string &parent_name, const string &name) const { - if (parent_name.empty()) - return name; - else - return parent_name + "::" + name; + return MakeQualifiedNameWithSeparator(parent_name, "::", name); + } + + virtual DemangleResult DemangleName(const string& mangled, + string* demangled) const { +#if defined(__ANDROID__) + // Android NDK doesn't provide abi::__cxa_demangle. + demangled->clear(); + return kDontDemangle; +#else + int status; + char* demangled_c = + abi::__cxa_demangle(mangled.c_str(), NULL, NULL, &status); + + DemangleResult result; + if (status == 0) { + result = kDemangleSuccess; + demangled->assign(demangled_c); + } else { + result = kDemangleFailure; + demangled->clear(); + } + + if (demangled_c) { + free(reinterpret_cast<void*>(demangled_c)); + } + + return result; +#endif } }; @@ -54,19 +106,79 @@ CPPLanguage CPPLanguageSingleton; // Java language-specific operations. class JavaLanguage: public Language { public: + JavaLanguage() {} + string MakeQualifiedName(const string &parent_name, const string &name) const { - if (parent_name.empty()) - return name; - else - return parent_name + "." + name; + return MakeQualifiedNameWithSeparator(parent_name, ".", name); } }; JavaLanguage JavaLanguageSingleton; +// Swift language-specific operations. +class SwiftLanguage: public Language { + public: + SwiftLanguage() {} + + string MakeQualifiedName(const string &parent_name, + const string &name) const { + return MakeQualifiedNameWithSeparator(parent_name, ".", name); + } + + virtual DemangleResult DemangleName(const string& mangled, + string* demangled) const { + // There is no programmatic interface to a Swift demangler. Pass through the + // mangled form because it encodes more information than the qualified name + // that would have been built by MakeQualifiedName(). The output can be + // post-processed by xcrun swift-demangle to transform mangled Swift names + // into something more readable. + demangled->assign(mangled); + return kDemangleSuccess; + } +}; + +SwiftLanguage SwiftLanguageSingleton; + +// Rust language-specific operations. +class RustLanguage: public Language { + public: + RustLanguage() {} + + string MakeQualifiedName(const string &parent_name, + const string &name) const { + return MakeQualifiedNameWithSeparator(parent_name, ".", name); + } + + virtual DemangleResult DemangleName(const string& mangled, + string* demangled) const { + // Rust names use GCC C++ name mangling, but demangling them with + // abi_demangle doesn't produce stellar results due to them having + // another layer of encoding. + // If callers provide rustc-demangle, use that. +#if defined(HAVE_RUST_DEMANGLE) + char* rust_demangled = rust_demangle(mangled.c_str()); + if (rust_demangled == nullptr) { + return kDemangleFailure; + } + demangled->assign(rust_demangled); + free_rust_demangled_name(rust_demangled); +#else + // Otherwise, pass through the mangled name so callers can demangle + // after the fact. + demangled->assign(mangled); +#endif + return kDemangleSuccess; + } +}; + +RustLanguage RustLanguageSingleton; + // Assembler language-specific operations. class AssemblerLanguage: public Language { + public: + AssemblerLanguage() {} + bool HasFunctions() const { return false; } string MakeQualifiedName(const string &parent_name, const string &name) const { @@ -78,6 +190,8 @@ AssemblerLanguage AssemblerLanguageSingleton; const Language * const Language::CPlusPlus = &CPPLanguageSingleton; const Language * const Language::Java = &JavaLanguageSingleton; +const Language * const Language::Swift = &SwiftLanguageSingleton; +const Language * const Language::Rust = &RustLanguageSingleton; const Language * const Language::Assembler = &AssemblerLanguageSingleton; } // namespace google_breakpad |