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);
68bool Demangler::isMemberPointer(std::string_view MangledName,
bool &
Error) {
70 const char F = MangledName.front();
71 MangledName.remove_prefix(1);
97 if (MangledName[0] !=
'6' && MangledName[0] !=
'8') {
101 return (MangledName[0] ==
'8');
109 demanglePointerAuthQualifier(MangledName);
111 if (MangledName.empty()) {
117 switch (MangledName.front()) {
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");
254static std::pair<Qualifiers, PointerAffinity>
259 const char F = MangledName.front();
260 MangledName.remove_prefix(1);
284 for (
size_t I = 0;
I <
Count; ++
I) {
285 N->Nodes[
I] = Head->
N;
291std::string_view Demangler::copyString(std::string_view Borrowed) {
296 std::memcpy(Stable, Borrowed.data(), Borrowed.size());
298 return {Stable, Borrowed.size()};
302Demangler::demangleSpecialTableSymbolNode(std::string_view &MangledName,
304 NamedIdentifierNode *NI = Arena.
alloc<NamedIdentifierNode>();
307 NI->
Name =
"`vftable'";
310 NI->
Name =
"`vbtable'";
313 NI->
Name =
"`local vftable'";
316 NI->
Name =
"`RTTI Complete Object Locator'";
321 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI);
322 SpecialTableSymbolNode *STSN = Arena.
alloc<SpecialTableSymbolNode>();
325 if (MangledName.empty()) {
329 char Front = MangledName.front();
330 MangledName.remove_prefix(1);
331 if (Front !=
'6' && Front !=
'7') {
336 std::tie(STSN->
Quals, IsMember) = demangleQualifiers(MangledName);
350 TargetCurrent =
Next;
351 QualifiedNameNode *QN = demangleFullyQualifiedTypeName(MangledName);
355 TargetCurrent->
N = QN;
365Demangler::demangleLocalStaticGuard(std::string_view &MangledName,
367 LocalStaticGuardIdentifierNode *LSGI =
368 Arena.
alloc<LocalStaticGuardIdentifierNode>();
370 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, LSGI);
371 LocalStaticGuardVariableNode *LSGVN =
372 Arena.
alloc<LocalStaticGuardVariableNode>();
384 if (!MangledName.empty())
385 LSGI->
ScopeIndex = demangleUnsigned(MangledName);
390 std::string_view Name) {
407 std::string_view Name) {
413 std::string_view Description) {
422 std::string_view &MangledName,
423 std::string_view VariableName) {
425 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI);
426 VariableSymbolNode *VSN = Arena.
alloc<VariableSymbolNode>();
436Demangler::demangleRttiBaseClassDescriptorNode(
ArenaAllocator &Arena,
437 std::string_view &MangledName) {
438 RttiBaseClassDescriptorNode *RBCDN =
439 Arena.
alloc<RttiBaseClassDescriptorNode>();
440 RBCDN->
NVOffset = demangleUnsigned(MangledName);
443 RBCDN->
Flags = demangleUnsigned(MangledName);
447 VariableSymbolNode *VSN = Arena.
alloc<VariableSymbolNode>();
448 VSN->
Name = demangleNameScopeChain(MangledName, RBCDN);
454Demangler::demangleInitFiniStub(std::string_view &MangledName,
456 DynamicStructorIdentifierNode *DSIN =
457 Arena.
alloc<DynamicStructorIdentifierNode>();
460 bool IsKnownStaticDataMember =
false;
462 IsKnownStaticDataMember =
true;
464 SymbolNode *
Symbol = demangleDeclarator(MangledName);
468 FunctionSymbolNode *FSN =
nullptr;
477 int AtCount = IsKnownStaticDataMember ? 2 : 1;
478 for (
int I = 0;
I < AtCount; ++
I) {
485 FSN = demangleFunctionEncoding(MangledName);
489 if (IsKnownStaticDataMember) {
495 FSN =
static_cast<FunctionSymbolNode *
>(
Symbol);
503SymbolNode *Demangler::demangleSpecialIntrinsic(std::string_view &MangledName) {
510 return demangleStringLiteral(MangledName);
515 return demangleSpecialTableSymbolNode(MangledName, SIK);
517 return demangleVcallThunkNode(MangledName);
519 return demangleLocalStaticGuard(MangledName,
false);
521 return demangleLocalStaticGuard(MangledName,
true);
528 if (!MangledName.empty())
533 return demangleUntypedVariable(Arena, MangledName,
534 "`RTTI Base Class Array'");
536 return demangleUntypedVariable(Arena, MangledName,
537 "`RTTI Class Hierarchy Descriptor'");
539 return demangleRttiBaseClassDescriptorNode(Arena, MangledName);
541 return demangleInitFiniStub(MangledName,
false);
543 return demangleInitFiniStub(MangledName,
true);
557Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName) {
558 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
559 MangledName.remove_prefix(1);
560 if (MangledName.empty()) {
566 return demangleFunctionIdentifierCode(
569 return demangleFunctionIdentifierCode(MangledName,
571 return demangleFunctionIdentifierCode(MangledName,
576Demangler::demangleStructorIdentifier(std::string_view &MangledName,
578 StructorIdentifierNode *
N = Arena.
alloc<StructorIdentifierNode>();
579 N->IsDestructor = IsDestructor;
584Demangler::demangleConversionOperatorIdentifier(std::string_view &MangledName) {
585 ConversionOperatorIdentifierNode *
N =
586 Arena.
alloc<ConversionOperatorIdentifierNode>();
591Demangler::demangleLiteralOperatorIdentifier(std::string_view &MangledName) {
592 LiteralOperatorIdentifierNode *
N =
593 Arena.
alloc<LiteralOperatorIdentifierNode>();
594 N->Name = demangleSimpleString(MangledName,
false);
599Demangler::translateIntrinsicFunctionCode(
char CH,
602 if (!(
CH >=
'0' &&
CH <=
'9') && !(
CH >=
'A' &&
CH <=
'Z')) {
610 static IFK
Basic[36] = {
636 IFK::GreaterThanEqual,
648 static IFK
Under[36] = {
653 IFK::BitwiseAndEqual,
655 IFK::BitwiseXorEqual,
664 IFK::DefaultCtorClosure,
668 IFK::VecVbaseCtorIter,
672 IFK::EHVecVbaseCtorIter,
673 IFK::CopyCtorClosure,
678 IFK::LocalVftableCtorClosure,
697 IFK::ManVectorCtorIter,
698 IFK::ManVectorDtorIter,
699 IFK::EHVectorCopyCtorIter,
700 IFK::EHVectorVbaseCopyCtorIter,
703 IFK::VectorCopyCtorIter,
704 IFK::VectorVbaseCopyCtorIter,
705 IFK::ManVectorVbaseCopyCtorIter,
726 int Index = (
CH >=
'0' &&
CH <=
'9') ? (
CH -
'0') : (
CH -
'A' + 10);
739Demangler::demangleFunctionIdentifierCode(std::string_view &MangledName,
741 if (MangledName.empty()) {
745 const char CH = MangledName.front();
748 MangledName.remove_prefix(1);
752 return demangleStructorIdentifier(MangledName,
CH ==
'1');
754 return demangleConversionOperatorIdentifier(MangledName);
756 return Arena.
alloc<IntrinsicFunctionIdentifierNode>(
757 translateIntrinsicFunctionCode(
CH, Group));
760 MangledName.remove_prefix(1);
761 return Arena.
alloc<IntrinsicFunctionIdentifierNode>(
762 translateIntrinsicFunctionCode(
CH, Group));
764 MangledName.remove_prefix(1);
767 return demangleLiteralOperatorIdentifier(MangledName);
769 return Arena.
alloc<IntrinsicFunctionIdentifierNode>(
770 translateIntrinsicFunctionCode(
CH, Group));
777SymbolNode *Demangler::demangleEncodedSymbol(std::string_view &MangledName,
779 if (MangledName.empty()) {
785 switch (MangledName.front()) {
791 StorageClass SC = demangleVariableStorageClass(MangledName);
792 return demangleVariableEncoding(MangledName, SC);
795 FunctionSymbolNode *FSN = demangleFunctionEncoding(MangledName);
797 IdentifierNode *UQN =
Name->getUnqualifiedIdentifier();
799 ConversionOperatorIdentifierNode *COIN =
800 static_cast<ConversionOperatorIdentifierNode *
>(UQN);
807SymbolNode *Demangler::demangleDeclarator(std::string_view &MangledName) {
810 QualifiedNameNode *QN = demangleFullyQualifiedSymbolName(MangledName);
814 SymbolNode *
Symbol = demangleEncodedSymbol(MangledName, QN);
821 ConversionOperatorIdentifierNode *COIN =
822 static_cast<ConversionOperatorIdentifierNode *
>(UQN);
831SymbolNode *Demangler::demangleMD5Name(std::string_view &MangledName) {
832 assert(llvm::itanium_demangle::starts_with(MangledName,
"??@"));
836 size_t MD5Last = MangledName.find(
'@', strlen(
"??@"));
837 if (MD5Last == std::string_view::npos) {
841 const char *
Start = MangledName.data();
842 const size_t StartSize = MangledName.size();
843 MangledName.remove_prefix(MD5Last + 1);
857 assert(MangledName.size() < StartSize);
858 const size_t Count = StartSize - MangledName.size();
866SymbolNode *Demangler::demangleTypeinfoName(std::string_view &MangledName) {
867 assert(llvm::itanium_demangle::starts_with(MangledName,
'.'));
871 if (
Error || !MangledName.empty()) {
883 if (llvm::itanium_demangle::starts_with(MangledName,
'.'))
884 return demangleTypeinfoName(MangledName);
886 if (llvm::itanium_demangle::starts_with(MangledName,
"??@"))
887 return demangleMD5Name(MangledName);
890 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
899 if (
SymbolNode *
SI = demangleSpecialIntrinsic(MangledName))
902 return demangleDeclarator(MangledName);
905TagTypeNode *Demangler::parseTagUniqueName(std::string_view &MangledName) {
911 if (MangledName.empty()) {
916 return demangleClassType(MangledName);
927Demangler::demangleVariableEncoding(std::string_view &MangledName,
945 demanglePointerExtQualifiers(MangledName));
947 bool IsMember =
false;
948 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
952 demangleFullyQualifiedTypeName(MangledName);
960 VSN->
Type->
Quals = demangleQualifiers(MangledName).first;
978std::pair<uint64_t, bool>
979Demangler::demangleNumber(std::string_view &MangledName) {
983 uint64_t Ret = MangledName[0] -
'0' + 1;
984 MangledName.remove_prefix(1);
985 return {Ret, IsNegative};
989 for (
size_t i = 0; i < MangledName.size(); ++i) {
990 char C = MangledName[i];
992 MangledName.remove_prefix(i + 1);
993 return {Ret, IsNegative};
995 if (
'A' <=
C &&
C <=
'P') {
996 Ret = (Ret << 4) + (
C -
'A');
1003 return {0ULL,
false};
1006uint64_t Demangler::demangleUnsigned(std::string_view &MangledName) {
1007 bool IsNegative =
false;
1009 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
1015int64_t Demangler::demangleSigned(std::string_view &MangledName) {
1016 bool IsNegative =
false;
1018 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
1021 int64_t
I =
static_cast<int64_t
>(
Number);
1022 return IsNegative ? -
I :
I;
1027void Demangler::memorizeString(std::string_view S) {
1030 for (
size_t i = 0; i < Backrefs.
NamesCount; ++i)
1033 NamedIdentifierNode *
N = Arena.
alloc<NamedIdentifierNode>();
1039Demangler::demangleBackRefName(std::string_view &MangledName) {
1042 size_t I = MangledName[0] -
'0';
1048 MangledName.remove_prefix(1);
1049 return Backrefs.
Names[
I];
1057 std::string_view Owned = copyString(OB);
1058 memorizeString(Owned);
1059 std::free(
OB.getBuffer());
1063Demangler::demangleTemplateInstantiationName(std::string_view &MangledName,
1065 assert(llvm::itanium_demangle::starts_with(MangledName,
"?$"));
1068 BackrefContext OuterContext;
1072 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1074 Identifier->TemplateParams = demangleTemplateParameterList(MangledName);
1090 memorizeIdentifier(Identifier);
1097Demangler::demangleSimpleName(std::string_view &MangledName,
bool Memorize) {
1098 std::string_view S = demangleSimpleString(MangledName, Memorize);
1102 NamedIdentifierNode *
Name = Arena.
alloc<NamedIdentifierNode>();
1111 return (
C <=
'J') ? (
C -
'A') : (10 +
C -
'K');
1114uint8_t Demangler::demangleCharLiteral(std::string_view &MangledName) {
1115 assert(!MangledName.empty());
1116 if (!llvm::itanium_demangle::starts_with(MangledName,
'?')) {
1117 const uint8_t
F = MangledName.front();
1118 MangledName.remove_prefix(1);
1122 MangledName.remove_prefix(1);
1123 if (MangledName.empty())
1124 goto CharLiteralError;
1128 if (MangledName.size() < 2)
1129 goto CharLiteralError;
1130 std::string_view Nibbles = MangledName.substr(0, 2);
1132 goto CharLiteralError;
1136 MangledName.remove_prefix(2);
1137 return (C1 << 4) | C2;
1141 const char *
Lookup =
",/\\:. \n\t'-";
1142 char C =
Lookup[MangledName[0] -
'0'];
1143 MangledName.remove_prefix(1);
1147 if (MangledName[0] >=
'a' && MangledName[0] <=
'z') {
1148 char Lookup[26] = {
'\xE1',
'\xE2',
'\xE3',
'\xE4',
'\xE5',
'\xE6',
'\xE7',
1149 '\xE8',
'\xE9',
'\xEA',
'\xEB',
'\xEC',
'\xED',
'\xEE',
1150 '\xEF',
'\xF0',
'\xF1',
'\xF2',
'\xF3',
'\xF4',
'\xF5',
1151 '\xF6',
'\xF7',
'\xF8',
'\xF9',
'\xFA'};
1152 char C =
Lookup[MangledName[0] -
'a'];
1153 MangledName.remove_prefix(1);
1157 if (MangledName[0] >=
'A' && MangledName[0] <=
'Z') {
1158 char Lookup[26] = {
'\xC1',
'\xC2',
'\xC3',
'\xC4',
'\xC5',
'\xC6',
'\xC7',
1159 '\xC8',
'\xC9',
'\xCA',
'\xCB',
'\xCC',
'\xCD',
'\xCE',
1160 '\xCF',
'\xD0',
'\xD1',
'\xD2',
'\xD3',
'\xD4',
'\xD5',
1161 '\xD6',
'\xD7',
'\xD8',
'\xD9',
'\xDA'};
1162 char C =
Lookup[MangledName[0] -
'A'];
1163 MangledName.remove_prefix(1);
1172wchar_t Demangler::demangleWcharLiteral(std::string_view &MangledName) {
1175 C1 = demangleCharLiteral(MangledName);
1176 if (
Error || MangledName.empty())
1177 goto WCharLiteralError;
1178 C2 = demangleCharLiteral(MangledName);
1180 goto WCharLiteralError;
1182 return ((
wchar_t)C1 << 8) | (wchar_t)C2;
1191 *Buffer = (Digit < 10) ? (
'0' + Digit) : (
'A' + Digit - 10);
1202 char TempBuffer[17];
1204 ::memset(TempBuffer, 0,
sizeof(TempBuffer));
1205 constexpr int MaxPos =
sizeof(TempBuffer) - 1;
1207 int Pos = MaxPos - 1;
1209 for (
int I = 0;
I < 2; ++
I) {
1214 TempBuffer[Pos--] =
'x';
1216 TempBuffer[Pos--] =
'\\';
1217 OB << std::string_view(&TempBuffer[Pos + 1]);
1259 if (
C > 0x1F &&
C < 0x7F) {
1271 while (
Length > 0 && *End == 0) {
1283 if (*StringBytes++ == 0)
1297 if (NumBytes % 2 == 1)
1303 if (NumBytes < 32) {
1305 if (TrailingNulls >= 4 && NumBytes % 4 == 0)
1307 if (TrailingNulls >= 2)
1319 if (Nulls >= 2 * NumChars / 3 && NumBytes % 4 == 0)
1321 if (Nulls >= NumChars / 3)
1327 unsigned CharIndex,
unsigned CharBytes) {
1328 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1329 unsigned Offset = CharIndex * CharBytes;
1331 StringBytes = StringBytes +
Offset;
1332 for (
unsigned I = 0;
I < CharBytes; ++
I) {
1333 unsigned C =
static_cast<unsigned>(StringBytes[
I]);
1340Demangler::demangleVcallThunkNode(std::string_view &MangledName) {
1341 FunctionSymbolNode *FSN = Arena.
alloc<FunctionSymbolNode>();
1342 VcallThunkIdentifierNode *VTIN = Arena.
alloc<VcallThunkIdentifierNode>();
1346 FSN->
Name = demangleNameScopeChain(MangledName, VTIN);
1350 VTIN->OffsetInVTable = demangleUnsigned(MangledName);
1355 return (
Error) ? nullptr : FSN;
1359Demangler::demangleStringLiteral(std::string_view &MangledName) {
1362 std::string_view CRC;
1363 uint64_t StringByteSize;
1364 bool IsWcharT =
false;
1365 bool IsNegative =
false;
1366 size_t CrcEndPos = 0;
1369 EncodedStringLiteralNode *
Result = Arena.
alloc<EncodedStringLiteralNode>();
1373 goto StringLiteralError;
1374 if (MangledName.empty())
1375 goto StringLiteralError;
1378 F = MangledName.front();
1379 MangledName.remove_prefix(1);
1387 goto StringLiteralError;
1391 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
1392 if (
Error || IsNegative || StringByteSize < (IsWcharT ? 2 : 1))
1393 goto StringLiteralError;
1396 CrcEndPos = MangledName.find(
'@');
1397 if (CrcEndPos == std::string_view::npos)
1398 goto StringLiteralError;
1399 CRC = MangledName.substr(0, CrcEndPos);
1400 MangledName.remove_prefix(CrcEndPos + 1);
1401 if (MangledName.empty())
1402 goto StringLiteralError;
1406 if (StringByteSize > 64)
1407 Result->IsTruncated =
true;
1411 if (StringByteSize % 2 != 0)
1412 goto StringLiteralError;
1413 if (StringByteSize == 0)
1414 goto StringLiteralError;
1415 if (MangledName.size() < 2)
1416 goto StringLiteralError;
1417 wchar_t W = demangleWcharLiteral(MangledName);
1418 if (StringByteSize != 2 ||
Result->IsTruncated)
1420 StringByteSize -= 2;
1422 goto StringLiteralError;
1427 constexpr unsigned MaxStringByteLength = 32 * 4;
1428 uint8_t StringBytes[MaxStringByteLength];
1430 unsigned BytesDecoded = 0;
1432 if (MangledName.size() < 1 || BytesDecoded >= MaxStringByteLength)
1433 goto StringLiteralError;
1434 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
1437 if (StringByteSize > BytesDecoded)
1438 Result->IsTruncated =
true;
1440 unsigned CharBytes =
1442 assert(StringByteSize % CharBytes == 0);
1443 switch (CharBytes) {
1456 const unsigned NumChars = BytesDecoded / CharBytes;
1457 for (
unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
1460 if (CharIndex + 1 < NumChars ||
Result->IsTruncated)
1465 Result->DecodedString = copyString(OB);
1466 std::free(
OB.getBuffer());
1471 std::free(
OB.getBuffer());
1477std::string_view Demangler::demangleSimpleString(std::string_view &MangledName,
1480 for (
size_t i = 0; i < MangledName.size(); ++i) {
1481 if (MangledName[i] !=
'@')
1485 S = MangledName.substr(0, i);
1486 MangledName.remove_prefix(i + 1);
1498Demangler::demangleAnonymousNamespaceName(std::string_view &MangledName) {
1499 assert(llvm::itanium_demangle::starts_with(MangledName,
"?A"));
1502 NamedIdentifierNode *
Node = Arena.
alloc<NamedIdentifierNode>();
1503 Node->Name =
"`anonymous namespace'";
1504 size_t EndPos = MangledName.find(
'@');
1505 if (EndPos == std::string_view::npos) {
1509 std::string_view NamespaceKey = MangledName.substr(0, EndPos);
1510 memorizeString(NamespaceKey);
1511 MangledName = MangledName.substr(EndPos + 1);
1516Demangler::demangleLocallyScopedNamePiece(std::string_view &MangledName) {
1522 bool IsNegative =
false;
1523 std::tie(
Number, IsNegative) = demangleNumber(MangledName);
1542 std::free(
OB.getBuffer());
1548Demangler::demangleFullyQualifiedTypeName(std::string_view &MangledName) {
1550 demangleUnqualifiedTypeName(MangledName,
true);
1555 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, Identifier);
1566Demangler::demangleFullyQualifiedSymbolName(std::string_view &MangledName) {
1573 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1577 QualifiedNameNode *QN = demangleNameScopeChain(MangledName, Identifier);
1586 StructorIdentifierNode *SIN =
1587 static_cast<StructorIdentifierNode *
>(
Identifier);
1589 SIN->
Class =
static_cast<IdentifierNode *
>(ClassNode);
1596Demangler::demangleUnqualifiedTypeName(std::string_view &MangledName,
1603 return demangleBackRefName(MangledName);
1605 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1606 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1608 return demangleSimpleName(MangledName, Memorize);
1612Demangler::demangleUnqualifiedSymbolName(std::string_view &MangledName,
1615 return demangleBackRefName(MangledName);
1616 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1617 return demangleTemplateInstantiationName(MangledName, NBB);
1618 if (llvm::itanium_demangle::starts_with(MangledName,
'?'))
1619 return demangleFunctionIdentifierCode(MangledName);
1620 return demangleSimpleName(MangledName, (NBB &
NBB_Simple) != 0);
1624Demangler::demangleNameScopePiece(std::string_view &MangledName) {
1626 return demangleBackRefName(MangledName);
1628 if (llvm::itanium_demangle::starts_with(MangledName,
"?$"))
1629 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1631 if (llvm::itanium_demangle::starts_with(MangledName,
"?A"))
1632 return demangleAnonymousNamespaceName(MangledName);
1635 return demangleLocallyScopedNamePiece(MangledName);
1637 return demangleSimpleName(MangledName,
true);
1641Demangler::demangleNameScopeChain(std::string_view &MangledName,
1645 Head->
N = UnqualifiedName;
1651 NewHead->
Next = Head;
1654 if (MangledName.empty()) {
1660 IdentifierNode *Elem = demangleNameScopePiece(MangledName);
1667 QualifiedNameNode *QN = Arena.
alloc<QualifiedNameNode>();
1672FuncClass Demangler::demangleFunctionClass(std::string_view &MangledName) {
1673 const char F = MangledName.front();
1674 MangledName.remove_prefix(1);
1734 if (MangledName.empty())
1736 const char F = MangledName.front();
1737 MangledName.remove_prefix(1);
1760Demangler::demangleCallingConvention(std::string_view &MangledName) {
1761 if (MangledName.empty()) {
1766 const char F = MangledName.front();
1767 MangledName.remove_prefix(1);
1802Demangler::demangleVariableStorageClass(std::string_view &MangledName) {
1803 assert(MangledName.front() >=
'0' && MangledName.front() <=
'4');
1805 const char F = MangledName.front();
1806 MangledName.remove_prefix(1);
1822std::pair<Qualifiers, bool>
1823Demangler::demangleQualifiers(std::string_view &MangledName) {
1824 if (MangledName.empty()) {
1826 return std::make_pair(
Q_None,
false);
1829 const char F = MangledName.front();
1830 MangledName.remove_prefix(1);
1834 return std::make_pair(
Q_None,
true);
1836 return std::make_pair(
Q_Const,
true);
1843 return std::make_pair(
Q_None,
false);
1845 return std::make_pair(
Q_Const,
false);
1852 return std::make_pair(
Q_None,
false);
1857TypeNode *Demangler::demangleType(std::string_view &MangledName,
1862 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1865 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1868 if (MangledName.empty()) {
1873 TypeNode *Ty =
nullptr;
1875 Ty = demangleClassType(MangledName);
1877 if (isMemberPointer(MangledName,
Error))
1878 Ty = demangleMemberPointerType(MangledName);
1880 Ty = demanglePointerType(MangledName);
1884 Ty = demangleArrayType(MangledName);
1887 Ty = demangleFunctionType(MangledName,
true);
1889 assert(llvm::itanium_demangle::starts_with(MangledName,
"$$A6"));
1891 Ty = demangleFunctionType(MangledName,
false);
1894 Ty = demangleCustomType(MangledName);
1896 Ty = demanglePrimitiveType(MangledName);
1905bool Demangler::demangleThrowSpecification(std::string_view &MangledName) {
1916Demangler::demangleFunctionType(std::string_view &MangledName,
1917 bool HasThisQuals) {
1918 FunctionSignatureNode *FTy = Arena.
alloc<FunctionSignatureNode>();
1921 FTy->
Quals = demanglePointerExtQualifiers(MangledName);
1937 FTy->
IsNoexcept = demangleThrowSpecification(MangledName);
1943Demangler::demangleFunctionEncoding(std::string_view &MangledName) {
1948 if (MangledName.empty()) {
1953 FuncClass FC = demangleFunctionClass(MangledName);
1956 FunctionSignatureNode *FSN =
nullptr;
1957 ThunkSignatureNode *TTN =
nullptr;
1959 TTN = Arena.
alloc<ThunkSignatureNode>();
1962 TTN = Arena.
alloc<ThunkSignatureNode>();
1975 FSN = Arena.
alloc<FunctionSignatureNode>();
1978 FSN = demangleFunctionType(MangledName, HasThisQuals);
1985 *
static_cast<FunctionSignatureNode *
>(TTN) = *FSN;
1990 FunctionSymbolNode *
Symbol = Arena.
alloc<FunctionSymbolNode>();
1995CustomTypeNode *Demangler::demangleCustomType(std::string_view &MangledName) {
1996 assert(llvm::itanium_demangle::starts_with(MangledName,
'?'));
1997 MangledName.remove_prefix(1);
1999 CustomTypeNode *CTN = Arena.
alloc<CustomTypeNode>();
2000 CTN->
Identifier = demangleUnqualifiedTypeName(MangledName,
true);
2010Demangler::demanglePrimitiveType(std::string_view &MangledName) {
2014 const char F = MangledName.front();
2015 MangledName.remove_prefix(1);
2044 if (MangledName.empty()) {
2048 const char F = MangledName.front();
2049 MangledName.remove_prefix(1);
2077TagTypeNode *Demangler::demangleClassType(std::string_view &MangledName) {
2078 TagTypeNode *
TT =
nullptr;
2080 const char F = MangledName.front();
2081 MangledName.remove_prefix(1);
2103 TT->QualifiedName = demangleFullyQualifiedTypeName(MangledName);
2109PointerTypeNode *Demangler::demanglePointerType(std::string_view &MangledName) {
2110 PointerTypeNode *
Pointer = Arena.
alloc<PointerTypeNode>();
2116 Pointer->Pointee = demangleFunctionType(MangledName,
false);
2120 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2123 Pointer->PointerAuthQualifier = createPointerAuthQualifier(MangledName);
2130Demangler::demangleMemberPointerType(std::string_view &MangledName) {
2131 PointerTypeNode *
Pointer = Arena.
alloc<PointerTypeNode>();
2137 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2143 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2144 Pointer->Pointee = demangleFunctionType(MangledName,
true);
2148 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
2150 Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2154 Pointer->Pointee->Quals = PointeeQuals;
2161Demangler::demanglePointerExtQualifiers(std::string_view &MangledName) {
2173std::optional<PointerAuthQualifierNode::ArgArray>
2174Demangler::demanglePointerAuthQualifier(std::string_view &MangledName) {
2176 return std::nullopt;
2181 for (
unsigned I = 0;
I < NumArgs; ++
I) {
2182 bool IsNegative =
false;
2184 std::tie(
Value, IsNegative) = demangleNumber(MangledName);
2186 return std::nullopt;
2195Demangler::createPointerAuthQualifier(std::string_view &MangledName) {
2197 std::optional<PointerAuthQualifierNode::ArgArray> Vals =
2198 demanglePointerAuthQualifier(MangledName);
2203 PointerAuthQualifierNode *PtrAuthQual =
2204 Arena.
alloc<PointerAuthQualifierNode>();
2205 NodeArrayNode *
Array = Arena.
alloc<NodeArrayNode>();
2207 Array->Count = NumArgs;
2210 for (
unsigned I = 0;
I < NumArgs; ++
I)
2211 Array->Nodes[
I] = Arena.
alloc<IntegerLiteralNode>((*Vals)[
I],
false);
2216ArrayTypeNode *Demangler::demangleArrayType(std::string_view &MangledName) {
2217 assert(MangledName.front() ==
'Y');
2218 MangledName.remove_prefix(1);
2221 bool IsNegative =
false;
2222 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2223 if (IsNegative || Rank == 0) {
2228 ArrayTypeNode *ATy = Arena.
alloc<ArrayTypeNode>();
2232 for (uint64_t
I = 0;
I < Rank; ++
I) {
2234 std::tie(
D, IsNegative) = demangleNumber(MangledName);
2235 if (
Error || IsNegative) {
2239 Tail->N = Arena.
alloc<IntegerLiteralNode>(
D, IsNegative);
2249 std::tie(ATy->
Quals, IsMember) = demangleQualifiers(MangledName);
2262Demangler::demangleFunctionParameterList(std::string_view &MangledName,
2271 while (!
Error && !llvm::itanium_demangle::starts_with(MangledName,
'@') &&
2272 !llvm::itanium_demangle::starts_with(MangledName,
'Z')) {
2276 size_t N = MangledName[0] -
'0';
2281 MangledName.remove_prefix(1);
2285 Current = &(*Current)->Next;
2289 size_t OldSize = MangledName.size();
2298 size_t CharsConsumed = OldSize - MangledName.size();
2299 assert(CharsConsumed != 0);
2306 Current = &(*Current)->Next;
2328Demangler::demangleTemplateParameterList(std::string_view &MangledName) {
2333 while (!llvm::itanium_demangle::starts_with(MangledName,
'@')) {
2348 const bool IsAutoNTTP =
consumeFront(MangledName,
"$M");
2359 TemplateParameterReferenceNode *TPRN =
nullptr;
2362 TP.N = demangleFullyQualifiedTypeName(MangledName);
2369 }
else if (
startsWith(MangledName,
"$1",
"1", !IsAutoNTTP) ||
2370 startsWith(MangledName,
"$H",
"H", !IsAutoNTTP) ||
2371 startsWith(MangledName,
"$I",
"I", !IsAutoNTTP) ||
2372 startsWith(MangledName,
"$J",
"J", !IsAutoNTTP)) {
2374 TP.N = TPRN = Arena.
alloc<TemplateParameterReferenceNode>();
2378 MangledName.remove_prefix(1);
2384 char InheritanceSpecifier = MangledName.front();
2385 MangledName.remove_prefix(1);
2386 SymbolNode *S =
nullptr;
2387 if (llvm::itanium_demangle::starts_with(MangledName,
'?')) {
2388 S =
parse(MangledName);
2396 switch (InheritanceSpecifier) {
2399 demangleSigned(MangledName);
2403 demangleSigned(MangledName);
2407 demangleSigned(MangledName);
2416 }
else if (llvm::itanium_demangle::starts_with(MangledName,
"$E?")) {
2419 TP.N = TPRN = Arena.
alloc<TemplateParameterReferenceNode>();
2422 }
else if (
startsWith(MangledName,
"$F",
"F", !IsAutoNTTP) ||
2423 startsWith(MangledName,
"$G",
"G", !IsAutoNTTP)) {
2424 TP.N = TPRN = Arena.
alloc<TemplateParameterReferenceNode>();
2428 MangledName.remove_prefix(1);
2429 char InheritanceSpecifier = MangledName.front();
2430 MangledName.remove_prefix(1);
2432 switch (InheritanceSpecifier) {
2435 demangleSigned(MangledName);
2439 demangleSigned(MangledName);
2441 demangleSigned(MangledName);
2448 }
else if (
consumeFront(MangledName,
"$0",
"0", !IsAutoNTTP)) {
2450 bool IsNegative =
false;
2452 std::tie(
Value, IsNegative) = demangleNumber(MangledName);
2454 TP.N = Arena.
alloc<IntegerLiteralNode>(
Value, IsNegative);
2469 assert(llvm::itanium_demangle::starts_with(
2475void Demangler::dumpBackReferences() {
2476 std::printf(
"%d function parameter backreferences\n",
2477 (
int)Backrefs.FunctionParamCount);
2481 for (
size_t I = 0;
I < Backrefs.FunctionParamCount; ++
I) {
2482 OB.setCurrentPosition(0);
2487 std::string_view
B = OB;
2488 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)
B.size(),
B.data());
2490 std::free(OB.getBuffer());
2492 if (Backrefs.FunctionParamCount > 0)
2494 std::printf(
"%d name backreferences\n", (
int)Backrefs.NamesCount);
2495 for (
size_t I = 0;
I < Backrefs.NamesCount; ++
I) {
2496 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)Backrefs.Names[
I]->Name.size(),
2497 Backrefs.Names[
I]->Name.data());
2499 if (Backrefs.NamesCount > 0)
2503std::optional<size_t>
2505 std::string_view ProcessedName{MangledName};
2509 return std::nullopt;
2514 D.demangleFullyQualifiedSymbolName(ProcessedName);
2516 return std::nullopt;
2518 return MangledName.length() - ProcessedName.length();
2525 std::string_view Name{MangledName};
2527 if (!
D.Error && NMangled)
2528 *NMangled = MangledName.size() - Name.size();
2531 D.dumpBackReferences();
2559 Buf = OB.getBuffer();
2563 *
Status = InternalStatus;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#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 VariableSymbolNode * synthesizeType(ArenaAllocator &Arena, TypeNode *Type, std::string_view Description)
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 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.
T * alloc(Args &&... ConstructorArgs)
char * allocUnalignedBuffer(size_t Size)
T * allocArray(size_t Count)
DEMANGLE_ABI SymbolNode * parse(std::string_view &MangledName)
@ 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
@ OF_NoDecorativeRTTITypeDescriptor
@ RttiBaseClassDescriptor
@ DynamicAtexitDestructor
@ RttiClassHierarchyDescriptor
NodeAddr< NodeBase * > Node
SmallVector< Node, 4 > NodeList
This is an optimization pass for GlobalISel generic memory operations.
@ demangle_invalid_mangled_name
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
DEMANGLE_ABI std::optional< size_t > getArm64ECInsertionPointInMangledName(std::string_view MangledName)
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
@ MSDF_NoVoidParameter
Don't write "(void)" for functions that take no parameters.
@ MSDF_NoDecorativeRTTITypeDescriptor
Don't add decoration to RTTI type descriptors: struct MyStruct ‘RTTI Type Descriptor Name’ will inste...
@ MSDF_NoCallingConvention
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
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
NodeArrayNode * TargetNames
void output(OutputBuffer &OB, OutputFlags Flags) const override
std::array< int64_t, 3 > ThunkOffsets