summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangle.cpp75
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangleNodes.cpp12
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangleNodes.h3
-rw-r--r--llvm/test/Demangle/ms-back-references.test3
-rw-r--r--llvm/test/Demangle/ms-operators.test6
-rw-r--r--llvm/test/Demangle/ms-string-literals.test11
6 files changed, 82 insertions, 28 deletions
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index 5081f94f387..ad6990c4e21 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -350,8 +350,8 @@ private:
VariableSymbolNode *
demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
StringView &MangledName);
- FunctionSymbolNode *demangleDynamicStructorFunction(StringView &MangledName,
- bool IsDestructor);
+ FunctionSymbolNode *demangleInitFiniStub(StringView &MangledName,
+ bool IsDestructor);
NamedIdentifierNode *demangleSimpleName(StringView &MangledName,
bool Memorize);
@@ -520,16 +520,35 @@ Demangler::demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
return VSN;
}
-FunctionSymbolNode *
-Demangler::demangleDynamicStructorFunction(StringView &MangledName,
- bool IsDestructor) {
+FunctionSymbolNode *Demangler::demangleInitFiniStub(StringView &MangledName,
+ bool IsDestructor) {
DynamicStructorIdentifierNode *DSIN =
Arena.alloc<DynamicStructorIdentifierNode>();
DSIN->IsDestructor = IsDestructor;
- DSIN->Name = demangleFullyQualifiedTypeName(MangledName);
- QualifiedNameNode *QNN = synthesizeQualifiedName(Arena, DSIN);
- FunctionSymbolNode *FSN = demangleFunctionEncoding(MangledName);
- FSN->Name = QNN;
+
+ // What follows is a main symbol name. This may include namespaces or class
+ // back references.
+ QualifiedNameNode *QN = demangleFullyQualifiedSymbolName(MangledName);
+
+ SymbolNode *Symbol = demangleEncodedSymbol(MangledName, QN);
+ FunctionSymbolNode *FSN = nullptr;
+ Symbol->Name = QN;
+
+ if (Symbol->kind() == NodeKind::VariableSymbol) {
+ DSIN->Variable = static_cast<VariableSymbolNode *>(Symbol);
+ if (!MangledName.consumeFront('@')) {
+ Error = true;
+ return nullptr;
+ }
+
+ FSN = demangleFunctionEncoding(MangledName);
+ FSN->Name = synthesizeQualifiedName(Arena, DSIN);
+ } else {
+ FSN = static_cast<FunctionSymbolNode *>(Symbol);
+ DSIN->Name = Symbol->Name;
+ FSN->Name = synthesizeQualifiedName(Arena, DSIN);
+ }
+
return FSN;
}
@@ -569,9 +588,9 @@ SymbolNode *Demangler::demangleSpecialIntrinsic(StringView &MangledName) {
case SpecialIntrinsicKind::RttiBaseClassDescriptor:
return demangleRttiBaseClassDescriptorNode(Arena, MangledName);
case SpecialIntrinsicKind::DynamicInitializer:
- return demangleDynamicStructorFunction(MangledName, false);
+ return demangleInitFiniStub(MangledName, false);
case SpecialIntrinsicKind::DynamicAtexitDestructor:
- return demangleDynamicStructorFunction(MangledName, true);
+ return demangleInitFiniStub(MangledName, true);
default:
break;
}
@@ -837,6 +856,8 @@ SymbolNode *Demangler::parse(StringView &MangledName) {
// What follows is a main symbol name. This may include namespaces or class
// back references.
QualifiedNameNode *QN = demangleFullyQualifiedSymbolName(MangledName);
+ if (Error)
+ return nullptr;
SymbolNode *Symbol = demangleEncodedSymbol(MangledName, QN);
if (Symbol) {
@@ -1325,10 +1346,9 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
goto StringLiteralError;
}
} else {
- if (StringByteSize > 32)
- Result->IsTruncated = true;
-
- constexpr unsigned MaxStringByteLength = 32;
+ // The max byte length is actually 32, but some compilers mangled strings
+ // incorrectly, so we have to assume it can go higher.
+ constexpr unsigned MaxStringByteLength = 32 * 4;
uint8_t StringBytes[MaxStringByteLength];
unsigned BytesDecoded = 0;
@@ -1337,6 +1357,9 @@ Demangler::demangleStringLiteral(StringView &MangledName) {
StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
}
+ if (StringByteSize > BytesDecoded)
+ Result->IsTruncated = true;
+
unsigned CharBytes =
guessCharByteSize(StringBytes, BytesDecoded, StringByteSize);
assert(StringByteSize % CharBytes == 0);
@@ -1587,6 +1610,10 @@ FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
return FuncClass(FC_Private | FC_Virtual);
case 'F':
return FuncClass(FC_Private | FC_Virtual);
+ case 'G':
+ return FuncClass(FC_Private | FC_StaticThisAdjust);
+ case 'H':
+ return FuncClass(FC_Private | FC_StaticThisAdjust | FC_Far);
case 'I':
return FuncClass(FC_Protected);
case 'J':
@@ -1760,7 +1787,6 @@ TypeNode *Demangler::demangleType(StringView &MangledName,
Ty = demangleCustomType(MangledName);
} else {
Ty = demanglePrimitiveType(MangledName);
- assert(Ty && !Error);
if (!Ty || Error)
return Ty;
}
@@ -1976,14 +2002,14 @@ PointerTypeNode *Demangler::demangleMemberPointerType(StringView &MangledName) {
Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
if (MangledName.consumeFront("8")) {
- Pointer->ClassParent = demangleFullyQualifiedSymbolName(MangledName);
+ Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
Pointer->Pointee = demangleFunctionType(MangledName, true);
} else {
Qualifiers PointeeQuals = Q_None;
bool IsMember = false;
std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
assert(IsMember);
- Pointer->ClassParent = demangleFullyQualifiedSymbolName(MangledName);
+ Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
Pointer->Pointee->Quals = PointeeQuals;
@@ -2121,18 +2147,21 @@ Demangler::demangleTemplateParameterList(StringView &MangledName) {
size_t Count = 0;
while (!Error && !MangledName.startsWith('@')) {
+ if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
+ MangledName.consumeFront("$$$V")) {
+ // Empty parameter pack.
+ continue;
+ }
+
++Count;
+
// Template parameter lists don't participate in back-referencing.
*Current = Arena.alloc<NodeList>();
NodeList &TP = **Current;
TemplateParameterReferenceNode *TPRN = nullptr;
- if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
- MangledName.consumeFront("$$$V")) {
- // Empty parameter pack.
- TP.N = nullptr;
- } else if (MangledName.consumeFront("$$Y")) {
+ if (MangledName.consumeFront("$$Y")) {
// Template alias
TP.N = demangleFullyQualifiedTypeName(MangledName);
} else if (MangledName.consumeFront("$$B")) {
diff --git a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
index 9d1aa1ac28d..93719f89342 100644
--- a/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp
@@ -223,9 +223,15 @@ void DynamicStructorIdentifierNode::output(OutputStream &OS,
else
OS << "`dynamic initializer for ";
- OS << "'";
- Name->output(OS, Flags);
- OS << "''";
+ if (Variable) {
+ OS << "`";
+ Variable->output(OS, Flags);
+ OS << "''";
+ } else {
+ OS << "'";
+ Name->output(OS, Flags);
+ OS << "''";
+ }
}
void NamedIdentifierNode::output(OutputStream &OS, OutputFlags Flags) const {
diff --git a/llvm/lib/Demangle/MicrosoftDemangleNodes.h b/llvm/lib/Demangle/MicrosoftDemangleNodes.h
index 93845b5200b..caa7eb3b526 100644
--- a/llvm/lib/Demangle/MicrosoftDemangleNodes.h
+++ b/llvm/lib/Demangle/MicrosoftDemangleNodes.h
@@ -322,7 +322,7 @@ enum class NodeKind {
LocalStaticGuardVariable,
FunctionSymbol,
VariableSymbol,
- SpecialTableSymbol,
+ SpecialTableSymbol
};
struct Node {
@@ -443,6 +443,7 @@ struct DynamicStructorIdentifierNode : public IdentifierNode {
void output(OutputStream &OS, OutputFlags Flags) const override;
+ VariableSymbolNode *Variable = nullptr;
QualifiedNameNode *Name = nullptr;
bool IsDestructor = false;
};
diff --git a/llvm/test/Demangle/ms-back-references.test b/llvm/test/Demangle/ms-back-references.test
index 53bc8b449ed..e04fd846721 100644
--- a/llvm/test/Demangle/ms-back-references.test
+++ b/llvm/test/Demangle/ms-back-references.test
@@ -169,3 +169,6 @@
?AddEmitPasses@EmitAssemblyHelper@?A0x43583946@@AEAA_NAEAVPassManager@legacy@llvm@@W4BackendAction@clang@@AEAVraw_pwrite_stream@5@PEAV85@@Z
; CHECK: bool __cdecl `anonymous namespace'::EmitAssemblyHelper::AddEmitPasses(class llvm::legacy::PassManager &, enum clang::BackendAction, class llvm::raw_pwrite_stream &, class llvm::raw_pwrite_stream *)
+
+??$forward@P8?$DecoderStream@$01@media@@AEXXZ@std@@YA$$QAP8?$DecoderStream@$01@media@@AEXXZAAP812@AEXXZ@Z
+; CHECK: void (__thiscall media::DecoderStream<2>::*&& __cdecl std::forward<void (__thiscall media::DecoderStream<2>::*)(void)>(void (__thiscall media::DecoderStream<2>::*&)(void)))(void) \ No newline at end of file
diff --git a/llvm/test/Demangle/ms-operators.test b/llvm/test/Demangle/ms-operators.test
index d03d9da7eb0..ad3d87807b4 100644
--- a/llvm/test/Demangle/ms-operators.test
+++ b/llvm/test/Demangle/ms-operators.test
@@ -161,6 +161,9 @@
??_EBase@@UEAAPEAXI@Z
; CHECK: virtual void * __cdecl Base::`vector deleting dtor'(unsigned int)
+??_EBase@@G3AEPAXI@Z
+; CHECK: [thunk]: void * __thiscall Base::`vector deleting dtor'`adjustor{4}'(unsigned int)
+
??_F?$SomeTemplate@H@@QAEXXZ
; CHECK: void __thiscall SomeTemplate<int>::`default ctor closure'(void)
@@ -224,6 +227,9 @@
??__FFoo@@YAXXZ
; CHECK: void __cdecl `dynamic atexit destructor for 'Foo''(void)
+??__F_decisionToDFA@XPathLexer@@0V?$vector@VDFA@dfa@antlr4@@V?$allocator@VDFA@dfa@antlr4@@@std@@@std@@A@YAXXZ
+; CHECK: void __cdecl `dynamic atexit destructor for `static class std::vector<class antlr4::dfa::DFA, class std::allocator<class antlr4::dfa::DFA>> XPathLexer::_decisionToDFA''(void)
+
??__K_deg@@YAHO@Z
; CHECK: int __cdecl operator ""_deg(long double)
diff --git a/llvm/test/Demangle/ms-string-literals.test b/llvm/test/Demangle/ms-string-literals.test
index 77a1882b49d..132637c267d 100644
--- a/llvm/test/Demangle/ms-string-literals.test
+++ b/llvm/test/Demangle/ms-string-literals.test
@@ -761,4 +761,13 @@
; CHECK: const char16_t * {u"012345678901234"}
??_C@_0CA@KFPHPCC@0?$AA?$AA?$AA1?$AA?$AA?$AA2?$AA?$AA?$AA3?$AA?$AA?$AA4?$AA?$AA?$AA5?$AA?$AA?$AA6?$AA?$AA?$AA?$AA?$AA?$AA?$AA@
-; CHECK: const char32_t * {U"0123456"} \ No newline at end of file
+; CHECK: const char32_t * {U"0123456"}
+
+; There are too many bytes encoded in this string literal (it should encode a max of 32 bytes)
+; but some buggy compilers will incorrectly generate this, so we need to be able to demangle
+; both the correct and incorrect versions.
+??_C@_0CG@HJGBPLNO@l?$AAo?$AAo?$AAk?$AAA?$AAh?$AAe?$AAa?$AAd?$AAH?$AAa?$AAr?$AAd?$AAB?$AAr?$AAe?$AAa?$AAk?$AA?$AA?$AA@
+; CHECK: const char16_t * {u"lookAheadHardBreak"}
+
+??_C@_0CG@HJGBPLNO@l?$AAo?$AAo?$AAk?$AAA?$AAh?$AAe?$AAa?$AAd?$AAH?$AAa?$AAr?$AAd?$AAB?$AAr?$AAe?$AA@
+; CHECK: const char16_t * {u"lookAheadHardBre"...} \ No newline at end of file
OpenPOWER on IntegriCloud