File indexing completed on 2026-05-10 08:43:48
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
0010 #define LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
0011
0012 #include "llvm/Demangle/Demangle.h"
0013 #include "llvm/Demangle/MicrosoftDemangleNodes.h"
0014
0015 #include <cassert>
0016 #include <string_view>
0017 #include <utility>
0018
0019 namespace llvm {
0020 namespace ms_demangle {
0021
0022
0023
0024
0025
0026 constexpr size_t AllocUnit = 4096;
0027
0028 class ArenaAllocator {
0029 struct AllocatorNode {
0030 uint8_t *Buf = nullptr;
0031 size_t Used = 0;
0032 size_t Capacity = 0;
0033 AllocatorNode *Next = nullptr;
0034 };
0035
0036 void addNode(size_t Capacity) {
0037 AllocatorNode *NewHead = new AllocatorNode;
0038 NewHead->Buf = new uint8_t[Capacity];
0039 NewHead->Next = Head;
0040 NewHead->Capacity = Capacity;
0041 Head = NewHead;
0042 NewHead->Used = 0;
0043 }
0044
0045 public:
0046 ArenaAllocator() { addNode(AllocUnit); }
0047
0048 ~ArenaAllocator() {
0049 while (Head) {
0050 assert(Head->Buf);
0051 delete[] Head->Buf;
0052 AllocatorNode *Next = Head->Next;
0053 delete Head;
0054 Head = Next;
0055 }
0056 }
0057
0058
0059 ArenaAllocator(const ArenaAllocator &) = delete;
0060 ArenaAllocator &operator=(const ArenaAllocator &) = delete;
0061
0062 char *allocUnalignedBuffer(size_t Size) {
0063 assert(Head && Head->Buf);
0064
0065 uint8_t *P = Head->Buf + Head->Used;
0066
0067 Head->Used += Size;
0068 if (Head->Used <= Head->Capacity)
0069 return reinterpret_cast<char *>(P);
0070
0071 addNode(std::max(AllocUnit, Size));
0072 Head->Used = Size;
0073 return reinterpret_cast<char *>(Head->Buf);
0074 }
0075
0076 template <typename T, typename... Args> T *allocArray(size_t Count) {
0077 size_t Size = Count * sizeof(T);
0078 assert(Head && Head->Buf);
0079
0080 size_t P = (size_t)Head->Buf + Head->Used;
0081 uintptr_t AlignedP =
0082 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
0083 uint8_t *PP = (uint8_t *)AlignedP;
0084 size_t Adjustment = AlignedP - P;
0085
0086 Head->Used += Size + Adjustment;
0087 if (Head->Used <= Head->Capacity)
0088 return new (PP) T[Count]();
0089
0090 addNode(std::max(AllocUnit, Size));
0091 Head->Used = Size;
0092 return new (Head->Buf) T[Count]();
0093 }
0094
0095 template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
0096 constexpr size_t Size = sizeof(T);
0097 assert(Head && Head->Buf);
0098
0099 size_t P = (size_t)Head->Buf + Head->Used;
0100 uintptr_t AlignedP =
0101 (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
0102 uint8_t *PP = (uint8_t *)AlignedP;
0103 size_t Adjustment = AlignedP - P;
0104
0105 Head->Used += Size + Adjustment;
0106 if (Head->Used <= Head->Capacity)
0107 return new (PP) T(std::forward<Args>(ConstructorArgs)...);
0108
0109 static_assert(Size < AllocUnit);
0110 addNode(AllocUnit);
0111 Head->Used = Size;
0112 return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
0113 }
0114
0115 private:
0116 AllocatorNode *Head = nullptr;
0117 };
0118
0119 struct BackrefContext {
0120 static constexpr size_t Max = 10;
0121
0122 TypeNode *FunctionParams[Max];
0123 size_t FunctionParamCount = 0;
0124
0125
0126
0127 NamedIdentifierNode *Names[Max];
0128 size_t NamesCount = 0;
0129 };
0130
0131 enum class QualifierMangleMode { Drop, Mangle, Result };
0132
0133 enum NameBackrefBehavior : uint8_t {
0134 NBB_None = 0,
0135 NBB_Template = 1 << 0,
0136 NBB_Simple = 1 << 1,
0137 };
0138
0139 enum class FunctionIdentifierCodeGroup { Basic, Under, DoubleUnder };
0140
0141
0142
0143
0144 class Demangler {
0145 friend std::optional<size_t>
0146 llvm::getArm64ECInsertionPointInMangledName(std::string_view MangledName);
0147
0148 public:
0149 Demangler() = default;
0150 virtual ~Demangler() = default;
0151
0152
0153
0154 SymbolNode *parse(std::string_view &MangledName);
0155
0156 TagTypeNode *parseTagUniqueName(std::string_view &MangledName);
0157
0158
0159 bool Error = false;
0160
0161 void dumpBackReferences();
0162
0163 private:
0164 SymbolNode *demangleEncodedSymbol(std::string_view &MangledName,
0165 QualifiedNameNode *QN);
0166 SymbolNode *demangleDeclarator(std::string_view &MangledName);
0167 SymbolNode *demangleMD5Name(std::string_view &MangledName);
0168 SymbolNode *demangleTypeinfoName(std::string_view &MangledName);
0169
0170 VariableSymbolNode *demangleVariableEncoding(std::string_view &MangledName,
0171 StorageClass SC);
0172 FunctionSymbolNode *demangleFunctionEncoding(std::string_view &MangledName);
0173
0174 Qualifiers demanglePointerExtQualifiers(std::string_view &MangledName);
0175
0176
0177 TypeNode *demangleType(std::string_view &MangledName,
0178 QualifierMangleMode QMM);
0179 PrimitiveTypeNode *demanglePrimitiveType(std::string_view &MangledName);
0180 CustomTypeNode *demangleCustomType(std::string_view &MangledName);
0181 TagTypeNode *demangleClassType(std::string_view &MangledName);
0182 PointerTypeNode *demanglePointerType(std::string_view &MangledName);
0183 PointerTypeNode *demangleMemberPointerType(std::string_view &MangledName);
0184 FunctionSignatureNode *demangleFunctionType(std::string_view &MangledName,
0185 bool HasThisQuals);
0186
0187 ArrayTypeNode *demangleArrayType(std::string_view &MangledName);
0188
0189 NodeArrayNode *demangleFunctionParameterList(std::string_view &MangledName,
0190 bool &IsVariadic);
0191 NodeArrayNode *demangleTemplateParameterList(std::string_view &MangledName);
0192
0193 std::pair<uint64_t, bool> demangleNumber(std::string_view &MangledName);
0194 uint64_t demangleUnsigned(std::string_view &MangledName);
0195 int64_t demangleSigned(std::string_view &MangledName);
0196
0197 void memorizeString(std::string_view s);
0198 void memorizeIdentifier(IdentifierNode *Identifier);
0199
0200
0201 std::string_view copyString(std::string_view Borrowed);
0202
0203 QualifiedNameNode *
0204 demangleFullyQualifiedTypeName(std::string_view &MangledName);
0205 QualifiedNameNode *
0206 demangleFullyQualifiedSymbolName(std::string_view &MangledName);
0207
0208 IdentifierNode *demangleUnqualifiedTypeName(std::string_view &MangledName,
0209 bool Memorize);
0210 IdentifierNode *demangleUnqualifiedSymbolName(std::string_view &MangledName,
0211 NameBackrefBehavior NBB);
0212
0213 QualifiedNameNode *demangleNameScopeChain(std::string_view &MangledName,
0214 IdentifierNode *UnqualifiedName);
0215 IdentifierNode *demangleNameScopePiece(std::string_view &MangledName);
0216
0217 NamedIdentifierNode *demangleBackRefName(std::string_view &MangledName);
0218 IdentifierNode *
0219 demangleTemplateInstantiationName(std::string_view &MangledName,
0220 NameBackrefBehavior NBB);
0221 IntrinsicFunctionKind
0222 translateIntrinsicFunctionCode(char CH, FunctionIdentifierCodeGroup Group);
0223 IdentifierNode *demangleFunctionIdentifierCode(std::string_view &MangledName);
0224 IdentifierNode *
0225 demangleFunctionIdentifierCode(std::string_view &MangledName,
0226 FunctionIdentifierCodeGroup Group);
0227 StructorIdentifierNode *
0228 demangleStructorIdentifier(std::string_view &MangledName, bool IsDestructor);
0229 ConversionOperatorIdentifierNode *
0230 demangleConversionOperatorIdentifier(std::string_view &MangledName);
0231 LiteralOperatorIdentifierNode *
0232 demangleLiteralOperatorIdentifier(std::string_view &MangledName);
0233
0234 SymbolNode *demangleSpecialIntrinsic(std::string_view &MangledName);
0235 SpecialTableSymbolNode *
0236 demangleSpecialTableSymbolNode(std::string_view &MangledName,
0237 SpecialIntrinsicKind SIK);
0238 LocalStaticGuardVariableNode *
0239 demangleLocalStaticGuard(std::string_view &MangledName, bool IsThread);
0240 VariableSymbolNode *demangleUntypedVariable(ArenaAllocator &Arena,
0241 std::string_view &MangledName,
0242 std::string_view VariableName);
0243 VariableSymbolNode *
0244 demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
0245 std::string_view &MangledName);
0246 FunctionSymbolNode *demangleInitFiniStub(std::string_view &MangledName,
0247 bool IsDestructor);
0248
0249 NamedIdentifierNode *demangleSimpleName(std::string_view &MangledName,
0250 bool Memorize);
0251 NamedIdentifierNode *
0252 demangleAnonymousNamespaceName(std::string_view &MangledName);
0253 NamedIdentifierNode *
0254 demangleLocallyScopedNamePiece(std::string_view &MangledName);
0255 EncodedStringLiteralNode *
0256 demangleStringLiteral(std::string_view &MangledName);
0257 FunctionSymbolNode *demangleVcallThunkNode(std::string_view &MangledName);
0258
0259 std::string_view demangleSimpleString(std::string_view &MangledName,
0260 bool Memorize);
0261
0262 FuncClass demangleFunctionClass(std::string_view &MangledName);
0263 CallingConv demangleCallingConvention(std::string_view &MangledName);
0264 StorageClass demangleVariableStorageClass(std::string_view &MangledName);
0265 bool demangleThrowSpecification(std::string_view &MangledName);
0266 wchar_t demangleWcharLiteral(std::string_view &MangledName);
0267 uint8_t demangleCharLiteral(std::string_view &MangledName);
0268
0269 std::pair<Qualifiers, bool> demangleQualifiers(std::string_view &MangledName);
0270
0271
0272 ArenaAllocator Arena;
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 BackrefContext Backrefs;
0288 };
0289
0290 }
0291 }
0292
0293 #endif