aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Demangle/MicrosoftDemangle.cpp
diff options
context:
space:
mode:
authorMax Winkler <max.enrico.winkler@gmail.com>2024-06-26 22:24:28 -0700
committerGitHub <noreply@github.com>2024-06-26 22:24:28 -0700
commitef067cf4b6d46cd48d2ed5cfe2300fe83b6bcc8a (patch)
treed820c87613bb54f1571e4e272a0fabd15895bafb /llvm/lib/Demangle/MicrosoftDemangle.cpp
parent0f8849349ae3d3f2f537ad6ab233a586fb39d375 (diff)
downloadllvm-ef067cf4b6d46cd48d2ed5cfe2300fe83b6bcc8a.zip
llvm-ef067cf4b6d46cd48d2ed5cfe2300fe83b6bcc8a.tar.gz
llvm-ef067cf4b6d46cd48d2ed5cfe2300fe83b6bcc8a.tar.bz2
Fix MSVC Demangling with auto NTTP mangled names for function pointer, pointer to data and integral types (#96590)
As cited here, https://github.com/llvm/llvm-project/pull/92477, undname needs updating to support the new auto NTTP name mangling. In short the deduced type of the auto NTTP parameter is mangled as `$M <type> <nttp-param>`. However the deduced type is not printed for the undecorated name so the `$M <type>` is parsed but simply ignored when stringifying the generated AST.
Diffstat (limited to 'llvm/lib/Demangle/MicrosoftDemangle.cpp')
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangle.cpp38
1 files changed, 32 insertions, 6 deletions
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index cd7ff40..e18de9a 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -53,6 +53,18 @@ static bool consumeFront(std::string_view &S, std::string_view C) {
return true;
}
+static bool consumeFront(std::string_view &S, std::string_view PrefixA,
+ std::string_view PrefixB, bool A) {
+ const std::string_view &Prefix = A ? PrefixA : PrefixB;
+ return consumeFront(S, Prefix);
+}
+
+static bool startsWith(std::string_view S, std::string_view PrefixA,
+ std::string_view PrefixB, bool A) {
+ const std::string_view &Prefix = A ? PrefixA : PrefixB;
+ return llvm::itanium_demangle::starts_with(S, Prefix);
+}
+
static bool isMemberPointer(std::string_view MangledName, bool &Error) {
Error = false;
const char F = MangledName.front();
@@ -2256,6 +2268,18 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
NodeList &TP = **Current;
+ // <auto-nttp> ::= $ M <type> <nttp>
+ const bool IsAutoNTTP = consumeFront(MangledName, "$M");
+ if (IsAutoNTTP) {
+ // The deduced type of the auto NTTP parameter isn't printed so
+ // we want to ignore the AST created from demangling the type.
+ //
+ // TODO: Avoid the extra allocations to the bump allocator in this case.
+ (void)demangleType(MangledName, QualifierMangleMode::Drop);
+ if (Error)
+ return nullptr;
+ }
+
TemplateParameterReferenceNode *TPRN = nullptr;
if (consumeFront(MangledName, "$$Y")) {
// Template alias
@@ -2266,15 +2290,17 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
} else if (consumeFront(MangledName, "$$C")) {
// Type has qualifiers.
TP.N = demangleType(MangledName, QualifierMangleMode::Mangle);
- } else if (llvm::itanium_demangle::starts_with(MangledName, "$1") ||
- llvm::itanium_demangle::starts_with(MangledName, "$H") ||
- llvm::itanium_demangle::starts_with(MangledName, "$I") ||
- llvm::itanium_demangle::starts_with(MangledName, "$J")) {
+ } else if (startsWith(MangledName, "$1", "1", !IsAutoNTTP) ||
+ startsWith(MangledName, "$H", "H", !IsAutoNTTP) ||
+ startsWith(MangledName, "$I", "I", !IsAutoNTTP) ||
+ startsWith(MangledName, "$J", "J", !IsAutoNTTP)) {
// Pointer to member
TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
TPRN->IsMemberPointer = true;
- MangledName.remove_prefix(1);
+ if (!IsAutoNTTP)
+ MangledName.remove_prefix(1); // Remove leading '$'
+
// 1 - single inheritance <name>
// H - multiple inheritance <name> <number>
// I - virtual inheritance <name> <number> <number>
@@ -2342,7 +2368,7 @@ Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
}
TPRN->IsMemberPointer = true;
- } else if (consumeFront(MangledName, "$0")) {
+ } else if (consumeFront(MangledName, "$0", "0", !IsAutoNTTP)) {
// Integral non-type template parameter
bool IsNegative = false;
uint64_t Value = 0;