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());
56static bool consumeFront(std::string_view &S, std::string_view PrefixA,
57 std::string_view PrefixB,
bool A) {
58 const std::string_view &Prefix =
A ? PrefixA : PrefixB;
62static bool startsWith(std::string_view S, std::string_view PrefixA,
63 std::string_view PrefixB,
bool A) {
64 const std::string_view &Prefix =
A ? PrefixA : PrefixB;
65 return llvm::itanium_demangle::starts_with(S, Prefix);
70 const char F = MangledName.front();
71 MangledName.remove_prefix(1);
97 if (MangledName[0] !=
'6' && MangledName[0] !=
'8') {
101 return (MangledName[0] ==
'8');
110 if (MangledName.empty()) {
116 switch (MangledName.front()) {
136 return SpecialIntrinsicKind::Vftable;
138 return SpecialIntrinsicKind::Vbtable;
140 return SpecialIntrinsicKind::VcallThunk;
142 return SpecialIntrinsicKind::Typeof;
144 return SpecialIntrinsicKind::LocalStaticGuard;
146 return SpecialIntrinsicKind::StringLiteralSymbol;
148 return SpecialIntrinsicKind::UdtReturning;
150 return SpecialIntrinsicKind::RttiTypeDescriptor;
152 return SpecialIntrinsicKind::RttiBaseClassDescriptor;
154 return SpecialIntrinsicKind::RttiBaseClassArray;
156 return SpecialIntrinsicKind::RttiClassHierarchyDescriptor;
158 return SpecialIntrinsicKind::RttiCompleteObjLocator;
160 return SpecialIntrinsicKind::LocalVftable;
162 return SpecialIntrinsicKind::DynamicInitializer;
164 return SpecialIntrinsicKind::DynamicAtexitDestructor;
166 return SpecialIntrinsicKind::LocalStaticThreadGuard;
167 return SpecialIntrinsicKind::None;
174 size_t End = S.find(
'?');
175 if (
End == std::string_view::npos)
177 std::string_view Candidate = S.substr(0,
End);
178 if (Candidate.empty())
183 if (Candidate.size() == 1)
184 return Candidate[0] ==
'@' || (Candidate[0] >=
'0' && Candidate[0] <=
'9');
187 if (Candidate.back() !=
'@')
189 Candidate.remove_suffix(1);
197 if (Candidate[0] <
'B' || Candidate[0] >
'P')
199 Candidate.remove_prefix(1);
200 while (!Candidate.empty()) {
201 if (Candidate[0] <
'A' || Candidate[0] >
'P')
203 Candidate.remove_prefix(1);
223 if (llvm::itanium_demangle::starts_with(S,
"$$Q"))
237static bool isArrayType(std::string_view S) {
return S[0] ==
'Y'; }
240 return llvm::itanium_demangle::starts_with(S,
"$$A8@@") ||
241 llvm::itanium_demangle::starts_with(S,
"$$A6");
247 return FunctionRefQualifier::Reference;
249 return FunctionRefQualifier::RValueReference;
250 return FunctionRefQualifier::None;
253static std::pair<Qualifiers, PointerAffinity>
256 return std::make_pair(
Q_None, PointerAffinity::RValueReference);
258 const char F = MangledName.front();
259 MangledName.remove_prefix(1);
262 return std::make_pair(
Q_None, PointerAffinity::Reference);
264 return std::make_pair(
Q_None, PointerAffinity::Pointer);
266 return std::make_pair(
Q_Const, PointerAffinity::Pointer);
268 return std::make_pair(
Q_Volatile, PointerAffinity::Pointer);
271 PointerAffinity::Pointer);
278std::string_view Demangler::copyString(std::string_view Borrowed) {
283 std::memcpy(Stable, Borrowed.data(), Borrowed.size());
285 return {Stable, Borrowed.size()};
289Demangler::demangleSpecialTableSymbolNode(std::string_view &MangledName,
294 NI->
Name =
"`vftable'";
297 NI->
Name =
"`vbtable'";
300 NI->
Name =
"`local vftable'";
303 NI->
Name =
"`RTTI Complete Object Locator'";
312 if (MangledName.empty()) {
316 char Front = MangledName.front();
317 MangledName.remove_prefix(1);
318 if (Front !=
'6' && Front !=
'7') {
323 std::tie(STSN->
Quals, IsMember) = demangleQualifiers(MangledName);
325 STSN->
TargetName = demangleFullyQualifiedTypeName(MangledName);
330Demangler::demangleLocalStaticGuard(std::string_view &MangledName,
349 if (!MangledName.empty())
350 LSGI->
ScopeIndex = demangleUnsigned(MangledName);
355 std::string_view
Name) {
372 std::string_view
Name) {
379 std::string_view VariableName) {
388 std::string_view &MangledName,
389 std::string_view VariableName) {
402Demangler::demangleRttiBaseClassDescriptorNode(
ArenaAllocator &Arena,
403 std::string_view &MangledName) {
406 RBCDN->
NVOffset = demangleUnsigned(MangledName);
409 RBCDN->
Flags = demangleUnsigned(MangledName);
414 VSN->
Name = demangleNameScopeChain(MangledName, RBCDN);
420Demangler::demangleInitFiniStub(std::string_view &MangledName,
426 bool IsKnownStaticDataMember =
false;
428 IsKnownStaticDataMember =
true;
443 int AtCount = IsKnownStaticDataMember ? 2 : 1;
444 for (
int I = 0;
I < AtCount; ++
I) {
451 FSN = demangleFunctionEncoding(MangledName);
455 if (IsKnownStaticDataMember) {
469SymbolNode *Demangler::demangleSpecialIntrinsic(std::string_view &MangledName) {
476 return demangleStringLiteral(MangledName);
481 return demangleSpecialTableSymbolNode(MangledName, SIK);
483 return demangleVcallThunkNode(MangledName);
485 return demangleLocalStaticGuard(MangledName,
false);
487 return demangleLocalStaticGuard(MangledName,
true);
494 if (!MangledName.empty())
499 return demangleUntypedVariable(Arena, MangledName,
500 "`RTTI Base Class Array'");
502 return demangleUntypedVariable(Arena, MangledName,
503 "`RTTI Class Hierarchy Descriptor'");
505 return demangleRttiBaseClassDescriptorNode(Arena, MangledName);
507 return demangleInitFiniStub(MangledName,
false);
509 return demangleInitFiniStub(MangledName,
true);
523Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName) {
524 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
525 MangledName.remove_prefix(1);
526 if (MangledName.empty()) {
532 return demangleFunctionIdentifierCode(
535 return demangleFunctionIdentifierCode(MangledName,
537 return demangleFunctionIdentifierCode(MangledName,
542Demangler::demangleStructorIdentifier(std::string_view &MangledName,
545 N->IsDestructor = IsDestructor;
550Demangler::demangleConversionOperatorIdentifier(std::string_view &MangledName) {
557Demangler::demangleLiteralOperatorIdentifier(std::string_view &MangledName) {
560 N->Name = demangleSimpleString(MangledName,
false);
565Demangler::translateIntrinsicFunctionCode(
char CH,
568 if (!(
CH >=
'0' &&
CH <=
'9') && !(
CH >=
'A' &&
CH <=
'Z')) {
576 static IFK
Basic[36] = {
602 IFK::GreaterThanEqual,
614 static IFK
Under[36] = {
619 IFK::BitwiseAndEqual,
621 IFK::BitwiseXorEqual,
630 IFK::DefaultCtorClosure,
634 IFK::VecVbaseCtorIter,
638 IFK::EHVecVbaseCtorIter,
639 IFK::CopyCtorClosure,
644 IFK::LocalVftableCtorClosure,
663 IFK::ManVectorCtorIter,
664 IFK::ManVectorDtorIter,
665 IFK::EHVectorCopyCtorIter,
666 IFK::EHVectorVbaseCopyCtorIter,
669 IFK::VectorCopyCtorIter,
670 IFK::VectorVbaseCopyCtorIter,
671 IFK::ManVectorVbaseCopyCtorIter,
692 int Index = (
CH >=
'0' &&
CH <=
'9') ? (
CH -
'0') : (
CH -
'A' + 10);
705Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName,
707 if (MangledName.empty()) {
711 const char CH = MangledName.front();
714 MangledName.remove_prefix(1);
718 return demangleStructorIdentifier(MangledName,
CH ==
'1');
720 return demangleConversionOperatorIdentifier(MangledName);
723 translateIntrinsicFunctionCode(
CH, Group));
726 MangledName.remove_prefix(1);
728 translateIntrinsicFunctionCode(
CH, Group));
730 MangledName.remove_prefix(1);
733 return demangleLiteralOperatorIdentifier(MangledName);
736 translateIntrinsicFunctionCode(
CH, Group));
743SymbolNode *Demangler::demangleEncodedSymbol(std::string_view &MangledName,
745 if (MangledName.empty()) {
751 switch (MangledName.front()) {
758 return demangleVariableEncoding(MangledName, SC);
773SymbolNode *Demangler::demangleDeclarator(std::string_view &MangledName) {
797SymbolNode *Demangler::demangleMD5Name(std::string_view &MangledName) {
798 assert(llvm::itanium_demangle::starts_with(MangledName,
"??@"));
802 size_t MD5Last = MangledName.find(
'@', strlen(
"??@"));
803 if (MD5Last == std::string_view::npos) {
807 const char *Start = MangledName.data();
808 const size_t StartSize = MangledName.size();
809 MangledName.remove_prefix(MD5Last + 1);
823 assert(MangledName.size() < StartSize);
824 const size_t Count = StartSize - MangledName.size();
825 std::string_view
MD5(Start, Count);
832SymbolNode *Demangler::demangleTypeinfoName(std::string_view &MangledName) {
833 assert(llvm::itanium_demangle::starts_with(MangledName,
'.'));
837 if (
Error || !MangledName.empty()) {
849 if (llvm::itanium_demangle::starts_with(MangledName,
'.'))
850 return demangleTypeinfoName(MangledName);
852 if (llvm::itanium_demangle::starts_with(MangledName,
"??@"))
853 return demangleMD5Name(MangledName);
856 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
865 if (
SymbolNode *SI = demangleSpecialIntrinsic(MangledName))
868 return demangleDeclarator(MangledName);
871TagTypeNode *Demangler::parseTagUniqueName(std::string_view &MangledName) {
877 if (MangledName.empty()) {
882 return demangleClassType(MangledName);
893Demangler::demangleVariableEncoding(std::string_view &MangledName,
911 demanglePointerExtQualifiers(MangledName));
913 bool IsMember =
false;
914 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
918 demangleFullyQualifiedTypeName(MangledName);
926 VSN->
Type->
Quals = demangleQualifiers(MangledName).first;
944std::pair<uint64_t, bool>
945Demangler::demangleNumber(std::string_view &MangledName) {
950 MangledName.remove_prefix(1);
951 return {
Ret, IsNegative};
955 for (
size_t i = 0; i < MangledName.size(); ++i) {
956 char C = MangledName[i];
958 MangledName.remove_prefix(i + 1);
959 return {
Ret, IsNegative};
961 if (
'A' <=
C &&
C <=
'P') {
969 return {0ULL,
false};
972uint64_t Demangler::demangleUnsigned(std::string_view &MangledName) {
973 bool IsNegative =
false;
975 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
981int64_t Demangler::demangleSigned(std::string_view &MangledName) {
982 bool IsNegative =
false;
984 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
987 int64_t
I =
static_cast<int64_t
>(
Number);
988 return IsNegative ? -
I :
I;
993void Demangler::memorizeString(std::string_view S) {
996 for (
size_t i = 0; i < Backrefs.
NamesCount; ++i)
1005Demangler::demangleBackRefName(std::string_view &MangledName) {
1008 size_t I = MangledName[0] -
'0';
1014 MangledName.remove_prefix(1);
1015 return Backrefs.
Names[
I];
1023 std::string_view Owned = copyString(OB);
1024 memorizeString(Owned);
1025 std::free(
OB.getBuffer());
1029Demangler::demangleTemplateInstantiationName(std::string_view &MangledName,
1031 assert(llvm::itanium_demangle::starts_with(MangledName,
"?$"));
1038 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1040 Identifier->TemplateParams = demangleTemplateParameterList(MangledName);
1063Demangler::demangleSimpleName(std::string_view &MangledName,
bool Memorize) {
1064 std::string_view S = demangleSimpleString(MangledName, Memorize);
1077 return (
C <=
'J') ? (
C -
'A') : (10 +
C -
'K');
1080uint8_t Demangler::demangleCharLiteral(std::string_view &MangledName) {
1081 assert(!MangledName.empty());
1082 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
1083 const uint8_t
F = MangledName.front();
1084 MangledName.remove_prefix(1);
1088 MangledName.remove_prefix(1);
1089 if (MangledName.empty())
1090 goto CharLiteralError;
1094 if (MangledName.size() < 2)
1095 goto CharLiteralError;
1096 std::string_view Nibbles = MangledName.substr(0, 2);
1098 goto CharLiteralError;
1102 MangledName.remove_prefix(2);
1103 return (C1 << 4) | C2;
1107 const char *
Lookup =
",/\\:. \n\t'-";
1108 char C =
Lookup[MangledName[0] -
'0'];
1109 MangledName.remove_prefix(1);
1113 if (MangledName[0] >=
'a' && MangledName[0] <=
'z') {
1114 char Lookup[26] = {
'\xE1',
'\xE2',
'\xE3',
'\xE4',
'\xE5',
'\xE6',
'\xE7',
1115 '\xE8',
'\xE9',
'\xEA',
'\xEB',
'\xEC',
'\xED',
'\xEE',
1116 '\xEF',
'\xF0',
'\xF1',
'\xF2',
'\xF3',
'\xF4',
'\xF5',
1117 '\xF6',
'\xF7',
'\xF8',
'\xF9',
'\xFA'};
1118 char C =
Lookup[MangledName[0] -
'a'];
1119 MangledName.remove_prefix(1);
1123 if (MangledName[0] >=
'A' && MangledName[0] <=
'Z') {
1124 char Lookup[26] = {
'\xC1',
'\xC2',
'\xC3',
'\xC4',
'\xC5',
'\xC6',
'\xC7',
1125 '\xC8',
'\xC9',
'\xCA',
'\xCB',
'\xCC',
'\xCD',
'\xCE',
1126 '\xCF',
'\xD0',
'\xD1',
'\xD2',
'\xD3',
'\xD4',
'\xD5',
1127 '\xD6',
'\xD7',
'\xD8',
'\xD9',
'\xDA'};
1128 char C =
Lookup[MangledName[0] -
'A'];
1129 MangledName.remove_prefix(1);
1138wchar_t Demangler::demangleWcharLiteral(std::string_view &MangledName) {
1141 C1 = demangleCharLiteral(MangledName);
1142 if (
Error || MangledName.empty())
1143 goto WCharLiteralError;
1144 C2 = demangleCharLiteral(MangledName);
1146 goto WCharLiteralError;
1148 return ((
wchar_t)C1 << 8) | (wchar_t)C2;
1157 *Buffer = (Digit < 10) ? (
'0' + Digit) : (
'A' + Digit - 10);
1168 char TempBuffer[17];
1170 ::memset(TempBuffer, 0,
sizeof(TempBuffer));
1171 constexpr int MaxPos =
sizeof(TempBuffer) - 1;
1173 int Pos = MaxPos - 1;
1175 for (
int I = 0;
I < 2; ++
I) {
1180 TempBuffer[Pos--] =
'x';
1182 TempBuffer[Pos--] =
'\\';
1183 OB << std::string_view(&TempBuffer[Pos + 1]);
1225 if (
C > 0x1F &&
C < 0x7F) {
1235 const uint8_t *
End = StringBytes +
Length - 1;
1249 if (*StringBytes++ == 0)
1263 if (NumBytes % 2 == 1)
1269 if (NumBytes < 32) {
1271 if (TrailingNulls >= 4 && NumBytes % 4 == 0)
1273 if (TrailingNulls >= 2)
1285 if (Nulls >= 2 * NumChars / 3 && NumBytes % 4 == 0)
1287 if (Nulls >= NumChars / 3)
1293 unsigned CharIndex,
unsigned CharBytes) {
1294 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1295 unsigned Offset = CharIndex * CharBytes;
1297 StringBytes = StringBytes +
Offset;
1298 for (
unsigned I = 0;
I < CharBytes; ++
I) {
1299 unsigned C =
static_cast<unsigned>(StringBytes[
I]);
1306Demangler::demangleVcallThunkNode(std::string_view &MangledName) {
1312 FSN->
Name = demangleNameScopeChain(MangledName, VTIN);
1316 VTIN->OffsetInVTable = demangleUnsigned(MangledName);
1321 return (
Error) ? nullptr : FSN;
1325Demangler::demangleStringLiteral(std::string_view &MangledName) {
1328 std::string_view CRC;
1330 bool IsWcharT =
false;
1331 bool IsNegative =
false;
1332 size_t CrcEndPos = 0;
1339 goto StringLiteralError;
1340 if (MangledName.empty())
1341 goto StringLiteralError;
1344 F = MangledName.front();
1345 MangledName.remove_prefix(1);
1353 goto StringLiteralError;
1357 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
1358 if (
Error || IsNegative || StringByteSize < (IsWcharT ? 2 : 1))
1359 goto StringLiteralError;
1362 CrcEndPos = MangledName.find(
'@');
1363 if (CrcEndPos == std::string_view::npos)
1364 goto StringLiteralError;
1365 CRC = MangledName.substr(0, CrcEndPos);
1366 MangledName.remove_prefix(CrcEndPos + 1);
1367 if (MangledName.empty())
1368 goto StringLiteralError;
1372 if (StringByteSize > 64)
1373 Result->IsTruncated =
true;
1376 if (MangledName.size() < 2)
1377 goto StringLiteralError;
1378 wchar_t W = demangleWcharLiteral(MangledName);
1379 if (StringByteSize != 2 ||
Result->IsTruncated)
1381 StringByteSize -= 2;
1383 goto StringLiteralError;
1388 constexpr unsigned MaxStringByteLength = 32 * 4;
1389 uint8_t StringBytes[MaxStringByteLength];
1391 unsigned BytesDecoded = 0;
1393 if (MangledName.size() < 1 || BytesDecoded >= MaxStringByteLength)
1394 goto StringLiteralError;
1395 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
1398 if (StringByteSize > BytesDecoded)
1399 Result->IsTruncated =
true;
1401 unsigned CharBytes =
1403 assert(StringByteSize % CharBytes == 0);
1404 switch (CharBytes) {
1417 const unsigned NumChars = BytesDecoded / CharBytes;
1418 for (
unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
1421 if (CharIndex + 1 < NumChars ||
Result->IsTruncated)
1426 Result->DecodedString = copyString(OB);
1427 std::free(
OB.getBuffer());
1432 std::free(
OB.getBuffer());
1438std::string_view Demangler::demangleSimpleString(std::string_view &MangledName,
1441 for (
size_t i = 0; i < MangledName.size(); ++i) {
1442 if (MangledName[i] !=
'@')
1446 S = MangledName.substr(0, i);
1447 MangledName.remove_prefix(i + 1);
1459Demangler::demangleAnonymousNamespaceName(std::string_view &MangledName) {
1460 assert(llvm::itanium_demangle::starts_with(MangledName,
"?A"));
1464 Node->Name =
"`anonymous namespace'";
1465 size_t EndPos = MangledName.find(
'@');
1466 if (EndPos == std::string_view::npos) {
1470 std::string_view NamespaceKey = MangledName.substr(0, EndPos);
1471 memorizeString(NamespaceKey);
1472 MangledName = MangledName.substr(EndPos + 1);
1477Demangler::demangleLocallyScopedNamePiece(std::string_view &MangledName) {
1483 bool IsNegative =
false;
1484 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
1503 std::free(
OB.getBuffer());
1509Demangler::demangleFullyQualifiedTypeName(std::string_view &MangledName) {
1511 demangleUnqualifiedTypeName(MangledName,
true);
1527Demangler::demangleFullyQualifiedSymbolName(std::string_view &MangledName) {
1534 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1557Demangler::demangleUnqualifiedTypeName(std::string_view &MangledName,
1564 return demangleBackRefName(MangledName);
1566 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1567 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1569 return demangleSimpleName(MangledName, Memorize);
1573Demangler::demangleUnqualifiedSymbolName(std::string_view &MangledName,
1576 return demangleBackRefName(MangledName);
1577 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1578 return demangleTemplateInstantiationName(MangledName, NBB);
1579 if (llvm::itanium_demangle::starts_with(MangledName,
'?'))
1580 return demangleFunctionIdentifierCode(MangledName);
1581 return demangleSimpleName(MangledName, (NBB &
NBB_Simple) != 0);
1585Demangler::demangleNameScopePiece(std::string_view &MangledName) {
1587 return demangleBackRefName(MangledName);
1589 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1590 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1592 if (llvm::itanium_demangle::starts_with(MangledName,
"?A"))
1593 return demangleAnonymousNamespaceName(MangledName);
1596 return demangleLocallyScopedNamePiece(MangledName);
1598 return demangleSimpleName(MangledName,
true);
1606 for (
size_t I = 0;
I < Count; ++
I) {
1607 N->Nodes[
I] = Head->
N;
1614Demangler::demangleNameScopeChain(std::string_view &MangledName,
1618 Head->
N = UnqualifiedName;
1624 NewHead->
Next = Head;
1627 if (MangledName.empty()) {
1645FuncClass Demangler::demangleFunctionClass(std::string_view &MangledName) {
1646 const char F = MangledName.front();
1647 MangledName.remove_prefix(1);
1707 if (MangledName.empty())
1709 const char F = MangledName.front();
1710 MangledName.remove_prefix(1);
1733Demangler::demangleCallingConvention(std::string_view &MangledName) {
1734 if (MangledName.empty()) {
1739 const char F = MangledName.front();
1740 MangledName.remove_prefix(1);
1775Demangler::demangleVariableStorageClass(std::string_view &MangledName) {
1776 assert(MangledName.front() >=
'0' && MangledName.front() <=
'4');
1778 const char F = MangledName.front();
1779 MangledName.remove_prefix(1);
1795std::pair<Qualifiers, bool>
1796Demangler::demangleQualifiers(std::string_view &MangledName) {
1797 if (MangledName.empty()) {
1799 return std::make_pair(
Q_None,
false);
1802 const char F = MangledName.front();
1803 MangledName.remove_prefix(1);
1807 return std::make_pair(
Q_None,
true);
1809 return std::make_pair(
Q_Const,
true);
1816 return std::make_pair(
Q_None,
false);
1818 return std::make_pair(
Q_Const,
false);
1825 return std::make_pair(
Q_None,
false);
1830TypeNode *Demangler::demangleType(std::string_view &MangledName,
1835 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1838 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1841 if (MangledName.empty()) {
1848 Ty = demangleClassType(MangledName);
1851 Ty = demangleMemberPointerType(MangledName);
1853 Ty = demanglePointerType(MangledName);
1857 Ty = demangleArrayType(MangledName);
1860 Ty = demangleFunctionType(MangledName,
true);
1862 assert(llvm::itanium_demangle::starts_with(MangledName,
"$$A6"));
1864 Ty = demangleFunctionType(MangledName,
false);
1867 Ty = demangleCustomType(MangledName);
1869 Ty = demanglePrimitiveType(MangledName);
1878bool Demangler::demangleThrowSpecification(std::string_view &MangledName) {
1889Demangler::demangleFunctionType(std::string_view &MangledName,
1890 bool HasThisQuals) {
1894 FTy->
Quals = demanglePointerExtQualifiers(MangledName);
1910 FTy->
IsNoexcept = demangleThrowSpecification(MangledName);
1916Demangler::demangleFunctionEncoding(std::string_view &MangledName) {
1921 if (MangledName.empty()) {
1926 FuncClass FC = demangleFunctionClass(MangledName);
1951 FSN = demangleFunctionType(MangledName, HasThisQuals);
1968CustomTypeNode *Demangler::demangleCustomType(std::string_view &MangledName) {
1969 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
1970 MangledName.remove_prefix(1);
1973 CTN->
Identifier = demangleUnqualifiedTypeName(MangledName,
true);
1983Demangler::demanglePrimitiveType(std::string_view &MangledName) {
1987 const char F = MangledName.front();
1988 MangledName.remove_prefix(1);
2017 if (MangledName.empty()) {
2021 const char F = MangledName.front();
2022 MangledName.remove_prefix(1);
2046TagTypeNode *Demangler::demangleClassType(std::string_view &MangledName) {
2049 const char F = MangledName.front();
2050 MangledName.remove_prefix(1);
2072 TT->QualifiedName = demangleFullyQualifiedTypeName(MangledName);
2078PointerTypeNode *Demangler::demanglePointerType(std::string_view &MangledName) {
2085 Pointer->Pointee = demangleFunctionType(MangledName,
false);
2089 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2097Demangler::demangleMemberPointerType(std::string_view &MangledName) {
2104 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2110 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2111 Pointer->Pointee = demangleFunctionType(MangledName,
true);
2115 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
2117 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2121 Pointer->Pointee->Quals = PointeeQuals;
2128Demangler::demanglePointerExtQualifiers(std::string_view &MangledName) {
2140ArrayTypeNode *Demangler::demangleArrayType(std::string_view &MangledName) {
2141 assert(MangledName.front() ==
'Y');
2142 MangledName.remove_prefix(1);
2145 bool IsNegative =
false;
2146 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2147 if (IsNegative || Rank == 0) {
2158 std::tie(
D, IsNegative) = demangleNumber(MangledName);
2159 if (
Error || IsNegative) {
2173 std::tie(ATy->
Quals, IsMember) = demangleQualifiers(MangledName);
2186Demangler::demangleFunctionParameterList(std::string_view &MangledName,
2195 while (!
Error && !llvm::itanium_demangle::starts_with(MangledName,
'@') &&
2196 !llvm::itanium_demangle::starts_with(MangledName,
'Z')) {
2200 size_t N = MangledName[0] -
'0';
2205 MangledName.remove_prefix(1);
2209 Current = &(*Current)->Next;
2213 size_t OldSize = MangledName.size();
2222 size_t CharsConsumed = OldSize - MangledName.size();
2223 assert(CharsConsumed != 0);
2230 Current = &(*Current)->Next;
2252Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
2257 while (!llvm::itanium_demangle::starts_with(MangledName,
'@')) {
2272 const bool IsAutoNTTP =
consumeFront(MangledName,
"$M");
2286 TP.N = demangleFullyQualifiedTypeName(MangledName);
2293 }
else if (
startsWith(MangledName,
"$1",
"1", !IsAutoNTTP) ||
2294 startsWith(MangledName,
"$H",
"H", !IsAutoNTTP) ||
2295 startsWith(MangledName,
"$I",
"I", !IsAutoNTTP) ||
2296 startsWith(MangledName,
"$J",
"J", !IsAutoNTTP)) {
2302 MangledName.remove_prefix(1);
2308 char InheritanceSpecifier = MangledName.front();
2309 MangledName.remove_prefix(1);
2311 if (llvm::itanium_demangle::starts_with(MangledName,
'?')) {
2312 S =
parse(MangledName);
2320 switch (InheritanceSpecifier) {
2323 demangleSigned(MangledName);
2327 demangleSigned(MangledName);
2331 demangleSigned(MangledName);
2340 }
else if (llvm::itanium_demangle::starts_with(MangledName,
"$E?")) {
2346 }
else if (
startsWith(MangledName,
"$F",
"F", !IsAutoNTTP) ||
2347 startsWith(MangledName,
"$G",
"G", !IsAutoNTTP)) {
2352 MangledName.remove_prefix(1);
2353 char InheritanceSpecifier = MangledName.front();
2354 MangledName.remove_prefix(1);
2356 switch (InheritanceSpecifier) {
2359 demangleSigned(MangledName);
2363 demangleSigned(MangledName);
2365 demangleSigned(MangledName);
2372 }
else if (
consumeFront(MangledName,
"$0",
"0", !IsAutoNTTP)) {
2374 bool IsNegative =
false;
2376 std::tie(
Value, IsNegative) = demangleNumber(MangledName);
2393 assert(llvm::itanium_demangle::starts_with(
2399void Demangler::dumpBackReferences() {
2400 std::printf(
"%d function parameter backreferences\n",
2406 OB.setCurrentPosition(0);
2411 std::string_view
B = OB;
2412 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)
B.size(),
B.data());
2414 std::free(OB.getBuffer());
2418 std::printf(
"%d name backreferences\n", (
int)Backrefs.
NamesCount);
2420 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)Backrefs.
Names[
I]->
Name.size(),
2431 std::string_view
Name{MangledName};
2433 if (!
D.Error && NMangled)
2434 *NMangled = MangledName.size() -
Name.size();
2437 D.dumpBackReferences();
2459 Buf = OB.getBuffer();
2463 *
Status = InternalStatus;
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 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 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)
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.
@ 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_invalid_mangled_name
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
QualifiedNameNode * ClassParent
IdentifierNode * getUnqualifiedIdentifier()
NodeArrayNode * Components
QualifiedNameNode * TargetName
void output(OutputBuffer &OB, OutputFlags Flags) const override
std::array< int64_t, 3 > ThunkOffsets