diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
| commit | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (patch) | |
| tree | f42add1021b9f2ac6a69ac7cf6c4499962739a45 /llvm/lib/Demangle/Demangle.cpp | |
| parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) | |
Diffstat (limited to 'llvm/lib/Demangle/Demangle.cpp')
| -rw-r--r-- | llvm/lib/Demangle/Demangle.cpp | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/llvm/lib/Demangle/Demangle.cpp b/llvm/lib/Demangle/Demangle.cpp index 1851fb77b09e..13aa2864c183 100644 --- a/llvm/lib/Demangle/Demangle.cpp +++ b/llvm/lib/Demangle/Demangle.cpp @@ -12,32 +12,53 @@ #include "llvm/Demangle/Demangle.h" #include <cstdlib> +#include <cstring> -static bool isItaniumEncoding(const std::string &MangledName) { - size_t Pos = MangledName.find_first_not_of('_'); - // A valid Itanium encoding requires 1-4 leading underscores, followed by 'Z'. - return Pos > 0 && Pos <= 4 && MangledName[Pos] == 'Z'; +static bool isItaniumEncoding(const char *S) { + // Itanium encoding requires 1 or 3 leading underscores, followed by 'Z'. + return std::strncmp(S, "_Z", 2) == 0 || std::strncmp(S, "___Z", 4) == 0; } -static bool isRustEncoding(const std::string &MangledName) { +static bool isRustEncoding(const char *S) { return S[0] == '_' && S[1] == 'R'; } + +static bool isDLangEncoding(const std::string &MangledName) { return MangledName.size() >= 2 && MangledName[0] == '_' && - MangledName[1] == 'R'; + MangledName[1] == 'D'; } std::string llvm::demangle(const std::string &MangledName) { - char *Demangled; + std::string Result; + const char *S = MangledName.c_str(); + + if (nonMicrosoftDemangle(S, Result)) + return Result; + + if (S[0] == '_' && nonMicrosoftDemangle(S + 1, Result)) + return Result; + + if (char *Demangled = + microsoftDemangle(S, nullptr, nullptr, nullptr, nullptr)) { + Result = Demangled; + std::free(Demangled); + return Result; + } + + return MangledName; +} + +bool llvm::nonMicrosoftDemangle(const char *MangledName, std::string &Result) { + char *Demangled = nullptr; if (isItaniumEncoding(MangledName)) - Demangled = itaniumDemangle(MangledName.c_str(), nullptr, nullptr, nullptr); + Demangled = itaniumDemangle(MangledName, nullptr, nullptr, nullptr); else if (isRustEncoding(MangledName)) - Demangled = rustDemangle(MangledName.c_str(), nullptr, nullptr, nullptr); - else - Demangled = microsoftDemangle(MangledName.c_str(), nullptr, nullptr, - nullptr, nullptr); + Demangled = rustDemangle(MangledName, nullptr, nullptr, nullptr); + else if (isDLangEncoding(MangledName)) + Demangled = dlangDemangle(MangledName); if (!Demangled) - return MangledName; + return false; - std::string Ret = Demangled; + Result = Demangled; std::free(Demangled); - return Ret; + return true; } |
