// Parser entry point.
SymbolNode *Demangler::parse(StringView &MangledName) {
- // We can't demangle MD5 names, just output them as-is.
- // Also, MSVC-style mangled symbols must start with '?'.
if (MangledName.startsWith("??@")) {
// This is an MD5 mangled name. We can't demangle it, just return the
// mangled name.
+ // An MD5 mangled name is ??@ followed by 32 characters and a terminating @.
+ size_t MD5Last = MangledName.find('@', strlen("??@"));
+ if (MD5Last == StringView::npos) {
+ Error = true;
+ return nullptr;
+ }
+ const char* Start = MangledName.begin();
+ MangledName = MangledName.dropFront(MD5Last + 1);
+
+ // There are two additional special cases for MD5 names:
+ // 1. For complete object locators where the object name is long enough
+ // for the object to have an MD5 name, the complete object locator is
+ // called ??@...@??_R4@ (with a trailing "??_R4@" instead of the usual
+ // leading "??_R4". This is handled here.
+ // 2. For catchable types, in versions of MSVC before 2015 (<1900) or after
+ // 2017.2 (>= 1914), the catchable type mangling is _CT??@...@??@...@8
+ // instead of_CT??@...@8 with just one MD5 name. Since we don't yet
+ // demangle catchable types anywhere, this isn't handled for MD5 names
+ // either.
+ MangledName.consumeFront("??_R4@");
+
+ StringView MD5(Start, MangledName.begin());
SymbolNode *S = Arena.alloc<SymbolNode>(NodeKind::Md5Symbol);
- S->Name = synthesizeQualifiedName(Arena, MangledName);
+ S->Name = synthesizeQualifiedName(Arena, MD5);
+
return S;
}
+ // MSVC-style mangled symbols must start with '?'.
if (!MangledName.startsWith('?')) {
Error = true;
return nullptr;
-; These tests are based on clang/test/CodeGenCXX/mangle-ms-cxx11.cpp
+; These tests are based on clang/test/CodeGenCXX/mangle-ms-md5.cpp
; RUN: llvm-undname < %s | FileCheck %s
; two check lines here since the tool echos the input.
??@a6a285da2eea70dba6b578022be61d81@
; CHECK: ??@a6a285da2eea70dba6b578022be61d81@
-; CHECK-NEXT: ??@a6a285da2eea70dba6b578022be61d81@
\ No newline at end of file
+; CHECK-NEXT: ??@a6a285da2eea70dba6b578022be61d81@
+
+; Don't include trailing garbage:
+??@a6a285da2eea70dba6b578022be61d81@asdf
+; CHECK: ??@a6a285da2eea70dba6b578022be61d81@asdf
+; CHECK-NEXT: ??@a6a285da2eea70dba6b578022be61d81@
+
+; The complete object locator special case:
+; FIXME: This should probably print
+; ??@a6a285da2eea70dba6b578022be61d81@::`RTTI Complete Object Locator' instead.
+??@a6a285da2eea70dba6b578022be61d81@??_R4@
+; CHECK: ??@a6a285da2eea70dba6b578022be61d81@??_R4@
+; CHECK-NEXT: ??@a6a285da2eea70dba6b578022be61d81@??_R4@