aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Demangle/MicrosoftDemangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Demangle/MicrosoftDemangle.cpp')
-rw-r--r--llvm/lib/Demangle/MicrosoftDemangle.cpp100
1 files changed, 76 insertions, 24 deletions
diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp
index 0704f7b..b0f4d9a 100644
--- a/llvm/lib/Demangle/MicrosoftDemangle.cpp
+++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp
@@ -65,7 +65,10 @@ static bool isMemberPointer(StringView MangledName, bool &Error) {
// If it starts with a number, then 6 indicates a non-member function
// pointer, and 8 indicates a member function pointer.
if (startsWithDigit(MangledName)) {
- assert(MangledName[0] == '6' || MangledName[0] == '8');
+ if (MangledName[0] != '6' && MangledName[0] != '8') {
+ Error = true;
+ return false;
+ }
return (MangledName[0] == '8');
}
@@ -75,7 +78,10 @@ static bool isMemberPointer(StringView MangledName, bool &Error) {
MangledName.consumeFront('I'); // restrict
MangledName.consumeFront('F'); // unaligned
- assert(!MangledName.empty());
+ if (MangledName.empty()) {
+ Error = true;
+ return false;
+ }
// The next value should be either ABCD (non-member) or QRST (member).
switch (MangledName.front()) {
@@ -378,11 +384,11 @@ FunctionSymbolNode *Demangler::demangleInitFiniStub(StringView &MangledName,
if (MangledName.consumeFront('?'))
IsKnownStaticDataMember = true;
- QualifiedNameNode *QN = demangleFullyQualifiedSymbolName(MangledName);
+ SymbolNode *Symbol = demangleDeclarator(MangledName);
+ if (Error)
+ return nullptr;
- SymbolNode *Symbol = demangleEncodedSymbol(MangledName, QN);
FunctionSymbolNode *FSN = nullptr;
- Symbol->Name = QN;
if (Symbol->kind() == NodeKind::VariableSymbol) {
DSIN->Variable = static_cast<VariableSymbolNode *>(Symbol);
@@ -400,7 +406,8 @@ FunctionSymbolNode *Demangler::demangleInitFiniStub(StringView &MangledName,
}
FSN = demangleFunctionEncoding(MangledName);
- FSN->Name = synthesizeQualifiedName(Arena, DSIN);
+ if (FSN)
+ FSN->Name = synthesizeQualifiedName(Arena, DSIN);
} else {
if (IsKnownStaticDataMember) {
// This was supposed to be a static data member, but we got a function.
@@ -674,6 +681,11 @@ Demangler::demangleFunctionIdentifierCode(StringView &MangledName,
SymbolNode *Demangler::demangleEncodedSymbol(StringView &MangledName,
QualifiedNameNode *Name) {
+ if (MangledName.empty()) {
+ Error = true;
+ return nullptr;
+ }
+
// Read a variable.
switch (MangledName.front()) {
case '0':
@@ -693,11 +705,36 @@ SymbolNode *Demangler::demangleEncodedSymbol(StringView &MangledName,
if (UQN->kind() == NodeKind::ConversionOperatorIdentifier) {
ConversionOperatorIdentifierNode *COIN =
static_cast<ConversionOperatorIdentifierNode *>(UQN);
- COIN->TargetType = FSN->Signature->ReturnType;
+ if (FSN)
+ COIN->TargetType = FSN->Signature->ReturnType;
}
return FSN;
}
+SymbolNode *Demangler::demangleDeclarator(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 (Error)
+ return nullptr;
+ Symbol->Name = QN;
+
+ IdentifierNode *UQN = QN->getUnqualifiedIdentifier();
+ if (UQN->kind() == NodeKind::ConversionOperatorIdentifier) {
+ ConversionOperatorIdentifierNode *COIN =
+ static_cast<ConversionOperatorIdentifierNode *>(UQN);
+ if (!COIN->TargetType) {
+ Error = true;
+ return nullptr;
+ }
+ }
+ return Symbol;
+}
+
// Parser entry point.
SymbolNode *Demangler::parse(StringView &MangledName) {
// We can't demangle MD5 names, just output them as-is.
@@ -722,21 +759,7 @@ SymbolNode *Demangler::parse(StringView &MangledName) {
if (SymbolNode *SI = demangleSpecialIntrinsic(MangledName))
return SI;
- // 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) {
- Symbol->Name = QN;
- }
-
- if (Error)
- return nullptr;
-
- return Symbol;
+ return demangleDeclarator(MangledName);
}
TagTypeNode *Demangler::parseTagUniqueName(StringView &MangledName) {
@@ -763,6 +786,9 @@ VariableSymbolNode *Demangler::demangleVariableEncoding(StringView &MangledName,
VSN->Type = demangleType(MangledName, QualifierMangleMode::Drop);
VSN->SC = SC;
+ if (Error)
+ return nullptr;
+
// <variable-type> ::= <type> <cvr-qualifiers>
// ::= <type> <pointee-cvr-qualifiers> # pointers, references
switch (VSN->Type->kind()) {
@@ -1574,6 +1600,11 @@ FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
}
CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
+ if (MangledName.empty()) {
+ Error = true;
+ return CallingConv::None;
+ }
+
switch (MangledName.popFront()) {
case 'A':
case 'B':
@@ -1624,6 +1655,10 @@ StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
std::pair<Qualifiers, bool>
Demangler::demangleQualifiers(StringView &MangledName) {
+ if (MangledName.empty()) {
+ Error = true;
+ return std::make_pair(Q_None, false);
+ }
switch (MangledName.popFront()) {
// Member qualifiers
@@ -1662,6 +1697,11 @@ TypeNode *Demangler::demangleType(StringView &MangledName,
std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
}
+ if (MangledName.empty()) {
+ Error = true;
+ return nullptr;
+ }
+
TypeNode *Ty = nullptr;
if (isTagType(MangledName))
Ty = demangleClassType(MangledName);
@@ -1736,6 +1776,11 @@ Demangler::demangleFunctionEncoding(StringView &MangledName) {
if (MangledName.consumeFront("$$J0"))
ExtraFlags = FC_ExternC;
+ if (MangledName.empty()) {
+ Error = true;
+ return nullptr;
+ }
+
FuncClass FC = demangleFunctionClass(MangledName);
FC = FuncClass(ExtraFlags | FC);
@@ -1763,6 +1808,10 @@ Demangler::demangleFunctionEncoding(StringView &MangledName) {
bool HasThisQuals = !(FC & (FC_Global | FC_Static));
FSN = demangleFunctionType(MangledName, HasThisQuals);
}
+
+ if (Error)
+ return nullptr;
+
if (TTN) {
*static_cast<FunctionSignatureNode *>(TTN) = *FSN;
FSN = TTN;
@@ -1903,6 +1952,8 @@ PointerTypeNode *Demangler::demangleMemberPointerType(StringView &MangledName) {
Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
+ // isMemberPointer() only returns true if there is at least one character
+ // after the qualifiers.
if (MangledName.consumeFront("8")) {
Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
Pointer->Pointee = demangleFunctionType(MangledName, true);
@@ -1910,11 +1961,12 @@ PointerTypeNode *Demangler::demangleMemberPointerType(StringView &MangledName) {
Qualifiers PointeeQuals = Q_None;
bool IsMember = false;
std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
- assert(IsMember);
+ assert(IsMember || Error);
Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
- Pointer->Pointee->Quals = PointeeQuals;
+ if (Pointer->Pointee)
+ Pointer->Pointee->Quals = PointeeQuals;
}
return Pointer;