32using namespace ms_demangle;
35 return !S.empty() && std::isdigit(S.front());
44 if (!llvm::itanium_demangle::starts_with(S,
C))
51 if (!llvm::itanium_demangle::starts_with(S,
C))
53 S.remove_prefix(
C.size());
57static bool consumeFront(std::string_view &S, std::string_view PrefixA,
58 std::string_view PrefixB,
bool A) {
59 const std::string_view &Prefix =
A ? PrefixA : PrefixB;
63static bool startsWith(std::string_view S, std::string_view PrefixA,
64 std::string_view PrefixB,
bool A) {
65 const std::string_view &Prefix =
A ? PrefixA : PrefixB;
66 return llvm::itanium_demangle::starts_with(S, Prefix);
69bool Demangler::isMemberPointer(std::string_view MangledName,
bool &
Error) {
71 const char F = MangledName.front();
72 MangledName.remove_prefix(1);
98 if (MangledName[0] !=
'6' && MangledName[0] !=
'8') {
102 return (MangledName[0] ==
'8');
110 demanglePointerAuthQualifier(MangledName);
112 if (MangledName.empty()) {
118 switch (MangledName.front()) {
176 size_t End = S.find(
'?');
177 if (
End == std::string_view::npos)
179 std::string_view Candidate = S.substr(0,
End);
180 if (Candidate.empty())
185 if (Candidate.size() == 1)
186 return Candidate[0] ==
'@' || (Candidate[0] >=
'0' && Candidate[0] <=
'9');
189 if (Candidate.back() !=
'@')
191 Candidate.remove_suffix(1);
199 if (Candidate[0] <
'B' || Candidate[0] >
'P')
201 Candidate.remove_prefix(1);
202 while (!Candidate.empty()) {
203 if (Candidate[0] <
'A' || Candidate[0] >
'P')
205 Candidate.remove_prefix(1);
225 if (llvm::itanium_demangle::starts_with(S,
"$$Q"))
239static bool isArrayType(std::string_view S) {
return S[0] ==
'Y'; }
242 return llvm::itanium_demangle::starts_with(S,
"$$A8@@") ||
243 llvm::itanium_demangle::starts_with(S,
"$$A6");
255static std::pair<Qualifiers, PointerAffinity>
260 const char F = MangledName.front();
261 MangledName.remove_prefix(1);
280std::string_view Demangler::copyString(std::string_view Borrowed) {
285 std::memcpy(Stable, Borrowed.data(), Borrowed.size());
287 return {Stable, Borrowed.size()};
291Demangler::demangleSpecialTableSymbolNode(std::string_view &MangledName,
296 NI->
Name =
"`vftable'";
299 NI->
Name =
"`vbtable'";
302 NI->
Name =
"`local vftable'";
305 NI->
Name =
"`RTTI Complete Object Locator'";
314 if (MangledName.empty()) {
318 char Front = MangledName.front();
319 MangledName.remove_prefix(1);
320 if (Front !=
'6' && Front !=
'7') {
325 std::tie(STSN->
Quals, IsMember) = demangleQualifiers(MangledName);
327 STSN->
TargetName = demangleFullyQualifiedTypeName(MangledName);
332Demangler::demangleLocalStaticGuard(std::string_view &MangledName,
351 if (!MangledName.empty())
352 LSGI->
ScopeIndex = demangleUnsigned(MangledName);
357 std::string_view
Name) {
374 std::string_view
Name) {
381 std::string_view VariableName) {
390 std::string_view &MangledName,
391 std::string_view VariableName) {
404Demangler::demangleRttiBaseClassDescriptorNode(
ArenaAllocator &Arena,
405 std::string_view &MangledName) {
408 RBCDN->
NVOffset = demangleUnsigned(MangledName);
411 RBCDN->
Flags = demangleUnsigned(MangledName);
416 VSN->
Name = demangleNameScopeChain(MangledName, RBCDN);
422Demangler::demangleInitFiniStub(std::string_view &MangledName,
428 bool IsKnownStaticDataMember =
false;
430 IsKnownStaticDataMember =
true;
445 int AtCount = IsKnownStaticDataMember ? 2 : 1;
446 for (
int I = 0;
I < AtCount; ++
I) {
453 FSN = demangleFunctionEncoding(MangledName);
457 if (IsKnownStaticDataMember) {
471SymbolNode *Demangler::demangleSpecialIntrinsic(std::string_view &MangledName) {
478 return demangleStringLiteral(MangledName);
483 return demangleSpecialTableSymbolNode(MangledName, SIK);
485 return demangleVcallThunkNode(MangledName);
487 return demangleLocalStaticGuard(MangledName,
false);
489 return demangleLocalStaticGuard(MangledName,
true);
496 if (!MangledName.empty())
501 return demangleUntypedVariable(Arena, MangledName,
502 "`RTTI Base Class Array'");
504 return demangleUntypedVariable(Arena, MangledName,
505 "`RTTI Class Hierarchy Descriptor'");
507 return demangleRttiBaseClassDescriptorNode(Arena, MangledName);
509 return demangleInitFiniStub(MangledName,
false);
511 return demangleInitFiniStub(MangledName,
true);
525Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName) {
526 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
527 MangledName.remove_prefix(1);
528 if (MangledName.empty()) {
534 return demangleFunctionIdentifierCode(
537 return demangleFunctionIdentifierCode(MangledName,
539 return demangleFunctionIdentifierCode(MangledName,
544Demangler::demangleStructorIdentifier(std::string_view &MangledName,
547 N->IsDestructor = IsDestructor;
552Demangler::demangleConversionOperatorIdentifier(std::string_view &MangledName) {
559Demangler::demangleLiteralOperatorIdentifier(std::string_view &MangledName) {
562 N->Name = demangleSimpleString(MangledName,
false);
567Demangler::translateIntrinsicFunctionCode(
char CH,
570 if (!(
CH >=
'0' &&
CH <=
'9') && !(
CH >=
'A' &&
CH <=
'Z')) {
578 static IFK
Basic[36] = {
604 IFK::GreaterThanEqual,
616 static IFK
Under[36] = {
621 IFK::BitwiseAndEqual,
623 IFK::BitwiseXorEqual,
632 IFK::DefaultCtorClosure,
636 IFK::VecVbaseCtorIter,
640 IFK::EHVecVbaseCtorIter,
641 IFK::CopyCtorClosure,
646 IFK::LocalVftableCtorClosure,
665 IFK::ManVectorCtorIter,
666 IFK::ManVectorDtorIter,
667 IFK::EHVectorCopyCtorIter,
668 IFK::EHVectorVbaseCopyCtorIter,
671 IFK::VectorCopyCtorIter,
672 IFK::VectorVbaseCopyCtorIter,
673 IFK::ManVectorVbaseCopyCtorIter,
694 int Index = (
CH >=
'0' &&
CH <=
'9') ? (
CH -
'0') : (
CH -
'A' + 10);
707Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName,
709 if (MangledName.empty()) {
713 const char CH = MangledName.front();
716 MangledName.remove_prefix(1);
720 return demangleStructorIdentifier(MangledName,
CH ==
'1');
722 return demangleConversionOperatorIdentifier(MangledName);
725 translateIntrinsicFunctionCode(
CH, Group));
728 MangledName.remove_prefix(1);
730 translateIntrinsicFunctionCode(
CH, Group));
732 MangledName.remove_prefix(1);
735 return demangleLiteralOperatorIdentifier(MangledName);
738 translateIntrinsicFunctionCode(
CH, Group));
745SymbolNode *Demangler::demangleEncodedSymbol(std::string_view &MangledName,
747 if (MangledName.empty()) {
753 switch (MangledName.front()) {
759 StorageClass SC = demangleVariableStorageClass(MangledName);
760 return demangleVariableEncoding(MangledName, SC);
775SymbolNode *Demangler::demangleDeclarator(std::string_view &MangledName) {
799SymbolNode *Demangler::demangleMD5Name(std::string_view &MangledName) {
800 assert(llvm::itanium_demangle::starts_with(MangledName,
"??@"));
804 size_t MD5Last = MangledName.find(
'@', strlen(
"??@"));
805 if (MD5Last == std::string_view::npos) {
809 const char *Start = MangledName.data();
810 const size_t StartSize = MangledName.size();
811 MangledName.remove_prefix(MD5Last + 1);
825 assert(MangledName.size() < StartSize);
826 const size_t Count = StartSize - MangledName.size();
827 std::string_view
MD5(Start, Count);
834SymbolNode *Demangler::demangleTypeinfoName(std::string_view &MangledName) {
835 assert(llvm::itanium_demangle::starts_with(MangledName,
'.'));
839 if (
Error || !MangledName.empty()) {
851 if (llvm::itanium_demangle::starts_with(MangledName,
'.'))
852 return demangleTypeinfoName(MangledName);
854 if (llvm::itanium_demangle::starts_with(MangledName,
"??@"))
855 return demangleMD5Name(MangledName);
858 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
867 if (
SymbolNode *SI = demangleSpecialIntrinsic(MangledName))
870 return demangleDeclarator(MangledName);
873TagTypeNode *Demangler::parseTagUniqueName(std::string_view &MangledName) {
879 if (MangledName.empty()) {
884 return demangleClassType(MangledName);
895Demangler::demangleVariableEncoding(std::string_view &MangledName,
913 demanglePointerExtQualifiers(MangledName));
915 bool IsMember =
false;
916 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
920 demangleFullyQualifiedTypeName(MangledName);
928 VSN->
Type->
Quals = demangleQualifiers(MangledName).first;
946std::pair<uint64_t, bool>
947Demangler::demangleNumber(std::string_view &MangledName) {
952 MangledName.remove_prefix(1);
953 return {
Ret, IsNegative};
957 for (
size_t i = 0; i < MangledName.size(); ++i) {
958 char C = MangledName[i];
960 MangledName.remove_prefix(i + 1);
961 return {
Ret, IsNegative};
963 if (
'A' <=
C &&
C <=
'P') {
971 return {0ULL,
false};
974uint64_t Demangler::demangleUnsigned(std::string_view &MangledName) {
975 bool IsNegative =
false;
977 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
983int64_t Demangler::demangleSigned(std::string_view &MangledName) {
984 bool IsNegative =
false;
986 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
989 int64_t
I =
static_cast<int64_t
>(
Number);
990 return IsNegative ? -
I :
I;
995void Demangler::memorizeString(std::string_view S) {
998 for (
size_t i = 0; i < Backrefs.
NamesCount; ++i)
1007Demangler::demangleBackRefName(std::string_view &MangledName) {
1010 size_t I = MangledName[0] -
'0';
1016 MangledName.remove_prefix(1);
1017 return Backrefs.
Names[
I];
1025 std::string_view Owned = copyString(OB);
1026 memorizeString(Owned);
1027 std::free(
OB.getBuffer());
1031Demangler::demangleTemplateInstantiationName(std::string_view &MangledName,
1033 assert(llvm::itanium_demangle::starts_with(MangledName,
"?$"));
1040 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1042 Identifier->TemplateParams = demangleTemplateParameterList(MangledName);
1058 memorizeIdentifier(Identifier);
1065Demangler::demangleSimpleName(std::string_view &MangledName,
bool Memorize) {
1066 std::string_view S = demangleSimpleString(MangledName, Memorize);
1079 return (
C <=
'J') ? (
C -
'A') : (10 +
C -
'K');
1082uint8_t Demangler::demangleCharLiteral(std::string_view &MangledName) {
1083 assert(!MangledName.empty());
1084 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
1085 const uint8_t F = MangledName.front();
1086 MangledName.remove_prefix(1);
1090 MangledName.remove_prefix(1);
1091 if (MangledName.empty())
1092 goto CharLiteralError;
1096 if (MangledName.size() < 2)
1097 goto CharLiteralError;
1098 std::string_view Nibbles = MangledName.substr(0, 2);
1100 goto CharLiteralError;
1104 MangledName.remove_prefix(2);
1105 return (C1 << 4) | C2;
1109 const char *
Lookup =
",/\\:. \n\t'-";
1110 char C =
Lookup[MangledName[0] -
'0'];
1111 MangledName.remove_prefix(1);
1115 if (MangledName[0] >=
'a' && MangledName[0] <=
'z') {
1116 char Lookup[26] = {
'\xE1',
'\xE2',
'\xE3',
'\xE4',
'\xE5',
'\xE6',
'\xE7',
1117 '\xE8',
'\xE9',
'\xEA',
'\xEB',
'\xEC',
'\xED',
'\xEE',
1118 '\xEF',
'\xF0',
'\xF1',
'\xF2',
'\xF3',
'\xF4',
'\xF5',
1119 '\xF6',
'\xF7',
'\xF8',
'\xF9',
'\xFA'};
1120 char C =
Lookup[MangledName[0] -
'a'];
1121 MangledName.remove_prefix(1);
1125 if (MangledName[0] >=
'A' && MangledName[0] <=
'Z') {
1126 char Lookup[26] = {
'\xC1',
'\xC2',
'\xC3',
'\xC4',
'\xC5',
'\xC6',
'\xC7',
1127 '\xC8',
'\xC9',
'\xCA',
'\xCB',
'\xCC',
'\xCD',
'\xCE',
1128 '\xCF',
'\xD0',
'\xD1',
'\xD2',
'\xD3',
'\xD4',
'\xD5',
1129 '\xD6',
'\xD7',
'\xD8',
'\xD9',
'\xDA'};
1130 char C =
Lookup[MangledName[0] -
'A'];
1131 MangledName.remove_prefix(1);
1140wchar_t Demangler::demangleWcharLiteral(std::string_view &MangledName) {
1143 C1 = demangleCharLiteral(MangledName);
1144 if (
Error || MangledName.empty())
1145 goto WCharLiteralError;
1146 C2 = demangleCharLiteral(MangledName);
1148 goto WCharLiteralError;
1150 return ((
wchar_t)C1 << 8) | (wchar_t)C2;
1159 *Buffer = (Digit < 10) ? (
'0' + Digit) : (
'A' + Digit - 10);
1170 char TempBuffer[17];
1172 ::memset(TempBuffer, 0,
sizeof(TempBuffer));
1173 constexpr int MaxPos =
sizeof(TempBuffer) - 1;
1175 int Pos = MaxPos - 1;
1177 for (
int I = 0;
I < 2; ++
I) {
1182 TempBuffer[Pos--] =
'x';
1184 TempBuffer[Pos--] =
'\\';
1185 OB << std::string_view(&TempBuffer[Pos + 1]);
1227 if (
C > 0x1F &&
C < 0x7F) {
1251 if (*StringBytes++ == 0)
1265 if (NumBytes % 2 == 1)
1271 if (NumBytes < 32) {
1273 if (TrailingNulls >= 4 && NumBytes % 4 == 0)
1275 if (TrailingNulls >= 2)
1287 if (Nulls >= 2 * NumChars / 3 && NumBytes % 4 == 0)
1289 if (Nulls >= NumChars / 3)
1295 unsigned CharIndex,
unsigned CharBytes) {
1296 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1297 unsigned Offset = CharIndex * CharBytes;
1299 StringBytes = StringBytes +
Offset;
1300 for (
unsigned I = 0;
I < CharBytes; ++
I) {
1301 unsigned C =
static_cast<unsigned>(StringBytes[
I]);
1308Demangler::demangleVcallThunkNode(std::string_view &MangledName) {
1314 FSN->
Name = demangleNameScopeChain(MangledName, VTIN);
1318 VTIN->OffsetInVTable = demangleUnsigned(MangledName);
1323 return (
Error) ? nullptr : FSN;
1327Demangler::demangleStringLiteral(std::string_view &MangledName) {
1330 std::string_view CRC;
1332 bool IsWcharT =
false;
1333 bool IsNegative =
false;
1334 size_t CrcEndPos = 0;
1341 goto StringLiteralError;
1342 if (MangledName.empty())
1343 goto StringLiteralError;
1346 F = MangledName.front();
1347 MangledName.remove_prefix(1);
1355 goto StringLiteralError;
1359 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
1360 if (
Error || IsNegative || StringByteSize < (IsWcharT ? 2 : 1))
1361 goto StringLiteralError;
1364 CrcEndPos = MangledName.find(
'@');
1365 if (CrcEndPos == std::string_view::npos)
1366 goto StringLiteralError;
1367 CRC = MangledName.substr(0, CrcEndPos);
1368 MangledName.remove_prefix(CrcEndPos + 1);
1369 if (MangledName.empty())
1370 goto StringLiteralError;
1374 if (StringByteSize > 64)
1375 Result->IsTruncated =
true;
1379 if (StringByteSize % 2 != 0)
1380 goto StringLiteralError;
1381 if (StringByteSize == 0)
1382 goto StringLiteralError;
1383 if (MangledName.size() < 2)
1384 goto StringLiteralError;
1385 wchar_t W = demangleWcharLiteral(MangledName);
1386 if (StringByteSize != 2 ||
Result->IsTruncated)
1388 StringByteSize -= 2;
1390 goto StringLiteralError;
1395 constexpr unsigned MaxStringByteLength = 32 * 4;
1396 uint8_t StringBytes[MaxStringByteLength];
1398 unsigned BytesDecoded = 0;
1400 if (MangledName.size() < 1 || BytesDecoded >= MaxStringByteLength)
1401 goto StringLiteralError;
1402 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
1405 if (StringByteSize > BytesDecoded)
1406 Result->IsTruncated =
true;
1408 unsigned CharBytes =
1410 assert(StringByteSize % CharBytes == 0);
1411 switch (CharBytes) {
1424 const unsigned NumChars = BytesDecoded / CharBytes;
1425 for (
unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
1428 if (CharIndex + 1 < NumChars ||
Result->IsTruncated)
1433 Result->DecodedString = copyString(OB);
1434 std::free(
OB.getBuffer());
1439 std::free(
OB.getBuffer());
1445std::string_view Demangler::demangleSimpleString(std::string_view &MangledName,
1448 for (
size_t i = 0; i < MangledName.size(); ++i) {
1449 if (MangledName[i] !=
'@')
1453 S = MangledName.substr(0, i);
1454 MangledName.remove_prefix(i + 1);
1466Demangler::demangleAnonymousNamespaceName(std::string_view &MangledName) {
1467 assert(llvm::itanium_demangle::starts_with(MangledName,
"?A"));
1471 Node->Name =
"`anonymous namespace'";
1472 size_t EndPos = MangledName.find(
'@');
1473 if (EndPos == std::string_view::npos) {
1477 std::string_view NamespaceKey = MangledName.substr(0, EndPos);
1478 memorizeString(NamespaceKey);
1479 MangledName = MangledName.substr(EndPos + 1);
1484Demangler::demangleLocallyScopedNamePiece(std::string_view &MangledName) {
1490 bool IsNegative =
false;
1491 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
1510 std::free(
OB.getBuffer());
1516Demangler::demangleFullyQualifiedTypeName(std::string_view &MangledName) {
1518 demangleUnqualifiedTypeName(MangledName,
true);
1534Demangler::demangleFullyQualifiedSymbolName(std::string_view &MangledName) {
1541 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1564Demangler::demangleUnqualifiedTypeName(std::string_view &MangledName,
1571 return demangleBackRefName(MangledName);
1573 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1574 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1576 return demangleSimpleName(MangledName, Memorize);
1580Demangler::demangleUnqualifiedSymbolName(std::string_view &MangledName,
1583 return demangleBackRefName(MangledName);
1584 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1585 return demangleTemplateInstantiationName(MangledName, NBB);
1586 if (llvm::itanium_demangle::starts_with(MangledName,
'?'))
1587 return demangleFunctionIdentifierCode(MangledName);
1588 return demangleSimpleName(MangledName, (NBB &
NBB_Simple) != 0);
1592Demangler::demangleNameScopePiece(std::string_view &MangledName) {
1594 return demangleBackRefName(MangledName);
1596 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1597 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1599 if (llvm::itanium_demangle::starts_with(MangledName,
"?A"))
1600 return demangleAnonymousNamespaceName(MangledName);
1603 return demangleLocallyScopedNamePiece(MangledName);
1605 return demangleSimpleName(MangledName,
true);
1613 for (
size_t I = 0;
I < Count; ++
I) {
1614 N->Nodes[
I] = Head->
N;
1621Demangler::demangleNameScopeChain(std::string_view &MangledName,
1625 Head->
N = UnqualifiedName;
1631 NewHead->
Next = Head;
1634 if (MangledName.empty()) {
1652FuncClass Demangler::demangleFunctionClass(std::string_view &MangledName) {
1653 const char F = MangledName.front();
1654 MangledName.remove_prefix(1);
1714 if (MangledName.empty())
1716 const char F = MangledName.front();
1717 MangledName.remove_prefix(1);
1740Demangler::demangleCallingConvention(std::string_view &MangledName) {
1741 if (MangledName.empty()) {
1746 const char F = MangledName.front();
1747 MangledName.remove_prefix(1);
1782Demangler::demangleVariableStorageClass(std::string_view &MangledName) {
1783 assert(MangledName.front() >=
'0' && MangledName.front() <=
'4');
1785 const char F = MangledName.front();
1786 MangledName.remove_prefix(1);
1802std::pair<Qualifiers, bool>
1803Demangler::demangleQualifiers(std::string_view &MangledName) {
1804 if (MangledName.empty()) {
1806 return std::make_pair(
Q_None,
false);
1809 const char F = MangledName.front();
1810 MangledName.remove_prefix(1);
1814 return std::make_pair(
Q_None,
true);
1816 return std::make_pair(
Q_Const,
true);
1823 return std::make_pair(
Q_None,
false);
1825 return std::make_pair(
Q_Const,
false);
1832 return std::make_pair(
Q_None,
false);
1837TypeNode *Demangler::demangleType(std::string_view &MangledName,
1842 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1845 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1848 if (MangledName.empty()) {
1855 Ty = demangleClassType(MangledName);
1857 if (isMemberPointer(MangledName,
Error))
1858 Ty = demangleMemberPointerType(MangledName);
1860 Ty = demanglePointerType(MangledName);
1864 Ty = demangleArrayType(MangledName);
1867 Ty = demangleFunctionType(MangledName,
true);
1869 assert(llvm::itanium_demangle::starts_with(MangledName,
"$$A6"));
1871 Ty = demangleFunctionType(MangledName,
false);
1874 Ty = demangleCustomType(MangledName);
1876 Ty = demanglePrimitiveType(MangledName);
1885bool Demangler::demangleThrowSpecification(std::string_view &MangledName) {
1896Demangler::demangleFunctionType(std::string_view &MangledName,
1897 bool HasThisQuals) {
1901 FTy->
Quals = demanglePointerExtQualifiers(MangledName);
1917 FTy->
IsNoexcept = demangleThrowSpecification(MangledName);
1923Demangler::demangleFunctionEncoding(std::string_view &MangledName) {
1928 if (MangledName.empty()) {
1933 FuncClass FC = demangleFunctionClass(MangledName);
1958 FSN = demangleFunctionType(MangledName, HasThisQuals);
1975CustomTypeNode *Demangler::demangleCustomType(std::string_view &MangledName) {
1976 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
1977 MangledName.remove_prefix(1);
1980 CTN->
Identifier = demangleUnqualifiedTypeName(MangledName,
true);
1990Demangler::demanglePrimitiveType(std::string_view &MangledName) {
1994 const char F = MangledName.front();
1995 MangledName.remove_prefix(1);
2024 if (MangledName.empty()) {
2028 const char F = MangledName.front();
2029 MangledName.remove_prefix(1);
2057TagTypeNode *Demangler::demangleClassType(std::string_view &MangledName) {
2060 const char F = MangledName.front();
2061 MangledName.remove_prefix(1);
2083 TT->QualifiedName = demangleFullyQualifiedTypeName(MangledName);
2089PointerTypeNode *Demangler::demanglePointerType(std::string_view &MangledName) {
2096 Pointer->Pointee = demangleFunctionType(MangledName,
false);
2100 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2103 Pointer->PointerAuthQualifier = createPointerAuthQualifier(MangledName);
2110Demangler::demangleMemberPointerType(std::string_view &MangledName) {
2117 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2123 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2124 Pointer->Pointee = demangleFunctionType(MangledName,
true);
2128 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
2130 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2134 Pointer->Pointee->Quals = PointeeQuals;
2141Demangler::demanglePointerExtQualifiers(std::string_view &MangledName) {
2153std::optional<PointerAuthQualifierNode::ArgArray>
2154Demangler::demanglePointerAuthQualifier(std::string_view &MangledName) {
2156 return std::nullopt;
2161 for (
unsigned I = 0;
I < NumArgs; ++
I) {
2162 bool IsNegative =
false;
2164 std::tie(
Value, IsNegative) = demangleNumber(MangledName);
2166 return std::nullopt;
2175Demangler::createPointerAuthQualifier(std::string_view &MangledName) {
2177 std::optional<PointerAuthQualifierNode::ArgArray> Vals =
2178 demanglePointerAuthQualifier(MangledName);
2187 Array->Count = NumArgs;
2190 for (
unsigned I = 0;
I < NumArgs; ++
I)
2196ArrayTypeNode *Demangler::demangleArrayType(std::string_view &MangledName) {
2197 assert(MangledName.front() ==
'Y');
2198 MangledName.remove_prefix(1);
2201 bool IsNegative =
false;
2202 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2203 if (IsNegative || Rank == 0) {
2214 std::tie(
D, IsNegative) = demangleNumber(MangledName);
2215 if (
Error || IsNegative) {
2229 std::tie(ATy->
Quals, IsMember) = demangleQualifiers(MangledName);
2242Demangler::demangleFunctionParameterList(std::string_view &MangledName,
2251 while (!
Error && !llvm::itanium_demangle::starts_with(MangledName,
'@') &&
2252 !llvm::itanium_demangle::starts_with(MangledName,
'Z')) {
2256 size_t N = MangledName[0] -
'0';
2261 MangledName.remove_prefix(1);
2265 Current = &(*Current)->Next;
2269 size_t OldSize = MangledName.size();
2278 size_t CharsConsumed = OldSize - MangledName.size();
2279 assert(CharsConsumed != 0);
2286 Current = &(*Current)->Next;
2308Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
2313 while (!llvm::itanium_demangle::starts_with(MangledName,
'@')) {
2328 const bool IsAutoNTTP =
consumeFront(MangledName,
"$M");
2342 TP.N = demangleFullyQualifiedTypeName(MangledName);
2349 }
else if (
startsWith(MangledName,
"$1",
"1", !IsAutoNTTP) ||
2350 startsWith(MangledName,
"$H",
"H", !IsAutoNTTP) ||
2351 startsWith(MangledName,
"$I",
"I", !IsAutoNTTP) ||
2352 startsWith(MangledName,
"$J",
"J", !IsAutoNTTP)) {
2358 MangledName.remove_prefix(1);
2364 char InheritanceSpecifier = MangledName.front();
2365 MangledName.remove_prefix(1);
2367 if (llvm::itanium_demangle::starts_with(MangledName,
'?')) {
2368 S =
parse(MangledName);
2376 switch (InheritanceSpecifier) {
2379 demangleSigned(MangledName);
2383 demangleSigned(MangledName);
2387 demangleSigned(MangledName);
2396 }
else if (llvm::itanium_demangle::starts_with(MangledName,
"$E?")) {
2402 }
else if (
startsWith(MangledName,
"$F",
"F", !IsAutoNTTP) ||
2403 startsWith(MangledName,
"$G",
"G", !IsAutoNTTP)) {
2408 MangledName.remove_prefix(1);
2409 char InheritanceSpecifier = MangledName.front();
2410 MangledName.remove_prefix(1);
2412 switch (InheritanceSpecifier) {
2415 demangleSigned(MangledName);
2419 demangleSigned(MangledName);
2421 demangleSigned(MangledName);
2428 }
else if (
consumeFront(MangledName,
"$0",
"0", !IsAutoNTTP)) {
2430 bool IsNegative =
false;
2432 std::tie(
Value, IsNegative) = demangleNumber(MangledName);
2449 assert(llvm::itanium_demangle::starts_with(
2455void Demangler::dumpBackReferences() {
2456 std::printf(
"%d function parameter backreferences\n",
2462 OB.setCurrentPosition(0);
2467 std::string_view
B = OB;
2468 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)
B.size(),
B.data());
2470 std::free(OB.getBuffer());
2474 std::printf(
"%d name backreferences\n", (
int)Backrefs.
NamesCount);
2476 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)Backrefs.
Names[
I]->
Name.size(),
2483std::optional<size_t>
2485 std::string_view ProcessedName{MangledName};
2489 return std::nullopt;
2494 D.demangleFullyQualifiedSymbolName(ProcessedName);
2496 return std::nullopt;
2498 return MangledName.length() - ProcessedName.length();
2505 std::string_view
Name{MangledName};
2507 if (!
D.Error && NMangled)
2508 *NMangled = MangledName.size() -
Name.size();
2511 D.dumpBackReferences();
2533 Buf = OB.getBuffer();
2537 *
Status = InternalStatus;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define DEMANGLE_FALLTHROUGH
#define DEMANGLE_UNREACHABLE
static bool startsWithLocalScopePattern(std::string_view S)
static bool isArrayType(std::string_view S)
static unsigned countEmbeddedNulls(const uint8_t *StringBytes, unsigned Length)
static bool startsWithDigit(std::string_view S)
static QualifiedNameNode * synthesizeQualifiedName(ArenaAllocator &Arena, IdentifierNode *Identifier)
static void outputEscapedChar(OutputBuffer &OB, unsigned C)
static bool isCustomType(std::string_view S)
static void outputHex(OutputBuffer &OB, unsigned C)
static std::pair< Qualifiers, PointerAffinity > demanglePointerCVQualifiers(std::string_view &MangledName)
static VariableSymbolNode * synthesizeVariable(ArenaAllocator &Arena, TypeNode *Type, std::string_view VariableName)
static unsigned decodeMultiByteChar(const uint8_t *StringBytes, unsigned CharIndex, unsigned CharBytes)
static void writeHexDigit(char *Buffer, uint8_t Digit)
static FunctionRefQualifier demangleFunctionRefQualifier(std::string_view &MangledName)
static bool isRebasedHexDigit(char C)
static NodeArrayNode * nodeListToNodeArray(ArenaAllocator &Arena, NodeList *Head, size_t Count)
static uint8_t rebasedHexDigitToNumber(char C)
static unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length)
static NamedIdentifierNode * synthesizeNamedIdentifier(ArenaAllocator &Arena, std::string_view Name)
static bool startsWith(std::string_view S, std::string_view PrefixA, std::string_view PrefixB, bool A)
static bool consumeFront(std::string_view &S, char C)
static bool isFunctionType(std::string_view S)
static bool isPointerType(std::string_view S)
static unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars, uint64_t NumBytes)
static SpecialIntrinsicKind consumeSpecialIntrinsicKind(std::string_view &MangledName)
static bool isTagType(std::string_view S)
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
Lightweight error class with error context and mandatory checking.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
T * alloc(Args &&... ConstructorArgs)
char * allocUnalignedBuffer(size_t Size)
T * allocArray(size_t Count)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ C
The default llvm calling convention, compatible with C.
@ OB
OB - OneByte - Set if this instruction has a one byte opcode.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
FunctionIdentifierCodeGroup
@ ConversionOperatorIdentifier
@ RttiBaseClassDescriptor
@ DynamicAtexitDestructor
@ RttiClassHierarchyDescriptor
This is an optimization pass for GlobalISel generic memory operations.
DEMANGLE_ABI std::optional< size_t > getArm64ECInsertionPointInMangledName(std::string_view MangledName)
@ demangle_invalid_mangled_name
DEMANGLE_ABI char * microsoftDemangle(std::string_view mangled_name, size_t *n_read, int *status, MSDemangleFlags Flags=MSDF_None)
Demangles the Microsoft symbol pointed at by mangled_name and returns it.
@ MSDF_NoCallingConvention
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
NodeArrayNode * Dimensions
static constexpr size_t Max
NamedIdentifierNode * Names[Max]
TypeNode * FunctionParams[Max]
size_t FunctionParamCount
IdentifierNode * Identifier
VariableSymbolNode * Variable
FunctionRefQualifier RefQualifier
CallingConv CallConvention
FunctionSignatureNode * Signature
std::array< uint64_t, NumArgs > ArgArray
static constexpr unsigned NumArgs
NodeArrayNode * Components
QualifiedNameNode * ClassParent
IdentifierNode * getUnqualifiedIdentifier()
NodeArrayNode * Components
QualifiedNameNode * TargetName
void output(OutputBuffer &OB, OutputFlags Flags) const override
std::array< int64_t, 3 > ThunkOffsets