31 using namespace ms_demangle;
69 assert(MangledName[0] ==
'6' || MangledName[0] ==
'8');
70 return (MangledName[0] ==
'8');
82 switch (MangledName.
front()) {
142 size_t End = S.
find(
'?');
146 if (Candidate.
empty())
151 if (Candidate.
size() == 1)
152 return Candidate[0] ==
'@' || (Candidate[0] >=
'0' && Candidate[0] <=
'9');
155 if (Candidate.
back() !=
'@')
165 if (Candidate[0] <
'B' || Candidate[0] >
'P')
168 while (!Candidate.
empty()) {
169 if (Candidate[0] <
'A' || Candidate[0] >
'P')
220 static std::pair<Qualifiers, PointerAffinity>
238 assert(
false &&
"Ty is not a pointer type!");
244 char *Stable = Arena.allocUnalignedBuffer(Borrowed.
size() + 1);
245 std::strcpy(Stable, Borrowed.
begin());
247 return {Stable, Borrowed.
size()};
251 Demangler::demangleSpecialTableSymbolNode(
StringView &MangledName,
256 NI->
Name =
"`vftable'";
259 NI->
Name =
"`vbtable'";
262 NI->
Name =
"`local vftable'";
265 NI->
Name =
"`RTTI Complete Object Locator'";
268 LLVM_BUILTIN_UNREACHABLE;
273 bool IsMember =
false;
274 char Front = MangledName.
popFront();
275 if (Front !=
'6' && Front !=
'7') {
280 std::tie(STSN->
Quals, IsMember) = demangleQualifiers(MangledName);
282 STSN->
TargetName = demangleFullyQualifiedTypeName(MangledName);
287 Demangler::demangleLocalStaticGuard(
StringView &MangledName) {
304 if (!MangledName.
empty())
305 LSGI->ScopeIndex = demangleUnsigned(MangledName);
355 Demangler::demangleRttiBaseClassDescriptorNode(
ArenaAllocator &Arena,
359 RBCDN->
NVOffset = demangleUnsigned(MangledName);
362 RBCDN->
Flags = demangleUnsigned(MangledName);
367 VSN->
Name = demangleNameScopeChain(MangledName, RBCDN);
378 bool IsKnownStaticDataMember =
false;
380 IsKnownStaticDataMember =
true;
395 int AtCount = IsKnownStaticDataMember ? 2 : 1;
396 for (
int I = 0;
I < AtCount; ++
I) {
403 FSN = demangleFunctionEncoding(MangledName);
406 if (IsKnownStaticDataMember) {
427 return demangleStringLiteral(MangledName);
432 return demangleSpecialTableSymbolNode(MangledName, SIK);
434 return demangleVcallThunkNode(MangledName);
436 return demangleLocalStaticGuard(MangledName);
443 if (!MangledName.
empty())
448 return demangleUntypedVariable(Arena, MangledName,
449 "`RTTI Base Class Array'");
451 return demangleUntypedVariable(Arena, MangledName,
452 "`RTTI Class Hierarchy Descriptor'");
454 return demangleRttiBaseClassDescriptorNode(Arena, MangledName);
456 return demangleInitFiniStub(MangledName,
false);
458 return demangleInitFiniStub(MangledName,
true);
467 Demangler::demangleFunctionIdentifierCode(
StringView &MangledName) {
471 if (MangledName.consumeFront(
"__"))
472 return demangleFunctionIdentifierCode(
474 else if (MangledName.consumeFront(
"_"))
475 return demangleFunctionIdentifierCode(MangledName,
477 return demangleFunctionIdentifierCode(MangledName,
482 Demangler::demangleStructorIdentifier(
StringView &MangledName,
490 Demangler::demangleConversionOperatorIdentifier(
StringView &MangledName) {
497 Demangler::demangleLiteralOperatorIdentifier(
StringView &MangledName) {
500 N->
Name = demangleSimpleString(MangledName,
false);
510 static IFK
Basic[36] = {
548 static IFK
Under[36] = {
626 int Index = (CH >=
'0' && CH <=
'9') ? (CH -
'0') : (CH -
'A' + 10);
633 return DoubleUnder[
Index];
635 LLVM_BUILTIN_UNREACHABLE;
639 Demangler::demangleFunctionIdentifierCode(
StringView &MangledName,
643 switch (
char CH = MangledName.
popFront()) {
646 return demangleStructorIdentifier(MangledName, CH ==
'1');
648 return demangleConversionOperatorIdentifier(MangledName);
658 switch (
char CH = MangledName.
popFront()) {
660 return demangleLiteralOperatorIdentifier(MangledName);
674 switch (MangledName.
front()) {
681 return demangleVariableEncoding(MangledName, SC);
718 if (
SymbolNode *
SI = demangleSpecialIntrinsic(MangledName))
742 if (MangledName.
empty())
745 return demangleClassType(MangledName);
770 demanglePointerExtQualifiers(MangledName));
772 bool IsMember =
false;
773 std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
777 demangleFullyQualifiedTypeName(MangledName);
785 VSN->
Type->
Quals = demangleQualifiers(MangledName).first;
803 std::pair<uint64_t, bool> Demangler::demangleNumber(
StringView &MangledName) {
807 uint64_t
Ret = MangledName[0] -
'0' + 1;
809 return {
Ret, IsNegative};
813 for (
size_t i = 0; i < MangledName.
size(); ++i) {
814 char C = MangledName[i];
816 MangledName = MangledName.
dropFront(i + 1);
817 return {
Ret, IsNegative};
819 if (
'A' <= C && C <=
'P') {
820 Ret = (Ret << 4) + (C -
'A');
827 return {0ULL,
false};
830 uint64_t Demangler::demangleUnsigned(
StringView &MangledName) {
831 bool IsNegative =
false;
833 std::tie(Number, IsNegative) = demangleNumber(MangledName);
839 int64_t Demangler::demangleSigned(
StringView &MangledName) {
840 bool IsNegative =
false;
842 std::tie(Number, IsNegative) = demangleNumber(MangledName);
845 int64_t
I =
static_cast<int64_t
>(Number);
846 return IsNegative ? -
I :
I;
851 void Demangler::memorizeString(
StringView S) {
854 for (
size_t i = 0; i < Backrefs.NamesCount; ++i)
855 if (S == Backrefs.Names[i]->Name)
859 Backrefs.Names[Backrefs.NamesCount++] =
N;
865 size_t I = MangledName[0] -
'0';
866 if (I >= Backrefs.NamesCount) {
872 return Backrefs.Names[
I];
887 memorizeString(Owned);
892 Demangler::demangleTemplateInstantiationName(
StringView &MangledName,
901 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
903 Identifier->
TemplateParams = demangleTemplateParameterList(MangledName);
910 memorizeIdentifier(Identifier);
917 StringView S = demangleSimpleString(MangledName, Memorize);
930 return (C <=
'J') ? (C -
'A') : (10 + C -
'K');
933 uint8_t Demangler::demangleCharLiteral(
StringView &MangledName) {
938 if (MangledName.
empty())
939 goto CharLiteralError;
943 if (MangledName.
size() < 2)
944 goto CharLiteralError;
947 goto CharLiteralError;
952 return (C1 << 4) | C2;
956 const char *
Lookup =
",/\\:. \n\t'-";
957 char C = Lookup[MangledName[0] -
'0'];
958 MangledName = MangledName.dropFront();
962 if (MangledName[0] >=
'a' && MangledName[0] <=
'z') {
963 char Lookup[26] = {
'\xE1',
'\xE2',
'\xE3',
'\xE4',
'\xE5',
'\xE6',
'\xE7',
964 '\xE8',
'\xE9',
'\xEA',
'\xEB',
'\xEC',
'\xED',
'\xEE',
965 '\xEF',
'\xF0',
'\xF1',
'\xF2',
'\xF3',
'\xF4',
'\xF5',
966 '\xF6',
'\xF7',
'\xF8',
'\xF9',
'\xFA'};
967 char C = Lookup[MangledName[0] -
'a'];
968 MangledName = MangledName.dropFront();
972 if (MangledName[0] >=
'A' && MangledName[0] <=
'Z') {
973 char Lookup[26] = {
'\xC1',
'\xC2',
'\xC3',
'\xC4',
'\xC5',
'\xC6',
'\xC7',
974 '\xC8',
'\xC9',
'\xCA',
'\xCB',
'\xCC',
'\xCD',
'\xCE',
975 '\xCF',
'\xD0',
'\xD1',
'\xD2',
'\xD3',
'\xD4',
'\xD5',
976 '\xD6',
'\xD7',
'\xD8',
'\xD9',
'\xDA'};
977 char C = Lookup[MangledName[0] -
'A'];
978 MangledName = MangledName.dropFront();
987 wchar_t Demangler::demangleWcharLiteral(
StringView &MangledName) {
990 C1 = demangleCharLiteral(MangledName);
992 goto WCharLiteralError;
993 C2 = demangleCharLiteral(MangledName);
995 goto WCharLiteralError;
997 return ((
wchar_t)C1 << 8) | (wchar_t)C2;
1006 *Buffer = (Digit < 10) ? (
'0' + Digit) : (
'A' + Digit - 10);
1019 char TempBuffer[17];
1021 ::memset(TempBuffer, 0,
sizeof(TempBuffer));
1022 constexpr
int MaxPos = 15;
1024 int Pos = MaxPos - 1;
1026 for (
int I = 0;
I < 2; ++
I) {
1030 TempBuffer[Pos--] =
'x';
1031 TempBuffer[Pos--] =
'\\';
1073 if (C > 0x1F && C < 0x7F) {
1083 const uint8_t *End = StringBytes + Length - 1;
1085 while (Length > 0 && *End == 0) {
1096 for (
unsigned I = 0;
I < Length; ++
I) {
1097 if (*StringBytes++ == 0)
1104 unsigned NumBytes) {
1108 if (NumBytes % 2 == 1)
1114 if (NumBytes < 32) {
1116 if (TrailingNulls >= 4)
1118 if (TrailingNulls >= 2)
1130 if (Nulls >= 2 * NumChars / 3)
1132 if (Nulls >= NumChars / 3)
1138 unsigned CharIndex,
unsigned CharBytes) {
1139 assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1140 unsigned Offset = CharIndex * CharBytes;
1142 StringBytes = StringBytes +
Offset;
1143 for (
unsigned I = 0;
I < CharBytes; ++
I) {
1144 unsigned C =
static_cast<unsigned>(StringBytes[
I]);
1145 Result |= C << (8 *
I);
1156 FSN->
Name = demangleNameScopeChain(MangledName, VTIN);
1160 VTIN->OffsetInVTable = demangleUnsigned(MangledName);
1165 return (
Error) ? nullptr : FSN;
1169 Demangler::demangleStringLiteral(
StringView &MangledName) {
1173 uint64_t StringByteSize;
1174 bool IsWcharT =
false;
1175 bool IsNegative =
false;
1176 size_t CrcEndPos = 0;
1177 char *ResultBuffer =
nullptr;
1183 goto StringLiteralError;
1184 if (MangledName.
empty())
1185 goto StringLiteralError;
1195 goto StringLiteralError;
1199 std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
1200 if (
Error || IsNegative)
1201 goto StringLiteralError;
1204 CrcEndPos = MangledName.
find(
'@');
1206 goto StringLiteralError;
1207 CRC = MangledName.
substr(0, CrcEndPos);
1208 MangledName = MangledName.
dropFront(CrcEndPos + 1);
1209 if (MangledName.
empty())
1210 goto StringLiteralError;
1217 if (StringByteSize > 64)
1221 assert(StringByteSize >= 2);
1222 wchar_t W = demangleWcharLiteral(MangledName);
1225 StringByteSize -= 2;
1227 goto StringLiteralError;
1232 constexpr
unsigned MaxStringByteLength = 32 * 4;
1233 uint8_t StringBytes[MaxStringByteLength];
1235 unsigned BytesDecoded = 0;
1237 assert(StringByteSize >= 1);
1238 StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
1241 if (StringByteSize > BytesDecoded)
1244 unsigned CharBytes =
1246 assert(StringByteSize % CharBytes == 0);
1247 switch (CharBytes) {
1258 LLVM_BUILTIN_UNREACHABLE;
1260 const unsigned NumChars = BytesDecoded / CharBytes;
1261 for (
unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
1264 if (CharIndex + 1 < NumChars || Result->
IsTruncated)
1272 std::free(ResultBuffer);
1283 for (
size_t i = 0; i < MangledName.
size(); ++i) {
1284 if (MangledName[i] !=
'@')
1286 S = MangledName.
substr(0, i);
1287 MangledName = MangledName.
dropFront(i + 1);
1299 Demangler::demangleAnonymousNamespaceName(
StringView &MangledName) {
1304 Node->
Name =
"`anonymous namespace'";
1305 size_t EndPos = MangledName.
find(
'@');
1311 memorizeString(NamespaceKey);
1312 MangledName = MangledName.
substr(EndPos + 1);
1317 Demangler::demangleLocallyScopedNamePiece(
StringView &MangledName) {
1322 auto Number = demangleNumber(MangledName);
1341 OS <<
"::`" <<
Number.first <<
"'";
1344 Identifier->
Name = copyString(Result);
1351 Demangler::demangleFullyQualifiedTypeName(
StringView &MangledName) {
1352 IdentifierNode *Identifier = demangleUnqualifiedTypeName(MangledName,
true);
1368 Demangler::demangleFullyQualifiedSymbolName(
StringView &MangledName) {
1375 demangleUnqualifiedSymbolName(MangledName,
NBB_Simple);
1401 return demangleBackRefName(MangledName);
1404 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1406 return demangleSimpleName(MangledName, Memorize);
1410 Demangler::demangleUnqualifiedSymbolName(
StringView &MangledName,
1413 return demangleBackRefName(MangledName);
1415 return demangleTemplateInstantiationName(MangledName, NBB);
1417 return demangleFunctionIdentifierCode(MangledName);
1418 return demangleSimpleName(MangledName, (NBB &
NBB_Simple) != 0);
1423 return demangleBackRefName(MangledName);
1426 return demangleTemplateInstantiationName(MangledName,
NBB_Template);
1429 return demangleAnonymousNamespaceName(MangledName);
1432 return demangleLocallyScopedNamePiece(MangledName);
1434 return demangleSimpleName(MangledName,
true);
1442 for (
size_t I = 0;
I < Count; ++
I) {
1450 Demangler::demangleNameScopeChain(
StringView &MangledName,
1454 Head->
N = UnqualifiedName;
1460 NewHead->
Next = Head;
1463 if (MangledName.
empty()) {
1612 std::pair<Qualifiers, bool>
1613 Demangler::demangleQualifiers(
StringView &MangledName) {
1618 return std::make_pair(
Q_None,
true);
1620 return std::make_pair(
Q_Const,
true);
1627 return std::make_pair(
Q_None,
false);
1629 return std::make_pair(
Q_Const,
false);
1636 return std::make_pair(
Q_None,
false);
1644 bool IsMember =
false;
1646 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1649 std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1654 Ty = demangleClassType(MangledName);
1657 Ty = demangleMemberPointerType(MangledName);
1659 Ty = demanglePointerType(MangledName);
1663 Ty = demangleArrayType(MangledName);
1666 Ty = demangleFunctionType(MangledName,
true);
1670 Ty = demangleFunctionType(MangledName,
false);
1673 Ty = demangleCustomType(MangledName);
1675 Ty = demanglePrimitiveType(MangledName);
1684 bool Demangler::demangleThrowSpecification(
StringView &MangledName) {
1695 bool HasThisQuals) {
1699 FTy->
Quals = demanglePointerExtQualifiers(MangledName);
1713 FTy->
Params = demangleFunctionParameterList(MangledName);
1715 FTy->
IsNoexcept = demangleThrowSpecification(MangledName);
1721 Demangler::demangleFunctionEncoding(
StringView &MangledName) {
1726 FuncClass FC = demangleFunctionClass(MangledName);
1751 FSN = demangleFunctionType(MangledName, HasThisQuals);
1769 CTN->
Identifier = demangleUnqualifiedTypeName(MangledName,
true);
1810 if (MangledName.
empty()) {
1849 if (MangledName.
popFront() !=
'4') {
1859 TT->
QualifiedName = demangleFullyQualifiedTypeName(MangledName);
1872 Pointer->
Pointee = demangleFunctionType(MangledName,
false);
1876 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
1890 Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
1894 Pointer->
ClassParent = demangleFullyQualifiedTypeName(MangledName);
1895 Pointer->
Pointee = demangleFunctionType(MangledName,
true);
1898 bool IsMember =
false;
1899 std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
1901 Pointer->
ClassParent = demangleFullyQualifiedTypeName(MangledName);
1927 bool IsNegative =
false;
1928 std::tie(Rank, IsNegative) = demangleNumber(MangledName);
1929 if (IsNegative || Rank == 0) {
1938 for (uint64_t
I = 0;
I < Rank; ++
I) {
1940 std::tie(D, IsNegative) = demangleNumber(MangledName);
1954 bool IsMember =
false;
1955 std::tie(ATy->
Quals, IsMember) = demangleQualifiers(MangledName);
1968 Demangler::demangleFunctionParameterList(
StringView &MangledName) {
1981 size_t N = MangledName[0] -
'0';
1982 if (N >= Backrefs.FunctionParamCount) {
1989 (*Current)->
N = Backrefs.FunctionParams[
N];
1990 Current = &(*Current)->Next;
1994 size_t OldSize = MangledName.
size();
2003 size_t CharsConsumed = OldSize - MangledName.
size();
2004 assert(CharsConsumed != 0);
2008 if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1)
2009 Backrefs.FunctionParams[Backrefs.FunctionParamCount++] = TN;
2011 Current = &(*Current)->Next;
2035 Demangler::demangleTemplateParameterList(
StringView &MangledName) {
2057 TP.N = demangleFullyQualifiedTypeName(MangledName);
2075 char InheritanceSpecifier = MangledName.
popFront();
2078 S =
parse(MangledName);
2082 switch (InheritanceSpecifier) {
2085 demangleSigned(MangledName);
2089 demangleSigned(MangledName);
2093 demangleSigned(MangledName);
2113 MangledName = MangledName.dropFront();
2114 char InheritanceSpecifier = MangledName.popFront();
2116 switch (InheritanceSpecifier) {
2119 demangleSigned(MangledName);
2123 demangleSigned(MangledName);
2125 demangleSigned(MangledName);
2137 bool IsNegative =
false;
2139 std::tie(Value, IsNegative) = demangleNumber(MangledName);
2163 std::printf(
"%d function parameter backreferences\n",
2164 (
int)Backrefs.FunctionParamCount);
2170 for (
size_t I = 0;
I < Backrefs.FunctionParamCount; ++
I) {
2181 if (Backrefs.FunctionParamCount > 0)
2183 std::printf(
"%d name backreferences\n", (
int)Backrefs.NamesCount);
2184 for (
size_t I = 0;
I < Backrefs.NamesCount; ++
I) {
2185 std::printf(
" [%d] - %.*s\n", (
int)
I, (
int)Backrefs.Names[I]->Name.size(),
2186 Backrefs.Names[
I]->Name.begin());
2188 if (Backrefs.NamesCount > 0)
2217 *Status = InternalStatus;
static VariableSymbolNode * synthesizeVariable(ArenaAllocator &Arena, TypeNode *Type, StringView VariableName)
static bool isFunctionType(StringView S)
bool startsWith(char C) const
NodeArrayNode * TemplateParams
StringView dropFront(size_t N=1) const
static void outputEscapedChar(OutputStream &OS, unsigned C)
void output(OutputStream &OS, OutputFlags Flags) const override
static uint8_t rebasedHexDigitToNumber(char C)
static bool isArrayType(StringView S)
This class represents lattice values for constants.
static unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length)
static SpecialIntrinsicKind consumeSpecialIntrinsicKind(StringView &MangledName)
void output(OutputStream &OS, OutputFlags Flags) const override
QualifiedNameNode * TargetName
static bool isMemberPointer(StringView MangledName, bool &Error)
SymbolNode * parse(StringView &MangledName)
static void outputHex(OutputStream &OS, unsigned C)
CallingConv CallConvention
NodeArrayNode * Components
static bool isTagType(StringView S)
T * allocArray(size_t Count)
QualifiedNameNode * QualifiedName
size_t find(char C, size_t From=0) const
amdgpu Simplify well known AMD library false Value Value const Twine & Name
StringView dropBack(size_t N=1) const
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
static unsigned decodeMultiByteChar(const uint8_t *StringBytes, unsigned CharIndex, unsigned CharBytes)
VariableSymbolNode * Variable
const char * begin() const
static FunctionRefQualifier demangleFunctionRefQualifier(StringView &MangledName)
void dumpBackReferences()
T * alloc(Args &&... ConstructorArgs)
static IntrinsicFunctionKind translateIntrinsicFunctionCode(char CH, FunctionIdentifierCodeGroup Group)
QualifiedNameNode * ClassParent
static bool isPointerType(StringView S)
TagTypeNode * parseTagUniqueName(StringView &MangledName)
static constexpr size_t Max
static bool isCustomType(StringView S)
IdentifierNode * getUnqualifiedIdentifier()
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
static unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars, unsigned NumBytes)
static NamedIdentifierNode * synthesizeNamedIdentifier(ArenaAllocator &Arena, StringView Name)
The instances of the Type class are immutable: once they are created, they are never changed...
size_t getCurrentPosition() const
static bool startsWithDigit(StringView S)
static bool isRebasedHexDigit(char C)
void setCurrentPosition(size_t NewPos)
static unsigned countEmbeddedNulls(const uint8_t *StringBytes, unsigned Length)
FunctionRefQualifier RefQualifier
StringView substr(size_t From) const
FunctionIdentifierCodeGroup
static NodeArrayNode * nodeListToNodeArray(ArenaAllocator &Arena, NodeList *Head, size_t Count)
llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
CHAIN = SC CHAIN, Imm128 - System call.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
NodeArrayNode * Dimensions
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
IdentifierNode * Identifier
FunctionSignatureNode * Signature
static bool startsWithLocalScopePattern(StringView S)
static QualifiedNameNode * synthesizeQualifiedName(ArenaAllocator &Arena, IdentifierNode *Identifier)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool consumeFront(char C)
LLVM Value Representation.
bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S, size_t InitSize)
Lightweight error class with error context and mandatory checking.
static std::pair< Qualifiers, PointerAffinity > demanglePointerCVQualifiers(StringView &MangledName)
virtual void output(OutputStream &OS, OutputFlags Flags) const =0
static void writeHexDigit(char *Buffer, uint8_t Digit)
char * microsoftDemangle(const char *mangled_name, char *buf, size_t *n, int *status, MSDemangleFlags Flags=MSDF_None)
std::array< int64_t, 3 > ThunkOffsets