}
// Returns the demangled C++ symbol name for Name.
-std::string elf::demangle(StringRef Name) {
+Optional<std::string> elf::demangle(StringRef Name) {
// __cxa_demangle can be used to demangle strings other than symbol
// names which do not necessarily start with "_Z". Name can be
// either a C or C++ symbol. Don't call __cxa_demangle if the name
// does not look like a C++ symbol name to avoid getting unexpected
// result for a C symbol that happens to match a mangled type name.
if (!Name.startswith("_Z"))
- return Name;
+ return None;
char *Buf = itaniumDemangle(Name.str().c_str(), nullptr, nullptr, nullptr);
if (!Buf)
- return Name;
+ return None;
std::string S(Buf);
free(Buf);
return S;
};
// Returns a demangled C++ symbol name. If Name is not a mangled
-// name or the system does not provide __cxa_demangle function,
-// it returns an unmodified string.
-std::string demangle(StringRef Name);
+// name, it returns Optional::None.
+llvm::Optional<std::string> demangle(StringRef Name);
inline StringRef toStringRef(ArrayRef<uint8_t> Arr) {
return {(const char *)Arr.data(), Arr.size()};
for (Symbol *Sym : SymVector) {
SymbolBody *B = Sym->body();
- (*DemangledSyms)[demangle(B->getName())].push_back(B);
+ if (Optional<std::string> S = demangle(B->getName()))
+ (*DemangledSyms)[*S].push_back(B);
+ else
+ (*DemangledSyms)[B->getName()].push_back(B);
}
}
// Returns a symbol for an error message.
std::string elf::toString(const SymbolBody &B) {
if (Config->Demangle)
- return demangle(B.getName());
+ if (Optional<std::string> S = demangle(B.getName()))
+ return *S;
return B.getName();
}