31using namespace ms_demangle;
34 return !S.empty() && std::isdigit(S.front());
43 if (!llvm::itanium_demangle::starts_with(S,
C))
50 if (!llvm::itanium_demangle::starts_with(S,
C))
52 S.remove_prefix(
C.size());
58 const char F = MangledName.front();
59 MangledName.remove_prefix(1);
85 if (MangledName[0] !=
'6' && MangledName[0] !=
'8') {
89 return (MangledName[0] ==
'8');
98 if (MangledName.empty()) {
104 switch (MangledName.front()) {
124 return SpecialIntrinsicKind::Vftable;
126 return SpecialIntrinsicKind::Vbtable;
128 return SpecialIntrinsicKind::VcallThunk;
130 return SpecialIntrinsicKind::Typeof;
132 return SpecialIntrinsicKind::LocalStaticGuard;
134 return SpecialIntrinsicKind::StringLiteralSymbol;
136 return SpecialIntrinsicKind::UdtReturning;
138 return SpecialIntrinsicKind::RttiTypeDescriptor;
140 return SpecialIntrinsicKind::RttiBaseClassDescriptor;
142 return SpecialIntrinsicKind::RttiBaseClassArray;
144 return SpecialIntrinsicKind::RttiClassHierarchyDescriptor;
146 return SpecialIntrinsicKind::RttiCompleteObjLocator;
148 return SpecialIntrinsicKind::LocalVftable;
150 return SpecialIntrinsicKind::DynamicInitializer;
152 return SpecialIntrinsicKind::DynamicAtexitDestructor;
154 return SpecialIntrinsicKind::LocalStaticThreadGuard;
155 return SpecialIntrinsicKind::None;
162 size_t End = S.find(
'?');
163 if (
End == std::string_view::npos)
165 std::string_view Candidate = S.substr(0,
End);
166 if (Candidate.empty())
171 if (Candidate.size() == 1)
172 return Candidate[0] ==
'@' || (Candidate[0] >=
'0' && Candidate[0] <=
'9');
175 if (Candidate.back() !=
'@')
177 Candidate.remove_suffix(1);
185 if (Candidate[0] <
'B' || Candidate[0] >
'P')
187 Candidate.remove_prefix(1);
188 while (!Candidate.empty()) {
189 if (Candidate[0] <
'A' || Candidate[0] >
'P')
191 Candidate.remove_prefix(1);
211 if (llvm::itanium_demangle::starts_with(S,
"$$Q"))
225static bool isArrayType(std::string_view S) {
return S[0] ==
'Y'; }
228 return llvm::itanium_demangle::starts_with(S,
"$$A8@@") ||
229 llvm::itanium_demangle::starts_with(S,
"$$A6");
235 return FunctionRefQualifier::Reference;
237 return FunctionRefQualifier::RValueReference;
238 return FunctionRefQualifier::None;
241static std::pair<Qualifiers, PointerAffinity>
244 return std::make_pair(
Q_None, PointerAffinity::RValueReference);
246 const char F = MangledName.front();
247 MangledName.remove_prefix(1);
250 return std::make_pair(
Q_None, PointerAffinity::Reference);
252 return std::make_pair(
Q_None, PointerAffinity::Pointer);
254 return std::make_pair(
Q_Const, PointerAffinity::Pointer);
256 return std::make_pair(
Q_Volatile, PointerAffinity::Pointer);
259 PointerAffinity::Pointer);
266std::string_view Demangler::copyString(std::string_view Borrowed) {
271 std::memcpy(Stable, &*Borrowed.begin(), Borrowed.size());
273 return {Stable, Borrowed.size()};
277Demangler::demangleSpecialTableSymbolNode(std::string_view &MangledName,
282 NI->
Name =
"`vftable'";
285 NI->
Name =
"`vbtable'";
288 NI->
Name =
"`local vftable'";
291 NI->
Name =
"`RTTI Complete Object Locator'";
300 if (MangledName.empty()) {
304 char Front = MangledName.front();
305 MangledName.remove_prefix(1);
306 if (Front !=
'6' && Front !=
'7') {
311 std::tie(STSN->
Quals, IsMember) = demangleQualifiers(MangledName);
313 STSN->
TargetName = demangleFullyQualifiedTypeName(MangledName);
318Demangler::demangleLocalStaticGuard(std::string_view &MangledName,
337 if (!MangledName.empty())
338 LSGI->
ScopeIndex = demangleUnsigned(MangledName);
343 std::string_view
Name) {
360 std::string_view
Name) {
367 std::string_view VariableName) {
376 std::string_view &MangledName,
377 std::string_view VariableName) {
390Demangler::demangleRttiBaseClassDescriptorNode(
ArenaAllocator &Arena,
391 std::string_view &MangledName) {
394 RBCDN->
NVOffset = demangleUnsigned(MangledName);
397 RBCDN->
Flags = demangleUnsigned(MangledName);
402 VSN->
Name = demangleNameScopeChain(MangledName, RBCDN);
408Demangler::demangleInitFiniStub(std::string_view &MangledName,
414 bool IsKnownStaticDataMember =
false;
416 IsKnownStaticDataMember =
true;
431 int AtCount = IsKnownStaticDataMember ? 2 : 1;
432 for (
int I = 0;
I < AtCount; ++
I) {
439 FSN = demangleFunctionEncoding(MangledName);
443 if (IsKnownStaticDataMember) {
457SymbolNode *Demangler::demangleSpecialIntrinsic(std::string_view &MangledName) {
464 return demangleStringLiteral(MangledName);
469 return demangleSpecialTableSymbolNode(MangledName, SIK);
471 return demangleVcallThunkNode(MangledName);
473 return demangleLocalStaticGuard(MangledName,
false);
475 return demangleLocalStaticGuard(MangledName,
true);
482 if (!MangledName.empty())
487 return demangleUntypedVariable(Arena, MangledName,
488 "`RTTI Base Class Array'");
490 return demangleUntypedVariable(Arena, MangledName,
491 "`RTTI Class Hierarchy Descriptor'");
493 return demangleRttiBaseClassDescriptorNode(Arena, MangledName);
495 return demangleInitFiniStub(MangledName,
false);
497 return demangleInitFiniStub(MangledName,
true);
511Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName) {
512 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
513 MangledName.remove_prefix(1);
514 if (MangledName.empty()) {
520 return demangleFunctionIdentifierCode(
523 return demangleFunctionIdentifierCode(MangledName,
525 return demangleFunctionIdentifierCode(MangledName,
530Demangler::demangleStructorIdentifier(std::string_view &MangledName,
533 N->IsDestructor = IsDestructor;
538Demangler::demangleConversionOperatorIdentifier(std::string_view &MangledName) {
545Demangler::demangleLiteralOperatorIdentifier(std::string_view &MangledName) {
548 N->Name = demangleSimpleString(MangledName,
false);
553Demangler::translateIntrinsicFunctionCode(
char CH,
556 if (!(
CH >=
'0' &&
CH <=
'9') && !(
CH >=
'A' &&
CH <=
'Z')) {
564 static IFK
Basic[36] = {
590 IFK::GreaterThanEqual,
602 static IFK
Under[36] = {
607 IFK::BitwiseAndEqual,
609 IFK::BitwiseXorEqual,
618 IFK::DefaultCtorClosure,
622 IFK::VecVbaseCtorIter,
626 IFK::EHVecVbaseCtorIter,
627 IFK::CopyCtorClosure,
632 IFK::LocalVftableCtorClosure,
651 IFK::ManVectorCtorIter,
652 IFK::ManVectorDtorIter,
653 IFK::EHVectorCopyCtorIter,
654 IFK::EHVectorVbaseCopyCtorIter,
657 IFK::VectorCopyCtorIter,
658 IFK::VectorVbaseCopyCtorIter,
659 IFK::ManVectorVbaseCopyCtorIter,
680 int Index = (
CH >=
'0' &&
CH <=
'9') ? (
CH -
'0') : (
CH -
'A' + 10);
693Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName,
695 if (MangledName.empty()) {
699 const char CH = MangledName.front();
702 MangledName.remove_prefix(1);
706 return demangleStructorIdentifier(MangledName,
CH ==
'1');
708 return demangleConversionOperatorIdentifier(MangledName);
711 translateIntrinsicFunctionCode(
CH, Group));
714 MangledName.remove_prefix(1);
716 translateIntrinsicFunctionCode(
CH, Group));
718 MangledName.remove_prefix(1);
721 return demangleLiteralOperatorIdentifier(MangledName);
724 translateIntrinsicFunctionCode(
CH, Group));
731SymbolNode *Demangler::demangleEncodedSymbol(std::string_view &MangledName,
733 if (MangledName.empty()) {
739 switch (MangledName.front()) {
746 return demangleVariableEncoding(MangledName, SC);
761SymbolNode *Demangler::demangleDeclarator(std::string_view &MangledName) {
785SymbolNode *Demangler::demangleMD5Name(std::string_view &MangledName) {
786 assert(llvm::itanium_demangle::starts_with(MangledName,
"??@"));
790 size_t MD5Last = MangledName.find(
'@', strlen(
"??@"));
791 if (MD5Last == std::string_view::npos) {
795 const char *Start = &*MangledName.begin();
796 const size_t StartSize = MangledName.size();
797 MangledName.remove_prefix(MD5Last + 1);
811 assert(MangledName.size() < StartSize);
812 const size_t Count = StartSize - MangledName.size();
813 std::string_view
MD5(Start, Count);
820SymbolNode *Demangler::demangleTypeinfoName(std::string_view &MangledName) {
821 assert(llvm::itanium_demangle::starts_with(MangledName,
'.'));
825 if (
Error || !MangledName.empty()) {
837 if (llvm::itanium_demangle::starts_with(MangledName,
'.'))
838 return demangleTypeinfoName(MangledName);
840 if (llvm::itanium_demangle::starts_with(MangledName,
"??@"))
841 return demangleMD5Name(MangledName);
844 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
853 if (
SymbolNode *
SI = demangleSpecialIntrinsic(MangledName))
856 return demangleDeclarator(MangledName);
859TagTypeNode *Demangler::parseTagUniqueName(std::string_view &MangledName) {
865 if (MangledName.empty()) {
870 return demangleClassType(MangledName);
881Demangler::demangleVariableEncoding(std::string_view &MangledName,
899 demanglePointerExtQualifiers(MangledName));
901 bool IsMember =
false;
902 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
906 demangleFullyQualifiedTypeName(MangledName);
914 VSN->
Type->
Quals = demangleQualifiers(MangledName).first;
932std::pair<uint64_t, bool>
933Demangler::demangleNumber(std::string_view &MangledName) {
938 MangledName.remove_prefix(1);
939 return {
Ret, IsNegative};
943 for (
size_t i = 0; i < MangledName.size(); ++i) {
944 char C = MangledName[i];
946 MangledName.remove_prefix(i + 1);
947 return {
Ret, IsNegative};
949 if (
'A' <=
C &&
C <=
'P') {
957 return {0ULL,
false};
960uint64_t Demangler::demangleUnsigned(std::string_view &MangledName) {
961 bool IsNegative =
false;
963 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
969int64_t Demangler::demangleSigned(std::string_view &MangledName) {
970 bool IsNegative =
false;
972 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
975 int64_t
I =
static_cast<int64_t
>(
Number);
976 return IsNegative ? -
I :
I;
981void Demangler::memorizeString(std::string_view S) {
984 for (
size_t i = 0; i < Backrefs.
NamesCount; ++i)
993Demangler::demangleBackRefName(std::string_view &MangledName) {
996 size_t I = MangledName[0] -
'0';
1002 MangledName.remove_prefix(1);
1003 return Backrefs.
Names[
I];
1011 std::string_view Owned = copyString(OB);
1012 memorizeString(Owned);
1013 std::free(
OB.getBuffer());
1017Demangler::demangleTemplateInstantiationName(std::string_view &MangledName,
1019 assert(llvm::itanium_demangle::starts_with(MangledName,
"?$"));
1026 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1028 Identifier->TemplateParams = demangleTemplateParameterList(MangledName);
1051Demangler::demangleSimpleName(std::string_view &MangledName,
bool Memorize) {
1052 std::string_view S = demangleSimpleString(MangledName, Memorize);
1065 return (
C <=
'J') ? (
C -
'A') : (10 +
C -
'K');
1068uint8_t Demangler::demangleCharLiteral(std::string_view &MangledName) {
1069 assert(!MangledName.empty());
1070 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
1071 const uint8_t
F = MangledName.front();
1072 MangledName.remove_prefix(1);
1076 MangledName.remove_prefix(1);
1077 if (MangledName.empty())
1078 goto CharLiteralError;
1082 if (MangledName.size() < 2)
1083 goto CharLiteralError;
1084 std::string_view Nibbles = MangledName.substr(0, 2);
1086 goto CharLiteralError;
1090 MangledName.remove_prefix(2);
1091 return (C1 << 4) | C2;
1095 const char *
Lookup =
",/\\:. \n\t'-";
1096 char C =
Lookup[MangledName[0] -
'0'];
1097 MangledName.remove_prefix(1);
1101 if (MangledName[0] >=
'a' && MangledName[0] <=
'z') {
1102 char Lookup[26] = {
'\xE1',
'\xE2',
'\xE3',
'\xE4',
'\xE5',
'\xE6',
'\xE7',
1103 '\xE8',
'\xE9',
'\xEA',
'\xEB',
'\xEC',
'\xED',
'\xEE',
1104 '\xEF',
'\xF0',
'\xF1',
'\xF2',
'\xF3',
'\xF4',
'\xF5',
1105 '\xF6',
'\xF7',
'\xF8',
'\xF9',
'\xFA'};
1106 char C =
Lookup[MangledName[0] -
'a'];
1107 MangledName.remove_prefix(1);
1111 if (MangledName[0] >=
'A' && MangledName[0] <=
'Z') {
1112 char Lookup[26] = {
'\xC1',
'\xC2',
'\xC3',
'\xC4',
'\xC5',
'\xC6',
'\xC7',
1113 '\xC8',
'\xC9',
'\xCA',
'\xCB',
'\xCC',
'\xCD',
'\xCE',
1114 '\xCF',
'\xD0',
'\xD1',
'\xD2',
'\xD3',
'\xD4',
'\xD5',
1115 '\xD6',
'\xD7',
'\xD8',
'\xD9',
'\xDA'};
1116 char C =
Lookup[MangledName[0] -
'A'];
1117 MangledName.remove_prefix(1);
1126wchar_t Demangler::demangleWcharLiteral(std::string_view &MangledName) {
1129 C1 = demangleCharLiteral(MangledName);
1130 if (
Error || MangledName.empty())
1131 goto WCharLiteralError;
1132 C2 = demangleCharLiteral(MangledName);
1134 goto WCharLiteralError;
1136 return ((
wchar_t)C1 << 8) | (wchar_t)C2;
1145 *Buffer = (Digit < 10) ? (
'0' + Digit) : (
'A' + Digit - 10);
1156 char TempBuffer[17];
1158 ::memset(TempBuffer, 0,
sizeof(TempBuffer));
1159 constexpr int MaxPos =
sizeof(TempBuffer) - 1;
1161 int Pos = MaxPos - 1;
1163 for (
int I = 0;
I < 2; ++
I) {
1168 TempBuffer[Pos--] =
'x';
1170 TempBuffer[Pos--] =
'\\';
1171 OB << std::string_view(&TempBuffer[Pos + 1]);
1213 if (
C > 0x1F &&
C < 0x7F) {
1223 const uint8_t *
End = StringBytes +
Length - 1;
1237 if (*StringBytes++ == 0)
1251 if (NumBytes % 2 == 1)
1257 if (NumBytes < 32) {
1259 if (TrailingNulls >= 4 && NumBytes % 4 == 0)
1261 if (TrailingNulls >= 2)
1273 if (Nulls >= 2 * NumChars / 3 && NumBytes % 4 == 0)
1275 if (Nulls >= NumChars / 3)
1281 unsigned CharIndex,
unsigned CharBytes) {
1282 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1283 unsigned Offset = CharIndex * CharBytes;
1285 StringBytes = StringBytes +
Offset;
1286 for (
unsigned I = 0;
I < CharBytes; ++
I) {
1287 unsigned C =
static_cast<unsigned>(StringBytes[
I]);
1294Demangler::demangleVcallThunkNode(std::string_view &MangledName) {
1300 FSN->
Name = demangleNameScopeChain(MangledName, VTIN);
1304 VTIN->OffsetInVTable = demangleUnsigned(MangledName);
1309 return (
Error) ? nullptr : FSN;
1313Demangler::demangleStringLiteral(std::string_view &MangledName) {
1316 std::string_view CRC;
1318 bool IsWcharT =
false;
1319 bool IsNegative =
false;
1320 size_t CrcEndPos = 0;
1327 goto StringLiteralError;
1328 if (MangledName.empty())
1329 goto StringLiteralError;
1332 F = MangledName.front();
1333 MangledName.remove_prefix(1);
1341 goto StringLiteralError;
1345 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
1346 if (
Error || IsNegative || StringByteSize < (IsWcharT ? 2 : 1))
1347 goto StringLiteralError;
1350 CrcEndPos = MangledName.find(
'@');
1351 if (CrcEndPos == std::string_view::npos)
1352 goto StringLiteralError;
1353 CRC = MangledName.substr(0, CrcEndPos);
1354 MangledName.remove_prefix(CrcEndPos + 1);
1355 if (MangledName.empty())
1356 goto StringLiteralError;
1360 if (StringByteSize > 64)
1361 Result->IsTruncated =
true;
1364 if (MangledName.size() < 2)
1365 goto StringLiteralError;
1366 wchar_t W = demangleWcharLiteral(MangledName);
1367 if (StringByteSize != 2 ||
Result->IsTruncated)
1369 StringByteSize -= 2;
1371 goto StringLiteralError;
1376 constexpr unsigned MaxStringByteLength = 32 * 4;
1377 uint8_t StringBytes[MaxStringByteLength];
1379 unsigned BytesDecoded = 0;
1381 if (MangledName.size() < 1 || BytesDecoded >= MaxStringByteLength)
1382 goto StringLiteralError;
1383 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
1386 if (StringByteSize > BytesDecoded)
1387 Result->IsTruncated =
true;
1389 unsigned CharBytes =
1391 assert(StringByteSize % CharBytes == 0);
1392 switch (CharBytes) {
1405 const unsigned NumChars = BytesDecoded / CharBytes;
1406 for (
unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
1409 if (CharIndex + 1 < NumChars ||
Result->IsTruncated)
1414 Result->DecodedString = copyString(OB);
1415 std::free(
OB.getBuffer());
1420 std::free(
OB.getBuffer());
1426std::string_view Demangler::demangleSimpleString(std::string_view &MangledName,
1429 for (
size_t i = 0; i < MangledName.size(); ++i) {
1430 if (MangledName[i] !=
'@')
1434 S = MangledName.substr(0, i);
1435 MangledName.remove_prefix(i + 1);
1447Demangler::demangleAnonymousNamespaceName(std::string_view &MangledName) {
1448 assert(llvm::itanium_demangle::starts_with(MangledName,
"?A"));
1452 Node->Name =
"`anonymous namespace'";
1453 size_t EndPos = MangledName.find(
'@');
1454 if (EndPos == std::string_view::npos) {
1458 std::string_view NamespaceKey = MangledName.substr(0, EndPos);
1459 memorizeString(NamespaceKey);
1460 MangledName = MangledName.substr(EndPos + 1);
1465Demangler::demangleLocallyScopedNamePiece(std::string_view &MangledName) {
1471 bool IsNegative =
false;
1472 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
1491 std::free(
OB.getBuffer());
1497Demangler::demangleFullyQualifiedTypeName(std::string_view &MangledName) {
1499 demangleUnqualifiedTypeName(MangledName,
true);
1515Demangler::demangleFullyQualifiedSymbolName(std::string_view &MangledName) {
1522 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1545Demangler::demangleUnqualifiedTypeName(std::string_view &MangledName,
1552 return demangleBackRefName(MangledName);
1554 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1555 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1557 return demangleSimpleName(MangledName, Memorize);
1561Demangler::demangleUnqualifiedSymbolName(std::string_view &MangledName,
1564 return demangleBackRefName(MangledName);
1565 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1566 return demangleTemplateInstantiationName(MangledName, NBB);
1567 if (llvm::itanium_demangle::starts_with(MangledName,
'?'))
1568 return demangleFunctionIdentifierCode(MangledName);
1569 return demangleSimpleName(MangledName, (NBB &
NBB_Simple) != 0);
1573Demangler::demangleNameScopePiece(std::string_view &MangledName) {
1575 return demangleBackRefName(MangledName);
1577 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1578 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1580 if (llvm::itanium_demangle::starts_with(MangledName,
"?A"))
1581 return demangleAnonymousNamespaceName(MangledName);
1584 return demangleLocallyScopedNamePiece(MangledName);
1586 return demangleSimpleName(MangledName,
true);
1594 for (
size_t I = 0;
I < Count; ++
I) {
1595 N->Nodes[
I] = Head->
N;
1602Demangler::demangleNameScopeChain(std::string_view &MangledName,
1606 Head->
N = UnqualifiedName;
1612 NewHead->
Next = Head;
1615 if (MangledName.empty()) {
1633FuncClass Demangler::demangleFunctionClass(std::string_view &MangledName) {
1634 const char F = MangledName.front();
1635 MangledName.remove_prefix(1);
1695 if (MangledName.empty())
1697 const char F = MangledName.front();
1698 MangledName.remove_prefix(1);
1721Demangler::demangleCallingConvention(std::string_view &MangledName) {
1722 if (MangledName.empty()) {
1727 const char F = MangledName.front();
1728 MangledName.remove_prefix(1);
1763Demangler::demangleVariableStorageClass(std::string_view &MangledName) {
1764 assert(MangledName.front() >=
'0' && MangledName.front() <=
'4');
1766 const char F = MangledName.front();
1767 MangledName.remove_prefix(1);
1783std::pair<Qualifiers, bool>
1784Demangler::demangleQualifiers(std::string_view &MangledName) {
1785 if (MangledName.empty()) {
1787 return std::make_pair(
Q_None,
false);
1790 const char F = MangledName.front();
1791 MangledName.remove_prefix(1);
1795 return std::make_pair(
Q_None,
true);
1797 return std::make_pair(
Q_Const,
true);
1804 return std::make_pair(
Q_None,
false);
1806 return std::make_pair(
Q_Const,
false);
1813 return std::make_pair(
Q_None,
false);
1818TypeNode *Demangler::demangleType(std::string_view &MangledName,
1823 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1826 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1829 if (MangledName.empty()) {
1836 Ty = demangleClassType(MangledName);
1839 Ty = demangleMemberPointerType(MangledName);
1841 Ty = demanglePointerType(MangledName);
1845 Ty = demangleArrayType(MangledName);
1848 Ty = demangleFunctionType(MangledName,
true);
1850 assert(llvm::itanium_demangle::starts_with(MangledName,
"$$A6"));
1852 Ty = demangleFunctionType(MangledName,
false);
1855 Ty = demangleCustomType(MangledName);
1857 Ty = demanglePrimitiveType(MangledName);
1866bool Demangler::demangleThrowSpecification(std::string_view &MangledName) {
1877Demangler::demangleFunctionType(std::string_view &MangledName,
1878 bool HasThisQuals) {
1882 FTy->
Quals = demanglePointerExtQualifiers(MangledName);
1898 FTy->
IsNoexcept = demangleThrowSpecification(MangledName);
1904Demangler::demangleFunctionEncoding(std::string_view &MangledName) {
1909 if (MangledName.empty()) {
1914 FuncClass FC = demangleFunctionClass(MangledName);
1939 FSN = demangleFunctionType(MangledName, HasThisQuals);
1956CustomTypeNode *Demangler::demangleCustomType(std::string_view &MangledName) {
1957 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
1958 MangledName.remove_prefix(1);
1961 CTN->
Identifier = demangleUnqualifiedTypeName(MangledName,
true);
1971Demangler::demanglePrimitiveType(std::string_view &MangledName) {
1975 const char F = MangledName.front();
1976 MangledName.remove_prefix(1);
2005 if (MangledName.empty()) {
2009 const char F = MangledName.front();
2010 MangledName.remove_prefix(1);
2034TagTypeNode *Demangler::demangleClassType(std::string_view &MangledName) {
2037 const char F = MangledName.front();
2038 MangledName.remove_prefix(1);
2060 TT->QualifiedName = demangleFullyQualifiedTypeName(MangledName);
2066PointerTypeNode *Demangler::demanglePointerType(std::string_view &MangledName) {
2073 Pointer->Pointee = demangleFunctionType(MangledName,
false);
2077 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2085Demangler::demangleMemberPointerType(std::string_view &MangledName) {
2092 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2098 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2099 Pointer->Pointee = demangleFunctionType(MangledName,
true);
2103 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
2105 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2109 Pointer->Pointee->Quals = PointeeQuals;
2116Demangler::demanglePointerExtQualifiers(std::string_view &MangledName) {
2128ArrayTypeNode *Demangler::demangleArrayType(std::string_view &MangledName) {
2129 assert(MangledName.front() ==
'Y');
2130 MangledName.remove_prefix(1);
2133 bool IsNegative =
false;
2134 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2135 if (IsNegative || Rank == 0) {
2146 std::tie(
D, IsNegative) = demangleNumber(MangledName);
2147 if (
Error || IsNegative) {
2161 std::tie(ATy->
Quals, IsMember) = demangleQualifiers(MangledName);
2174Demangler::demangleFunctionParameterList(std::string_view &MangledName,
2183 while (!
Error && !llvm::itanium_demangle::starts_with(MangledName,
'@') &&
2184 !llvm::itanium_demangle::starts_with(MangledName,
'Z')) {
2188 size_t N = MangledName[0] -
'0';
2193 MangledName.remove_prefix(1);
2197 Current = &(*Current)->Next;
2201 size_t OldSize = MangledName.size();
2210 size_t CharsConsumed = OldSize - MangledName.size();
2211 assert(CharsConsumed != 0);
2218 Current = &(*Current)->Next;
2240Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
2245 while (!llvm::itanium_demangle::starts_with(MangledName,
'@')) {
2262 TP.N = demangleFullyQualifiedTypeName(MangledName);
2269 }
else if (llvm::itanium_demangle::starts_with(MangledName,
"$1") ||
2270 llvm::itanium_demangle::starts_with(MangledName,
"$H") ||
2271 llvm::itanium_demangle::starts_with(MangledName,
"$I") ||
2272 llvm::itanium_demangle::starts_with(MangledName,
"$J")) {
2277 MangledName.remove_prefix(1);
2282 char InheritanceSpecifier = MangledName.front();
2283 MangledName.remove_prefix(1);
2285 if (llvm::itanium_demangle::starts_with(MangledName,
'?')) {
2286 S =
parse(MangledName);
2294 switch (InheritanceSpecifier) {
2297 demangleSigned(MangledName);
2301 demangleSigned(MangledName);
2305 demangleSigned(MangledName);
2314 }
else if (llvm::itanium_demangle::starts_with(MangledName,
"$E?")) {
2320 }
else if (llvm::itanium_demangle::starts_with(MangledName,
"$F") ||
2321 llvm::itanium_demangle::starts_with(MangledName,
"$G")) {
2325 MangledName.remove_prefix(1);
2326 char InheritanceSpecifier = MangledName.front();
2327 MangledName.remove_prefix(1);
2329 switch (InheritanceSpecifier) {
2332 demangleSigned(MangledName);
2336 demangleSigned(MangledName);
2338 demangleSigned(MangledName);
2347 bool IsNegative =
false;
2349 std::tie(
Value, IsNegative) = demangleNumber(MangledName);
2366 assert(llvm::itanium_demangle::starts_with(
2372void Demangler::dumpBackReferences() {
2373 std::printf(
"%d function parameter backreferences\n",
2379 OB.setCurrentPosition(0);
2384 std::string_view
B = OB;
2385 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)
B.size(), &*
B.begin());
2387 std::free(OB.getBuffer());
2391 std::printf(
"%d name backreferences\n", (
int)Backrefs.
NamesCount);
2393 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)Backrefs.
Names[
I]->
Name.size(),
2404 std::string_view
Name{MangledName};
2406 if (!
D.Error && NMangled)
2407 *NMangled =
Name.empty() ? 0 : &*
Name.begin() - MangledName;
2410 D.dumpBackReferences();
2432 Buf = OB.getBuffer();
2436 *
Status = InternalStatus;
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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 bool isMemberPointer(std::string_view MangledName, bool &Error)
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 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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isMemberPointer(uint32_t Attrs)
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.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
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.
char * microsoftDemangle(const char *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
@ demangle_invalid_mangled_name
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
QualifiedNameNode * ClassParent
IdentifierNode * getUnqualifiedIdentifier()
NodeArrayNode * Components
QualifiedNameNode * TargetName
void output(OutputBuffer &OB, OutputFlags Flags) const override
std::array< int64_t, 3 > ThunkOffsets