Index: src/common/language.cc |
diff --git a/src/common/language.cc b/src/common/language.cc |
index c2fd81f644c21ced2abbffba67a829b3bf721db5..3a598f6969a56223a0faaa622aa99b94b60cdb19 100644 |
--- a/src/common/language.cc |
+++ b/src/common/language.cc |
@@ -34,18 +34,66 @@ |
#include "common/language.h" |
+#include <stdlib.h> |
+ |
+#if !defined(__ANDROID__) |
+#include <cxxabi.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, |
+ std::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->clear(); |
+ } else { |
+ result = kDemangleFailure; |
+ demangled->assign(demangled_c); |
+ } |
+ |
+ if (demangled_c) { |
+ free(reinterpret_cast<void*>(demangled_c)); |
+ } |
+ |
+ return result; |
+#endif |
} |
}; |
@@ -54,19 +102,45 @@ 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, |
+ std::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; |
+ |
// 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 +152,7 @@ AssemblerLanguage AssemblerLanguageSingleton; |
const Language * const Language::CPlusPlus = &CPPLanguageSingleton; |
const Language * const Language::Java = &JavaLanguageSingleton; |
+const Language * const Language::Swift = &SwiftLanguageSingleton; |
const Language * const Language::Assembler = &AssemblerLanguageSingleton; |
} // namespace google_breakpad |