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);
71 const char F = MangledName.front();
72 MangledName.remove_prefix(1);
98 if (MangledName[0] !=
'6' && MangledName[0] !=
'8') {
102 return (MangledName[0] ==
'8');
111 if (MangledName.empty()) {
117 switch (MangledName.front()) {
137 return SpecialIntrinsicKind::Vftable;
139 return SpecialIntrinsicKind::Vbtable;
141 return SpecialIntrinsicKind::VcallThunk;
143 return SpecialIntrinsicKind::Typeof;
145 return SpecialIntrinsicKind::LocalStaticGuard;
147 return SpecialIntrinsicKind::StringLiteralSymbol;
149 return SpecialIntrinsicKind::UdtReturning;
151 return SpecialIntrinsicKind::RttiTypeDescriptor;
153 return SpecialIntrinsicKind::RttiBaseClassDescriptor;
155 return SpecialIntrinsicKind::RttiBaseClassArray;
157 return SpecialIntrinsicKind::RttiClassHierarchyDescriptor;
159 return SpecialIntrinsicKind::RttiCompleteObjLocator;
161 return SpecialIntrinsicKind::LocalVftable;
163 return SpecialIntrinsicKind::DynamicInitializer;
165 return SpecialIntrinsicKind::DynamicAtexitDestructor;
167 return SpecialIntrinsicKind::LocalStaticThreadGuard;
168 return SpecialIntrinsicKind::None;
175 size_t End = S.find(
'?');
176 if (
End == std::string_view::npos)
178 std::string_view Candidate = S.substr(0,
End);
179 if (Candidate.empty())
184 if (Candidate.size() == 1)
185 return Candidate[0] ==
'@' || (Candidate[0] >=
'0' && Candidate[0] <=
'9');
188 if (Candidate.back() !=
'@')
190 Candidate.remove_suffix(1);
198 if (Candidate[0] <
'B' || Candidate[0] >
'P')
200 Candidate.remove_prefix(1);
201 while (!Candidate.empty()) {
202 if (Candidate[0] <
'A' || Candidate[0] >
'P')
204 Candidate.remove_prefix(1);
224 if (llvm::itanium_demangle::starts_with(S,
"$$Q"))
238static bool isArrayType(std::string_view S) {
return S[0] ==
'Y'; }
241 return llvm::itanium_demangle::starts_with(S,
"$$A8@@") ||
242 llvm::itanium_demangle::starts_with(S,
"$$A6");
248 return FunctionRefQualifier::Reference;
250 return FunctionRefQualifier::RValueReference;
251 return FunctionRefQualifier::None;
254static std::pair<Qualifiers, PointerAffinity>
257 return std::make_pair(
Q_None, PointerAffinity::RValueReference);
259 const char F = MangledName.front();
260 MangledName.remove_prefix(1);
263 return std::make_pair(
Q_None, PointerAffinity::Reference);
265 return std::make_pair(
Q_None, PointerAffinity::Pointer);
267 return std::make_pair(
Q_Const, PointerAffinity::Pointer);
269 return std::make_pair(
Q_Volatile, PointerAffinity::Pointer);
272 PointerAffinity::Pointer);
279std::string_view Demangler::copyString(std::string_view Borrowed) {
284 std::memcpy(Stable, Borrowed.data(), Borrowed.size());
286 return {Stable, Borrowed.size()};
290Demangler::demangleSpecialTableSymbolNode(std::string_view &MangledName,
295 NI->
Name =
"`vftable'";
298 NI->
Name =
"`vbtable'";
301 NI->
Name =
"`local vftable'";
304 NI->
Name =
"`RTTI Complete Object Locator'";
313 if (MangledName.empty()) {
317 char Front = MangledName.front();
318 MangledName.remove_prefix(1);
319 if (Front !=
'6' && Front !=
'7') {
324 std::tie(STSN->
Quals, IsMember) = demangleQualifiers(MangledName);
326 STSN->
TargetName = demangleFullyQualifiedTypeName(MangledName);
331Demangler::demangleLocalStaticGuard(std::string_view &MangledName,
350 if (!MangledName.empty())
351 LSGI->
ScopeIndex = demangleUnsigned(MangledName);
356 std::string_view
Name) {
373 std::string_view
Name) {
380 std::string_view VariableName) {
389 std::string_view &MangledName,
390 std::string_view VariableName) {
403Demangler::demangleRttiBaseClassDescriptorNode(
ArenaAllocator &Arena,
404 std::string_view &MangledName) {
407 RBCDN->
NVOffset = demangleUnsigned(MangledName);
410 RBCDN->
Flags = demangleUnsigned(MangledName);
415 VSN->
Name = demangleNameScopeChain(MangledName, RBCDN);
421Demangler::demangleInitFiniStub(std::string_view &MangledName,
427 bool IsKnownStaticDataMember =
false;
429 IsKnownStaticDataMember =
true;
444 int AtCount = IsKnownStaticDataMember ? 2 : 1;
445 for (
int I = 0;
I < AtCount; ++
I) {
452 FSN = demangleFunctionEncoding(MangledName);
456 if (IsKnownStaticDataMember) {
470SymbolNode *Demangler::demangleSpecialIntrinsic(std::string_view &MangledName) {
477 return demangleStringLiteral(MangledName);
482 return demangleSpecialTableSymbolNode(MangledName, SIK);
484 return demangleVcallThunkNode(MangledName);
486 return demangleLocalStaticGuard(MangledName,
false);
488 return demangleLocalStaticGuard(MangledName,
true);
495 if (!MangledName.empty())
500 return demangleUntypedVariable(Arena, MangledName,
501 "`RTTI Base Class Array'");
503 return demangleUntypedVariable(Arena, MangledName,
504 "`RTTI Class Hierarchy Descriptor'");
506 return demangleRttiBaseClassDescriptorNode(Arena, MangledName);
508 return demangleInitFiniStub(MangledName,
false);
510 return demangleInitFiniStub(MangledName,
true);
524Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName) {
525 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
526 MangledName.remove_prefix(1);
527 if (MangledName.empty()) {
533 return demangleFunctionIdentifierCode(
536 return demangleFunctionIdentifierCode(MangledName,
538 return demangleFunctionIdentifierCode(MangledName,
543Demangler::demangleStructorIdentifier(std::string_view &MangledName,
546 N->IsDestructor = IsDestructor;
551Demangler::demangleConversionOperatorIdentifier(std::string_view &MangledName) {
558Demangler::demangleLiteralOperatorIdentifier(std::string_view &MangledName) {
561 N->Name = demangleSimpleString(MangledName,
false);
566Demangler::translateIntrinsicFunctionCode(
char CH,
569 if (!(
CH >=
'0' &&
CH <=
'9') && !(
CH >=
'A' &&
CH <=
'Z')) {
577 static IFK
Basic[36] = {
603 IFK::GreaterThanEqual,
615 static IFK
Under[36] = {
620 IFK::BitwiseAndEqual,
622 IFK::BitwiseXorEqual,
631 IFK::DefaultCtorClosure,
635 IFK::VecVbaseCtorIter,
639 IFK::EHVecVbaseCtorIter,
640 IFK::CopyCtorClosure,
645 IFK::LocalVftableCtorClosure,
664 IFK::ManVectorCtorIter,
665 IFK::ManVectorDtorIter,
666 IFK::EHVectorCopyCtorIter,
667 IFK::EHVectorVbaseCopyCtorIter,
670 IFK::VectorCopyCtorIter,
671 IFK::VectorVbaseCopyCtorIter,
672 IFK::ManVectorVbaseCopyCtorIter,
693 int Index = (
CH >=
'0' &&
CH <=
'9') ? (
CH -
'0') : (
CH -
'A' + 10);
706Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName,
708 if (MangledName.empty()) {
712 const char CH = MangledName.front();
715 MangledName.remove_prefix(1);
719 return demangleStructorIdentifier(MangledName,
CH ==
'1');
721 return demangleConversionOperatorIdentifier(MangledName);
724 translateIntrinsicFunctionCode(
CH, Group));
727 MangledName.remove_prefix(1);
729 translateIntrinsicFunctionCode(
CH, Group));
731 MangledName.remove_prefix(1);
734 return demangleLiteralOperatorIdentifier(MangledName);
737 translateIntrinsicFunctionCode(
CH, Group));
744SymbolNode *Demangler::demangleEncodedSymbol(std::string_view &MangledName,
746 if (MangledName.empty()) {
752 switch (MangledName.front()) {
759 return demangleVariableEncoding(MangledName, SC);
774SymbolNode *Demangler::demangleDeclarator(std::string_view &MangledName) {
798SymbolNode *Demangler::demangleMD5Name(std::string_view &MangledName) {
799 assert(llvm::itanium_demangle::starts_with(MangledName,
"??@"));
803 size_t MD5Last = MangledName.find(
'@', strlen(
"??@"));
804 if (MD5Last == std::string_view::npos) {
808 const char *Start = MangledName.data();
809 const size_t StartSize = MangledName.size();
810 MangledName.remove_prefix(MD5Last + 1);
824 assert(MangledName.size() < StartSize);
825 const size_t Count = StartSize - MangledName.size();
826 std::string_view
MD5(Start, Count);
833SymbolNode *Demangler::demangleTypeinfoName(std::string_view &MangledName) {
834 assert(llvm::itanium_demangle::starts_with(MangledName,
'.'));
838 if (
Error || !MangledName.empty()) {
850 if (llvm::itanium_demangle::starts_with(MangledName,
'.'))
851 return demangleTypeinfoName(MangledName);
853 if (llvm::itanium_demangle::starts_with(MangledName,
"??@"))
854 return demangleMD5Name(MangledName);
857 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
866 if (
SymbolNode *SI = demangleSpecialIntrinsic(MangledName))
869 return demangleDeclarator(MangledName);
872TagTypeNode *Demangler::parseTagUniqueName(std::string_view &MangledName) {
878 if (MangledName.empty()) {
883 return demangleClassType(MangledName);
894Demangler::demangleVariableEncoding(std::string_view &MangledName,
912 demanglePointerExtQualifiers(MangledName));
914 bool IsMember =
false;
915 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
919 demangleFullyQualifiedTypeName(MangledName);
927 VSN->
Type->
Quals = demangleQualifiers(MangledName).first;
945std::pair<uint64_t, bool>
946Demangler::demangleNumber(std::string_view &MangledName) {
951 MangledName.remove_prefix(1);
952 return {
Ret, IsNegative};
956 for (
size_t i = 0; i < MangledName.size(); ++i) {
957 char C = MangledName[i];
959 MangledName.remove_prefix(i + 1);
960 return {
Ret, IsNegative};
962 if (
'A' <=
C &&
C <=
'P') {
970 return {0ULL,
false};
973uint64_t Demangler::demangleUnsigned(std::string_view &MangledName) {
974 bool IsNegative =
false;
976 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
982int64_t Demangler::demangleSigned(std::string_view &MangledName) {
983 bool IsNegative =
false;
985 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
988 int64_t
I =
static_cast<int64_t
>(
Number);
989 return IsNegative ? -
I :
I;
994void Demangler::memorizeString(std::string_view S) {
997 for (
size_t i = 0; i < Backrefs.
NamesCount; ++i)
1006Demangler::demangleBackRefName(std::string_view &MangledName) {
1009 size_t I = MangledName[0] -
'0';
1015 MangledName.remove_prefix(1);
1016 return Backrefs.
Names[
I];
1024 std::string_view Owned = copyString(OB);
1025 memorizeString(Owned);
1026 std::free(
OB.getBuffer());
1030Demangler::demangleTemplateInstantiationName(std::string_view &MangledName,
1032 assert(llvm::itanium_demangle::starts_with(MangledName,
"?$"));
1039 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1041 Identifier->TemplateParams = demangleTemplateParameterList(MangledName);
1064Demangler::demangleSimpleName(std::string_view &MangledName,
bool Memorize) {
1065 std::string_view S = demangleSimpleString(MangledName, Memorize);
1078 return (
C <=
'J') ? (
C -
'A') : (10 +
C -
'K');
1081uint8_t Demangler::demangleCharLiteral(std::string_view &MangledName) {
1082 assert(!MangledName.empty());
1083 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
1084 const uint8_t F = MangledName.front();
1085 MangledName.remove_prefix(1);
1089 MangledName.remove_prefix(1);
1090 if (MangledName.empty())
1091 goto CharLiteralError;
1095 if (MangledName.size() < 2)
1096 goto CharLiteralError;
1097 std::string_view Nibbles = MangledName.substr(0, 2);
1099 goto CharLiteralError;
1103 MangledName.remove_prefix(2);
1104 return (C1 << 4) | C2;
1108 const char *
Lookup =
",/\\:. \n\t'-";
1109 char C =
Lookup[MangledName[0] -
'0'];
1110 MangledName.remove_prefix(1);
1114 if (MangledName[0] >=
'a' && MangledName[0] <=
'z') {
1115 char Lookup[26] = {
'\xE1',
'\xE2',
'\xE3',
'\xE4',
'\xE5',
'\xE6',
'\xE7',
1116 '\xE8',
'\xE9',
'\xEA',
'\xEB',
'\xEC',
'\xED',
'\xEE',
1117 '\xEF',
'\xF0',
'\xF1',
'\xF2',
'\xF3',
'\xF4',
'\xF5',
1118 '\xF6',
'\xF7',
'\xF8',
'\xF9',
'\xFA'};
1119 char C =
Lookup[MangledName[0] -
'a'];
1120 MangledName.remove_prefix(1);
1124 if (MangledName[0] >=
'A' && MangledName[0] <=
'Z') {
1125 char Lookup[26] = {
'\xC1',
'\xC2',
'\xC3',
'\xC4',
'\xC5',
'\xC6',
'\xC7',
1126 '\xC8',
'\xC9',
'\xCA',
'\xCB',
'\xCC',
'\xCD',
'\xCE',
1127 '\xCF',
'\xD0',
'\xD1',
'\xD2',
'\xD3',
'\xD4',
'\xD5',
1128 '\xD6',
'\xD7',
'\xD8',
'\xD9',
'\xDA'};
1129 char C =
Lookup[MangledName[0] -
'A'];
1130 MangledName.remove_prefix(1);
1139wchar_t Demangler::demangleWcharLiteral(std::string_view &MangledName) {
1142 C1 = demangleCharLiteral(MangledName);
1143 if (
Error || MangledName.empty())
1144 goto WCharLiteralError;
1145 C2 = demangleCharLiteral(MangledName);
1147 goto WCharLiteralError;
1149 return ((
wchar_t)C1 << 8) | (wchar_t)C2;
1158 *Buffer = (Digit < 10) ? (
'0' + Digit) : (
'A' + Digit - 10);
1169 char TempBuffer[17];
1171 ::memset(TempBuffer, 0,
sizeof(TempBuffer));
1172 constexpr int MaxPos =
sizeof(TempBuffer) - 1;
1174 int Pos = MaxPos - 1;
1176 for (
int I = 0;
I < 2; ++
I) {
1181 TempBuffer[Pos--] =
'x';
1183 TempBuffer[Pos--] =
'\\';
1184 OB << std::string_view(&TempBuffer[Pos + 1]);
1226 if (
C > 0x1F &&
C < 0x7F) {
1250 if (*StringBytes++ == 0)
1264 if (NumBytes % 2 == 1)
1270 if (NumBytes < 32) {
1272 if (TrailingNulls >= 4 && NumBytes % 4 == 0)
1274 if (TrailingNulls >= 2)
1286 if (Nulls >= 2 * NumChars / 3 && NumBytes % 4 == 0)
1288 if (Nulls >= NumChars / 3)
1294 unsigned CharIndex,
unsigned CharBytes) {
1295 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1296 unsigned Offset = CharIndex * CharBytes;
1298 StringBytes = StringBytes +
Offset;
1299 for (
unsigned I = 0;
I < CharBytes; ++
I) {
1300 unsigned C =
static_cast<unsigned>(StringBytes[
I]);
1307Demangler::demangleVcallThunkNode(std::string_view &MangledName) {
1313 FSN->
Name = demangleNameScopeChain(MangledName, VTIN);
1317 VTIN->OffsetInVTable = demangleUnsigned(MangledName);
1322 return (
Error) ? nullptr : FSN;
1326Demangler::demangleStringLiteral(std::string_view &MangledName) {
1329 std::string_view CRC;
1331 bool IsWcharT =
false;
1332 bool IsNegative =
false;
1333 size_t CrcEndPos = 0;
1340 goto StringLiteralError;
1341 if (MangledName.empty())
1342 goto StringLiteralError;
1345 F = MangledName.front();
1346 MangledName.remove_prefix(1);
1354 goto StringLiteralError;
1358 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
1359 if (
Error || IsNegative || StringByteSize < (IsWcharT ? 2 : 1))
1360 goto StringLiteralError;
1363 CrcEndPos = MangledName.find(
'@');
1364 if (CrcEndPos == std::string_view::npos)
1365 goto StringLiteralError;
1366 CRC = MangledName.substr(0, CrcEndPos);
1367 MangledName.remove_prefix(CrcEndPos + 1);
1368 if (MangledName.empty())
1369 goto StringLiteralError;
1373 if (StringByteSize > 64)
1374 Result->IsTruncated =
true;
1377 if (MangledName.size() < 2)
1378 goto StringLiteralError;
1379 wchar_t W = demangleWcharLiteral(MangledName);
1380 if (StringByteSize != 2 ||
Result->IsTruncated)
1382 StringByteSize -= 2;
1384 goto StringLiteralError;
1389 constexpr unsigned MaxStringByteLength = 32 * 4;
1390 uint8_t StringBytes[MaxStringByteLength];
1392 unsigned BytesDecoded = 0;
1394 if (MangledName.size() < 1 || BytesDecoded >= MaxStringByteLength)
1395 goto StringLiteralError;
1396 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
1399 if (StringByteSize > BytesDecoded)
1400 Result->IsTruncated =
true;
1402 unsigned CharBytes =
1404 assert(StringByteSize % CharBytes == 0);
1405 switch (CharBytes) {
1418 const unsigned NumChars = BytesDecoded / CharBytes;
1419 for (
unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
1422 if (CharIndex + 1 < NumChars ||
Result->IsTruncated)
1427 Result->DecodedString = copyString(OB);
1428 std::free(
OB.getBuffer());
1433 std::free(
OB.getBuffer());
1439std::string_view Demangler::demangleSimpleString(std::string_view &MangledName,
1442 for (
size_t i = 0; i < MangledName.size(); ++i) {
1443 if (MangledName[i] !=
'@')
1447 S = MangledName.substr(0, i);
1448 MangledName.remove_prefix(i + 1);
1460Demangler::demangleAnonymousNamespaceName(std::string_view &MangledName) {
1461 assert(llvm::itanium_demangle::starts_with(MangledName,
"?A"));
1465 Node->Name =
"`anonymous namespace'";
1466 size_t EndPos = MangledName.find(
'@');
1467 if (EndPos == std::string_view::npos) {
1471 std::string_view NamespaceKey = MangledName.substr(0, EndPos);
1472 memorizeString(NamespaceKey);
1473 MangledName = MangledName.substr(EndPos + 1);
1478Demangler::demangleLocallyScopedNamePiece(std::string_view &MangledName) {
1484 bool IsNegative =
false;
1485 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
1504 std::free(
OB.getBuffer());
1510Demangler::demangleFullyQualifiedTypeName(std::string_view &MangledName) {
1512 demangleUnqualifiedTypeName(MangledName,
true);
1528Demangler::demangleFullyQualifiedSymbolName(std::string_view &MangledName) {
1535 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1558Demangler::demangleUnqualifiedTypeName(std::string_view &MangledName,
1565 return demangleBackRefName(MangledName);
1567 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1568 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1570 return demangleSimpleName(MangledName, Memorize);
1574Demangler::demangleUnqualifiedSymbolName(std::string_view &MangledName,
1577 return demangleBackRefName(MangledName);
1578 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1579 return demangleTemplateInstantiationName(MangledName, NBB);
1580 if (llvm::itanium_demangle::starts_with(MangledName,
'?'))
1581 return demangleFunctionIdentifierCode(MangledName);
1582 return demangleSimpleName(MangledName, (NBB &
NBB_Simple) != 0);
1586Demangler::demangleNameScopePiece(std::string_view &MangledName) {
1588 return demangleBackRefName(MangledName);
1590 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1591 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1593 if (llvm::itanium_demangle::starts_with(MangledName,
"?A"))
1594 return demangleAnonymousNamespaceName(MangledName);
1597 return demangleLocallyScopedNamePiece(MangledName);
1599 return demangleSimpleName(MangledName,
true);
1607 for (
size_t I = 0;
I < Count; ++
I) {
1608 N->Nodes[
I] = Head->
N;
1615Demangler::demangleNameScopeChain(std::string_view &MangledName,
1619 Head->
N = UnqualifiedName;
1625 NewHead->
Next = Head;
1628 if (MangledName.empty()) {
1646FuncClass Demangler::demangleFunctionClass(std::string_view &MangledName) {
1647 const char F = MangledName.front();
1648 MangledName.remove_prefix(1);
1708 if (MangledName.empty())
1710 const char F = MangledName.front();
1711 MangledName.remove_prefix(1);
1734Demangler::demangleCallingConvention(std::string_view &MangledName) {
1735 if (MangledName.empty()) {
1740 const char F = MangledName.front();
1741 MangledName.remove_prefix(1);
1776Demangler::demangleVariableStorageClass(std::string_view &MangledName) {
1777 assert(MangledName.front() >=
'0' && MangledName.front() <=
'4');
1779 const char F = MangledName.front();
1780 MangledName.remove_prefix(1);
1796std::pair<Qualifiers, bool>
1797Demangler::demangleQualifiers(std::string_view &MangledName) {
1798 if (MangledName.empty()) {
1800 return std::make_pair(
Q_None,
false);
1803 const char F = MangledName.front();
1804 MangledName.remove_prefix(1);
1808 return std::make_pair(
Q_None,
true);
1810 return std::make_pair(
Q_Const,
true);
1817 return std::make_pair(
Q_None,
false);
1819 return std::make_pair(
Q_Const,
false);
1826 return std::make_pair(
Q_None,
false);
1831TypeNode *Demangler::demangleType(std::string_view &MangledName,
1836 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1839 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1842 if (MangledName.empty()) {
1849 Ty = demangleClassType(MangledName);
1852 Ty = demangleMemberPointerType(MangledName);
1854 Ty = demanglePointerType(MangledName);
1858 Ty = demangleArrayType(MangledName);
1861 Ty = demangleFunctionType(MangledName,
true);
1863 assert(llvm::itanium_demangle::starts_with(MangledName,
"$$A6"));
1865 Ty = demangleFunctionType(MangledName,
false);
1868 Ty = demangleCustomType(MangledName);
1870 Ty = demanglePrimitiveType(MangledName);
1879bool Demangler::demangleThrowSpecification(std::string_view &MangledName) {
1890Demangler::demangleFunctionType(std::string_view &MangledName,
1891 bool HasThisQuals) {
1895 FTy->
Quals = demanglePointerExtQualifiers(MangledName);
1911 FTy->
IsNoexcept = demangleThrowSpecification(MangledName);
1917Demangler::demangleFunctionEncoding(std::string_view &MangledName) {
1922 if (MangledName.empty()) {
1927 FuncClass FC = demangleFunctionClass(MangledName);
1952 FSN = demangleFunctionType(MangledName, HasThisQuals);
1969CustomTypeNode *Demangler::demangleCustomType(std::string_view &MangledName) {
1970 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
1971 MangledName.remove_prefix(1);
1974 CTN->
Identifier = demangleUnqualifiedTypeName(MangledName,
true);
1984Demangler::demanglePrimitiveType(std::string_view &MangledName) {
1988 const char F = MangledName.front();
1989 MangledName.remove_prefix(1);
2018 if (MangledName.empty()) {
2022 const char F = MangledName.front();
2023 MangledName.remove_prefix(1);
2051TagTypeNode *Demangler::demangleClassType(std::string_view &MangledName) {
2054 const char F = MangledName.front();
2055 MangledName.remove_prefix(1);
2077 TT->QualifiedName = demangleFullyQualifiedTypeName(MangledName);
2083PointerTypeNode *Demangler::demanglePointerType(std::string_view &MangledName) {
2090 Pointer->Pointee = demangleFunctionType(MangledName,
false);
2094 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2102Demangler::demangleMemberPointerType(std::string_view &MangledName) {
2109 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2115 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2116 Pointer->Pointee = demangleFunctionType(MangledName,
true);
2120 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
2122 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2126 Pointer->Pointee->Quals = PointeeQuals;
2133Demangler::demanglePointerExtQualifiers(std::string_view &MangledName) {
2145ArrayTypeNode *Demangler::demangleArrayType(std::string_view &MangledName) {
2146 assert(MangledName.front() ==
'Y');
2147 MangledName.remove_prefix(1);
2150 bool IsNegative =
false;
2151 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2152 if (IsNegative || Rank == 0) {
2163 std::tie(
D, IsNegative) = demangleNumber(MangledName);
2164 if (
Error || IsNegative) {
2178 std::tie(ATy->
Quals, IsMember) = demangleQualifiers(MangledName);
2191Demangler::demangleFunctionParameterList(std::string_view &MangledName,
2200 while (!
Error && !llvm::itanium_demangle::starts_with(MangledName,
'@') &&
2201 !llvm::itanium_demangle::starts_with(MangledName,
'Z')) {
2205 size_t N = MangledName[0] -
'0';
2210 MangledName.remove_prefix(1);
2214 Current = &(*Current)->Next;
2218 size_t OldSize = MangledName.size();
2227 size_t CharsConsumed = OldSize - MangledName.size();
2228 assert(CharsConsumed != 0);
2235 Current = &(*Current)->Next;
2257Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
2262 while (!llvm::itanium_demangle::starts_with(MangledName,
'@')) {
2277 const bool IsAutoNTTP =
consumeFront(MangledName,
"$M");
2291 TP.N = demangleFullyQualifiedTypeName(MangledName);
2298 }
else if (
startsWith(MangledName,
"$1",
"1", !IsAutoNTTP) ||
2299 startsWith(MangledName,
"$H",
"H", !IsAutoNTTP) ||
2300 startsWith(MangledName,
"$I",
"I", !IsAutoNTTP) ||
2301 startsWith(MangledName,
"$J",
"J", !IsAutoNTTP)) {
2307 MangledName.remove_prefix(1);
2313 char InheritanceSpecifier = MangledName.front();
2314 MangledName.remove_prefix(1);
2316 if (llvm::itanium_demangle::starts_with(MangledName,
'?')) {
2317 S =
parse(MangledName);
2325 switch (InheritanceSpecifier) {
2328 demangleSigned(MangledName);
2332 demangleSigned(MangledName);
2336 demangleSigned(MangledName);
2345 }
else if (llvm::itanium_demangle::starts_with(MangledName,
"$E?")) {
2351 }
else if (
startsWith(MangledName,
"$F",
"F", !IsAutoNTTP) ||
2352 startsWith(MangledName,
"$G",
"G", !IsAutoNTTP)) {
2357 MangledName.remove_prefix(1);
2358 char InheritanceSpecifier = MangledName.front();
2359 MangledName.remove_prefix(1);
2361 switch (InheritanceSpecifier) {
2364 demangleSigned(MangledName);
2368 demangleSigned(MangledName);
2370 demangleSigned(MangledName);
2377 }
else if (
consumeFront(MangledName,
"$0",
"0", !IsAutoNTTP)) {
2379 bool IsNegative =
false;
2381 std::tie(
Value, IsNegative) = demangleNumber(MangledName);
2398 assert(llvm::itanium_demangle::starts_with(
2404void Demangler::dumpBackReferences() {
2405 std::printf(
"%d function parameter backreferences\n",
2411 OB.setCurrentPosition(0);
2416 std::string_view
B = OB;
2417 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)
B.size(),
B.data());
2419 std::free(OB.getBuffer());
2423 std::printf(
"%d name backreferences\n", (
int)Backrefs.
NamesCount);
2425 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)Backrefs.
Names[
I]->
Name.size(),
2432std::optional<size_t>
2434 std::string_view ProcessedName{MangledName};
2438 return std::nullopt;
2443 D.demangleFullyQualifiedSymbolName(ProcessedName);
2445 return std::nullopt;
2447 return MangledName.length() - ProcessedName.length();
2454 std::string_view
Name{MangledName};
2456 if (!
D.Error && NMangled)
2457 *NMangled = MangledName.size() -
Name.size();
2460 D.dumpBackReferences();
2482 Buf = OB.getBuffer();
2486 *
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
std::optional< size_t > getArm64ECInsertionPointInMangledName(std::string_view MangledName)
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