[llvm] r340896 - Add support for various C++14 demanglings.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 28 21:12:44 PDT 2018
Author: zturner
Date: Tue Aug 28 21:12:44 2018
New Revision: 340896
URL: http://llvm.org/viewvc/llvm-project?rev=340896&view=rev
Log:
Add support for various C++14 demanglings.
Mostly this includes <auto> and <decltype-auto> return values.
Additionally, this fixes a fairly obscure back-referencing bug
that was encountered in one of the C++14 tests, which is that
if you have something like Foo<&bar, &bar> then the `bar`
forms a backreference.
Added:
llvm/trunk/test/Demangle/ms-cxx14.test
Modified:
llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp
llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.cpp
llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.h
Modified: llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp?rev=340896&r1=340895&r2=340896&view=diff
==============================================================================
--- llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp (original)
+++ llvm/trunk/lib/Demangle/MicrosoftDemangle.cpp Tue Aug 28 21:12:44 2018
@@ -191,6 +191,8 @@ static bool isTagType(StringView S) {
return false;
}
+static bool isCustomType(StringView S) { return S[0] == '?'; }
+
static bool isPointerType(StringView S) {
if (S.startsWith("$$Q")) // foo &&
return true;
@@ -288,6 +290,7 @@ private:
// Parser functions. This is a recursive-descent parser.
TypeNode *demangleType(StringView &MangledName, QualifierMangleMode QMM);
PrimitiveTypeNode *demanglePrimitiveType(StringView &MangledName);
+ CustomTypeNode *demangleCustomType(StringView &MangledName);
TagTypeNode *demangleClassType(StringView &MangledName);
PointerTypeNode *demanglePointerType(StringView &MangledName);
PointerTypeNode *demangleMemberPointerType(StringView &MangledName);
@@ -304,6 +307,7 @@ private:
int64_t demangleSigned(StringView &MangledName);
void memorizeString(StringView s);
+ void memorizeIdentifier(IdentifierNode *Identifier);
/// Allocate a copy of \p Borrowed into memory that we own.
StringView copyString(StringView Borrowed);
@@ -972,6 +976,19 @@ NamedIdentifierNode *Demangler::demangle
return Backrefs.Names[I];
}
+void Demangler::memorizeIdentifier(IdentifierNode *Identifier) {
+ // Render this class template name into a string buffer so that we can
+ // memorize it for the purpose of back-referencing.
+ OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
+ Identifier->output(OS, OF_Default);
+ OS << '\0';
+ char *Name = OS.getBuffer();
+
+ StringView Owned = copyString(Name);
+ memorizeString(Owned);
+ std::free(Name);
+}
+
IdentifierNode *
Demangler::demangleTemplateInstantiationName(StringView &MangledName,
NameBackrefBehavior NBB) {
@@ -990,18 +1007,8 @@ Demangler::demangleTemplateInstantiation
if (Error)
return nullptr;
- if (NBB & NBB_Template) {
- // Render this class template name into a string buffer so that we can
- // memorize it for the purpose of back-referencing.
- OutputStream OS = OutputStream::create(nullptr, nullptr, 1024);
- Identifier->output(OS, OF_Default);
- OS << '\0';
- char *Name = OS.getBuffer();
-
- StringView Owned = copyString(Name);
- memorizeString(Owned);
- std::free(Name);
- }
+ if (NBB & NBB_Template)
+ memorizeIdentifier(Identifier);
return Identifier;
}
@@ -1749,6 +1756,8 @@ TypeNode *Demangler::demangleType(String
MangledName.consumeFront("$$A6");
Ty = demangleFunctionType(MangledName, false);
}
+ } else if (isCustomType(MangledName)) {
+ Ty = demangleCustomType(MangledName);
} else {
Ty = demanglePrimitiveType(MangledName);
assert(Ty && !Error);
@@ -1837,6 +1846,19 @@ Demangler::demangleFunctionEncoding(Stri
return Symbol;
}
+CustomTypeNode *Demangler::demangleCustomType(StringView &MangledName) {
+ assert(MangledName.startsWith('?'));
+ MangledName.popFront();
+
+ CustomTypeNode *CTN = Arena.alloc<CustomTypeNode>();
+ CTN->Identifier = demangleUnqualifiedTypeName(MangledName, true);
+ if (!MangledName.consumeFront('@'))
+ Error = true;
+ if (Error)
+ return nullptr;
+ return CTN;
+}
+
// Reads a primitive type.
PrimitiveTypeNode *Demangler::demanglePrimitiveType(StringView &MangledName) {
if (MangledName.consumeFront("$$T"))
@@ -2131,8 +2153,12 @@ Demangler::demangleTemplateParameterList
// I - virtual inheritance <name> <number> <number> <number>
// J - unspecified inheritance <name> <number> <number> <number>
char InheritanceSpecifier = MangledName.popFront();
- SymbolNode *S =
- MangledName.startsWith('?') ? parse(MangledName) : nullptr;
+ SymbolNode *S = nullptr;
+ if (MangledName.startsWith('?')) {
+ S = parse(MangledName);
+ memorizeIdentifier(S->Name->getUnqualifiedIdentifier());
+ }
+
switch (InheritanceSpecifier) {
case 'J':
TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
Modified: llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.cpp?rev=340896&r1=340895&r2=340896&view=diff
==============================================================================
--- llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.cpp (original)
+++ llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.cpp Tue Aug 28 21:12:44 2018
@@ -565,9 +565,10 @@ void VariableSymbolNode::output(OutputSt
Type->outputPost(OS, Flags);
}
-void CustomNode::output(OutputStream &OS, OutputFlags Flags) const {
- OS << Name;
+void CustomTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
+ Identifier->output(OS, Flags);
}
+void CustomTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {}
void QualifiedNameNode::output(OutputStream &OS, OutputFlags Flags) const {
Components->output(OS, Flags, "::");
Modified: llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.h?rev=340896&r1=340895&r2=340896&view=diff
==============================================================================
--- llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.h (original)
+++ llvm/trunk/lib/Demangle/MicrosoftDemangleNodes.h Tue Aug 28 21:12:44 2018
@@ -148,7 +148,10 @@ enum class CallingConv : uint8_t {
enum class ReferenceKind : uint8_t { None, LValueRef, RValueRef };
-enum OutputFlags { OF_Default = 0, OF_NoCallingConvention = 1 };
+enum OutputFlags {
+ OF_Default = 0,
+ OF_NoCallingConvention = 1,
+};
// Types
enum class PrimitiveKind {
@@ -392,8 +395,8 @@ struct FunctionSignatureNode : public Ty
explicit FunctionSignatureNode(NodeKind K) : TypeNode(K) {}
FunctionSignatureNode() : TypeNode(NodeKind::FunctionSignature) {}
- virtual void outputPre(OutputStream &OS, OutputFlags Flags) const;
- virtual void outputPost(OutputStream &OS, OutputFlags Flags) const;
+ void outputPre(OutputStream &OS, OutputFlags Flags) const override;
+ void outputPost(OutputStream &OS, OutputFlags Flags) const override;
// Valid if this FunctionTypeNode is the Pointee of a PointerType or
// MemberPointerType.
@@ -566,13 +569,13 @@ struct IntrinsicNode : public TypeNode {
void output(OutputStream &OS, OutputFlags Flags) const override {}
};
-struct CustomNode : public Node {
- CustomNode() : Node(NodeKind::Custom) {}
+struct CustomTypeNode : public TypeNode {
+ CustomTypeNode() : TypeNode(NodeKind::Custom) {}
- void output(OutputStream &OS, OutputFlags Flags) const override;
+ void outputPre(OutputStream &OS, OutputFlags Flags) const override;
+ void outputPost(OutputStream &OS, OutputFlags Flags) const override;
- // The string to print.
- StringView Name;
+ IdentifierNode *Identifier;
};
struct NodeArrayNode : public Node {
Added: llvm/trunk/test/Demangle/ms-cxx14.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Demangle/ms-cxx14.test?rev=340896&view=auto
==============================================================================
--- llvm/trunk/test/Demangle/ms-cxx14.test (added)
+++ llvm/trunk/test/Demangle/ms-cxx14.test Tue Aug 28 21:12:44 2018
@@ -0,0 +1,37 @@
+; These tests are based on clang/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
+; RUN: llvm-undname < %s | FileCheck %s
+
+; CHECK-NOT: Invalid mangled name
+
+??$x at X@@3HA
+; CHECK: int x<void>
+
+?FunctionWithLocalType@@YA?A?<auto>@@XZ
+; CHECK: <auto> __cdecl FunctionWithLocalType(void)
+
+?ValueFromFunctionWithLocalType@@3ULocalType@?1??FunctionWithLocalType@@YA?A?<auto>@@XZ at A
+; CHECK: struct `<auto> __cdecl FunctionWithLocalType(void)'::`2'::LocalType ValueFromFunctionWithLocalType
+
+??R<lambda_0>@@QBE?A?<auto>@@XZ
+; CHECK: <auto> __thiscall <lambda_0>::operator()(void) const
+
+?ValueFromLambdaWithLocalType@@3ULocalType@?1???R<lambda_0>@@QBE?A?<auto>@@XZ at A
+; CHECK: struct `<auto> __thiscall <lambda_0>::operator()(void) const'::`2'::LocalType ValueFromLambdaWithLocalType
+
+?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@?0???$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBE?A?3 at XZ@A
+; CHECK: struct `<auto> __thiscall `<auto> __cdecl TemplateFuncionWithLocalLambda<int>(int)'::`1'::<lambda_1>::operator()(void) const'::`3'::LocalType ValueFromTemplateFuncionWithLocalLambda
+
+??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z
+; CHECK: <auto> __cdecl TemplateFuncionWithLocalLambda<int>(int)
+
+??R<lambda_1>@?0???$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBE?A?1 at XZ
+; CHECK: <auto> __thiscall `<auto> __cdecl TemplateFuncionWithLocalLambda<int>(int)'::`1'::<lambda_1>::operator()(void) const
+
+??$WithPMD@$GA at A@?0@@3HA
+; CHECK: int WithPMD<{0, 0, -1}>
+
+?Zoo@@3U?$Foo@$1??$x at H@@3HA$1?1 at 3HA@@A
+; CHECK: struct Foo<&int x<int>, &int x<int>> Zoo
+
+??$unaligned_x at PFAH@@3PFAHA
+; CHECK: int __unaligned *unaligned_x<int __unaligned *>
More information about the llvm-commits
mailing list