From 3475d3dfe84b4f72a246f0406b2b22cc78245b43 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Tue, 8 Jan 2019 21:05:51 +0000 Subject: [PATCH] [llvm-undname] Add support for demangling msvc's noexcept types. Starting in C++17, MSVC introduced a new mangling for function parameters that are themselves noexcept functions. This patch makes llvm-undname properly demangle them. Patch by Zachary Henkel Differential Revision: https://reviews.llvm.org/D55769 llvm-svn: 350656 --- include/llvm/Demangle/MicrosoftDemangle.h | 2 +- .../llvm/Demangle/MicrosoftDemangleNodes.h | 3 +++ lib/Demangle/MicrosoftDemangle.cpp | 9 ++++--- lib/Demangle/MicrosoftDemangleNodes.cpp | 3 +++ test/Demangle/ms-cxx17-noexcept.test | 25 +++++++++++++++++++ 5 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 test/Demangle/ms-cxx17-noexcept.test diff --git a/include/llvm/Demangle/MicrosoftDemangle.h b/include/llvm/Demangle/MicrosoftDemangle.h index b186758ebe2..97b918fc945 100644 --- a/include/llvm/Demangle/MicrosoftDemangle.h +++ b/include/llvm/Demangle/MicrosoftDemangle.h @@ -245,7 +245,7 @@ private: FuncClass demangleFunctionClass(StringView &MangledName); CallingConv demangleCallingConvention(StringView &MangledName); StorageClass demangleVariableStorageClass(StringView &MangledName); - void demangleThrowSpecification(StringView &MangledName); + bool demangleThrowSpecification(StringView &MangledName); wchar_t demangleWcharLiteral(StringView &MangledName); uint8_t demangleCharLiteral(StringView &MangledName); diff --git a/include/llvm/Demangle/MicrosoftDemangleNodes.h b/include/llvm/Demangle/MicrosoftDemangleNodes.h index e4802ae314d..9e3478e9fd2 100644 --- a/include/llvm/Demangle/MicrosoftDemangleNodes.h +++ b/include/llvm/Demangle/MicrosoftDemangleNodes.h @@ -323,6 +323,9 @@ struct FunctionSignatureNode : public TypeNode { // Function parameters NodeArrayNode *Params = nullptr; + + // True if the function type is noexcept + bool IsNoexcept = false; }; struct IdentifierNode : public Node { diff --git a/lib/Demangle/MicrosoftDemangle.cpp b/lib/Demangle/MicrosoftDemangle.cpp index cca7bf95a7e..51ffa0bff7f 100644 --- a/lib/Demangle/MicrosoftDemangle.cpp +++ b/lib/Demangle/MicrosoftDemangle.cpp @@ -1681,11 +1681,14 @@ TypeNode *Demangler::demangleType(StringView &MangledName, return Ty; } -void Demangler::demangleThrowSpecification(StringView &MangledName) { +bool Demangler::demangleThrowSpecification(StringView &MangledName) { + if (MangledName.consumeFront("_E")) + return true; if (MangledName.consumeFront('Z')) - return; + return false; Error = true; + return false; } FunctionSignatureNode *Demangler::demangleFunctionType(StringView &MangledName, @@ -1709,7 +1712,7 @@ FunctionSignatureNode *Demangler::demangleFunctionType(StringView &MangledName, FTy->Params = demangleFunctionParameterList(MangledName); - demangleThrowSpecification(MangledName); + FTy->IsNoexcept = demangleThrowSpecification(MangledName); return FTy; } diff --git a/lib/Demangle/MicrosoftDemangleNodes.cpp b/lib/Demangle/MicrosoftDemangleNodes.cpp index 49518ef57d6..622f8e75e35 100644 --- a/lib/Demangle/MicrosoftDemangleNodes.cpp +++ b/lib/Demangle/MicrosoftDemangleNodes.cpp @@ -423,6 +423,9 @@ void FunctionSignatureNode::outputPost(OutputStream &OS, if (Quals & Q_Unaligned) OS << " __unaligned"; + if (IsNoexcept) + OS << " noexcept"; + if (RefQualifier == FunctionRefQualifier::Reference) OS << " &"; else if (RefQualifier == FunctionRefQualifier::RValueReference) diff --git a/test/Demangle/ms-cxx17-noexcept.test b/test/Demangle/ms-cxx17-noexcept.test new file mode 100644 index 00000000000..fc60d666d52 --- /dev/null +++ b/test/Demangle/ms-cxx17-noexcept.test @@ -0,0 +1,25 @@ +; RUN: llvm-undname < %s | FileCheck %s + +; CHECK-NOT: Invalid mangled name + +?nochange@@YAXXZ +; CHECK: void __cdecl nochange(void) + +?a@@YAXP6AHXZ@Z +; CHECK: void __cdecl a(int (__cdecl *)(void)) +?a@@YAXP6AHX_E@Z +; CHECK: void __cdecl a(int (__cdecl *)(void) noexcept) + +?b@@YAXP6AHXZ@Z +; CHECK: void __cdecl b(int (__cdecl *)(void)) + +?c@@YAXP6AHXZ@Z +; CHECK: void __cdecl c(int (__cdecl *)(void)) +?c@@YAXP6AHX_E@Z +; CHECK: void __cdecl c(int (__cdecl *)(void) noexcept) + +?ee@?$e@$$A6AXXZ@@EEAAXXZ +; CHECK: private: virtual void __cdecl e::ee(void) + +?ee@?$e@$$A6AXX_E@@EEAAXXZ +; CHECK: private: virtual void __cdecl e::ee(void)