LLVM  16.0.0git
MicrosoftDemangle.h
Go to the documentation of this file.
1 //===------------------------- MicrosoftDemangle.h --------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
10 #define LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
11 
14 
15 #include <utility>
16 
17 namespace llvm {
18 namespace ms_demangle {
19 // This memory allocator is extremely fast, but it doesn't call dtors
20 // for allocated objects. That means you can't use STL containers
21 // (such as std::vector) with this allocator. But it pays off --
22 // the demangler is 3x faster with this allocator compared to one with
23 // STL containers.
24 constexpr size_t AllocUnit = 4096;
25 
27  struct AllocatorNode {
28  uint8_t *Buf = nullptr;
29  size_t Used = 0;
30  size_t Capacity = 0;
31  AllocatorNode *Next = nullptr;
32  };
33 
34  void addNode(size_t Capacity) {
35  AllocatorNode *NewHead = new AllocatorNode;
36  NewHead->Buf = new uint8_t[Capacity];
37  NewHead->Next = Head;
38  NewHead->Capacity = Capacity;
39  Head = NewHead;
40  NewHead->Used = 0;
41  }
42 
43 public:
44  ArenaAllocator() { addNode(AllocUnit); }
45 
47  while (Head) {
48  assert(Head->Buf);
49  delete[] Head->Buf;
50  AllocatorNode *Next = Head->Next;
51  delete Head;
52  Head = Next;
53  }
54  }
55 
56  char *allocUnalignedBuffer(size_t Size) {
57  assert(Head && Head->Buf);
58 
59  uint8_t *P = Head->Buf + Head->Used;
60 
61  Head->Used += Size;
62  if (Head->Used <= Head->Capacity)
63  return reinterpret_cast<char *>(P);
64 
65  addNode(std::max(AllocUnit, Size));
66  Head->Used = Size;
67  return reinterpret_cast<char *>(Head->Buf);
68  }
69 
70  template <typename T, typename... Args> T *allocArray(size_t Count) {
71  size_t Size = Count * sizeof(T);
72  assert(Head && Head->Buf);
73 
74  size_t P = (size_t)Head->Buf + Head->Used;
75  uintptr_t AlignedP =
76  (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
77  uint8_t *PP = (uint8_t *)AlignedP;
78  size_t Adjustment = AlignedP - P;
79 
80  Head->Used += Size + Adjustment;
81  if (Head->Used <= Head->Capacity)
82  return new (PP) T[Count]();
83 
84  addNode(std::max(AllocUnit, Size));
85  Head->Used = Size;
86  return new (Head->Buf) T[Count]();
87  }
88 
89  template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
90  constexpr size_t Size = sizeof(T);
91  assert(Head && Head->Buf);
92 
93  size_t P = (size_t)Head->Buf + Head->Used;
94  uintptr_t AlignedP =
95  (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
96  uint8_t *PP = (uint8_t *)AlignedP;
97  size_t Adjustment = AlignedP - P;
98 
99  Head->Used += Size + Adjustment;
100  if (Head->Used <= Head->Capacity)
101  return new (PP) T(std::forward<Args>(ConstructorArgs)...);
102 
103  static_assert(Size < AllocUnit);
104  addNode(AllocUnit);
105  Head->Used = Size;
106  return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
107  }
108 
109 private:
110  AllocatorNode *Head = nullptr;
111 };
112 
114  static constexpr size_t Max = 10;
115 
117  size_t FunctionParamCount = 0;
118 
119  // The first 10 BackReferences in a mangled name can be back-referenced by
120  // special name @[0-9]. This is a storage for the first 10 BackReferences.
122  size_t NamesCount = 0;
123 };
124 
126 
127 enum NameBackrefBehavior : uint8_t {
128  NBB_None = 0, // don't save any names as backrefs.
129  NBB_Template = 1 << 0, // save template instanations.
130  NBB_Simple = 1 << 1, // save simple names.
131 };
132 
134 
135 // Demangler class takes the main role in demangling symbols.
136 // It has a set of functions to parse mangled symbols into Type instances.
137 // It also has a set of functions to convert Type instances to strings.
138 class Demangler {
139 public:
140  Demangler() = default;
141  virtual ~Demangler() = default;
142 
143  // You are supposed to call parse() first and then check if error is true. If
144  // it is false, call output() to write the formatted name to the given stream.
145  SymbolNode *parse(StringView &MangledName);
146 
148 
149  // True if an error occurred.
150  bool Error = false;
151 
152  void dumpBackReferences();
153 
154 private:
155  SymbolNode *demangleEncodedSymbol(StringView &MangledName,
156  QualifiedNameNode *QN);
157  SymbolNode *demangleDeclarator(StringView &MangledName);
158  SymbolNode *demangleMD5Name(StringView &MangledName);
159  SymbolNode *demangleTypeinfoName(StringView &MangledName);
160 
161  VariableSymbolNode *demangleVariableEncoding(StringView &MangledName,
162  StorageClass SC);
163  FunctionSymbolNode *demangleFunctionEncoding(StringView &MangledName);
164 
165  Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
166 
167  // Parser functions. This is a recursive-descent parser.
168  TypeNode *demangleType(StringView &MangledName, QualifierMangleMode QMM);
169  PrimitiveTypeNode *demanglePrimitiveType(StringView &MangledName);
170  CustomTypeNode *demangleCustomType(StringView &MangledName);
171  TagTypeNode *demangleClassType(StringView &MangledName);
172  PointerTypeNode *demanglePointerType(StringView &MangledName);
173  PointerTypeNode *demangleMemberPointerType(StringView &MangledName);
174  FunctionSignatureNode *demangleFunctionType(StringView &MangledName,
175  bool HasThisQuals);
176 
177  ArrayTypeNode *demangleArrayType(StringView &MangledName);
178 
179  NodeArrayNode *demangleFunctionParameterList(StringView &MangledName,
180  bool &IsVariadic);
181  NodeArrayNode *demangleTemplateParameterList(StringView &MangledName);
182 
183  std::pair<uint64_t, bool> demangleNumber(StringView &MangledName);
184  uint64_t demangleUnsigned(StringView &MangledName);
185  int64_t demangleSigned(StringView &MangledName);
186 
187  void memorizeString(StringView s);
188  void memorizeIdentifier(IdentifierNode *Identifier);
189 
190  /// Allocate a copy of \p Borrowed into memory that we own.
191  StringView copyString(StringView Borrowed);
192 
193  QualifiedNameNode *demangleFullyQualifiedTypeName(StringView &MangledName);
194  QualifiedNameNode *demangleFullyQualifiedSymbolName(StringView &MangledName);
195 
196  IdentifierNode *demangleUnqualifiedTypeName(StringView &MangledName,
197  bool Memorize);
198  IdentifierNode *demangleUnqualifiedSymbolName(StringView &MangledName,
199  NameBackrefBehavior NBB);
200 
201  QualifiedNameNode *demangleNameScopeChain(StringView &MangledName,
202  IdentifierNode *UnqualifiedName);
203  IdentifierNode *demangleNameScopePiece(StringView &MangledName);
204 
205  NamedIdentifierNode *demangleBackRefName(StringView &MangledName);
206  IdentifierNode *demangleTemplateInstantiationName(StringView &MangledName,
207  NameBackrefBehavior NBB);
209  translateIntrinsicFunctionCode(char CH, FunctionIdentifierCodeGroup Group);
210  IdentifierNode *demangleFunctionIdentifierCode(StringView &MangledName);
212  demangleFunctionIdentifierCode(StringView &MangledName,
214  StructorIdentifierNode *demangleStructorIdentifier(StringView &MangledName,
215  bool IsDestructor);
217  demangleConversionOperatorIdentifier(StringView &MangledName);
219  demangleLiteralOperatorIdentifier(StringView &MangledName);
220 
221  SymbolNode *demangleSpecialIntrinsic(StringView &MangledName);
223  demangleSpecialTableSymbolNode(StringView &MangledName,
226  demangleLocalStaticGuard(StringView &MangledName, bool IsThread);
227  VariableSymbolNode *demangleUntypedVariable(ArenaAllocator &Arena,
228  StringView &MangledName,
229  StringView VariableName);
231  demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
232  StringView &MangledName);
233  FunctionSymbolNode *demangleInitFiniStub(StringView &MangledName,
234  bool IsDestructor);
235 
236  NamedIdentifierNode *demangleSimpleName(StringView &MangledName,
237  bool Memorize);
238  NamedIdentifierNode *demangleAnonymousNamespaceName(StringView &MangledName);
239  NamedIdentifierNode *demangleLocallyScopedNamePiece(StringView &MangledName);
240  EncodedStringLiteralNode *demangleStringLiteral(StringView &MangledName);
241  FunctionSymbolNode *demangleVcallThunkNode(StringView &MangledName);
242 
243  StringView demangleSimpleString(StringView &MangledName, bool Memorize);
244 
245  FuncClass demangleFunctionClass(StringView &MangledName);
246  CallingConv demangleCallingConvention(StringView &MangledName);
247  StorageClass demangleVariableStorageClass(StringView &MangledName);
248  bool demangleThrowSpecification(StringView &MangledName);
249  wchar_t demangleWcharLiteral(StringView &MangledName);
250  uint8_t demangleCharLiteral(StringView &MangledName);
251 
252  std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
253 
254  // Memory allocator.
255  ArenaAllocator Arena;
256 
257  // A single type uses one global back-ref table for all function params.
258  // This means back-refs can even go "into" other types. Examples:
259  //
260  // // Second int* is a back-ref to first.
261  // void foo(int *, int*);
262  //
263  // // Second int* is not a back-ref to first (first is not a function param).
264  // int* foo(int*);
265  //
266  // // Second int* is a back-ref to first (ALL function types share the same
267  // // back-ref map.
268  // using F = void(*)(int*);
269  // F G(int *);
270  BackrefContext Backrefs;
271 };
272 
273 } // namespace ms_demangle
274 } // namespace llvm
275 
276 #endif // LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
llvm::ms_demangle::ArenaAllocator::allocUnalignedBuffer
char * allocUnalignedBuffer(size_t Size)
Definition: MicrosoftDemangle.h:56
llvm::ms_demangle::NameBackrefBehavior
NameBackrefBehavior
Definition: MicrosoftDemangle.h:127
llvm::ms_demangle::ArrayTypeNode
Definition: MicrosoftDemangleNodes.h:484
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::ms_demangle::BackrefContext::FunctionParams
TypeNode * FunctionParams[Max]
Definition: MicrosoftDemangle.h:116
llvm::ms_demangle::CustomTypeNode
Definition: MicrosoftDemangleNodes.h:505
llvm::ms_demangle::Demangler::dumpBackReferences
void dumpBackReferences()
Definition: MicrosoftDemangle.cpp:2300
llvm::ms_demangle::BackrefContext::NamesCount
size_t NamesCount
Definition: MicrosoftDemangle.h:122
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::ms_demangle::FunctionIdentifierCodeGroup
FunctionIdentifierCodeGroup
Definition: MicrosoftDemangle.h:133
CH
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference CH
Definition: README-X86-64.txt:44
llvm::ms_demangle::FunctionSignatureNode
Definition: MicrosoftDemangleNodes.h:322
llvm::ms_demangle::Demangler::~Demangler
virtual ~Demangler()=default
llvm::ms_demangle::ArenaAllocator::allocArray
T * allocArray(size_t Count)
Definition: MicrosoftDemangle.h:70
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::ms_demangle::Qualifiers
Qualifiers
Definition: MicrosoftDemangleNodes.h:34
size_t
llvm::ms_demangle::QualifiedNameNode
Definition: MicrosoftDemangleNodes.h:525
llvm::ms_demangle::StorageClass
StorageClass
Definition: MicrosoftDemangleNodes.h:45
llvm::ms_demangle::CallingConv
CallingConv
Definition: MicrosoftDemangleNodes.h:58
llvm::PPCISD::SC
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Definition: PPCISelLowering.h:419
llvm::ms_demangle::FunctionIdentifierCodeGroup::Basic
@ Basic
llvm::ms_demangle::IntrinsicFunctionKind
IntrinsicFunctionKind
Definition: MicrosoftDemangleNodes.h:117
llvm::ms_demangle::SpecialIntrinsicKind
SpecialIntrinsicKind
Definition: MicrosoftDemangleNodes.h:186
llvm::ms_demangle::FunctionIdentifierCodeGroup::DoubleUnder
@ DoubleUnder
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::ms_demangle::Demangler::Demangler
Demangler()=default
Definition: DLangDemangle.cpp:539
llvm::ms_demangle::ArenaAllocator::alloc
T * alloc(Args &&... ConstructorArgs)
Definition: MicrosoftDemangle.h:89
llvm::ms_demangle::LocalStaticGuardVariableNode
Definition: MicrosoftDemangleNodes.h:590
llvm::ms_demangle::QualifierMangleMode::Drop
@ Drop
llvm::ms_demangle::AllocUnit
constexpr size_t AllocUnit
Definition: MicrosoftDemangle.h:24
llvm::ms_demangle::QualifierMangleMode
QualifierMangleMode
Definition: MicrosoftDemangle.h:125
llvm::ms_demangle::IdentifierNode
Definition: MicrosoftDemangleNodes.h:354
llvm::ms_demangle::TagTypeNode
Definition: MicrosoftDemangleNodes.h:474
StringView.h
llvm::ms_demangle::SymbolNode
Definition: MicrosoftDemangleNodes.h:575
llvm::ms_demangle::ConversionOperatorIdentifierNode
Definition: MicrosoftDemangleNodes.h:419
llvm::ms_demangle::NamedIdentifierNode
Definition: MicrosoftDemangleNodes.h:382
llvm::ms_demangle::PrimitiveTypeNode
Definition: MicrosoftDemangleNodes.h:312
uint64_t
llvm::ms_demangle::BackrefContext::Names
NamedIdentifierNode * Names[Max]
Definition: MicrosoftDemangle.h:121
llvm::ms_demangle::LiteralOperatorIdentifierNode
Definition: MicrosoftDemangleNodes.h:400
llvm::ms_demangle::FunctionIdentifierCodeGroup::Under
@ Under
s
multiplies can be turned into SHL s
Definition: README.txt:370
llvm::ms_demangle::SpecialTableSymbolNode
Definition: MicrosoftDemangleNodes.h:581
MicrosoftDemangleNodes.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::ms_demangle::PointerTypeNode
Definition: MicrosoftDemangleNodes.h:458
llvm::ms_demangle::ArenaAllocator::ArenaAllocator
ArenaAllocator()
Definition: MicrosoftDemangle.h:44
llvm::ms_demangle::FuncClass
FuncClass
Definition: MicrosoftDemangleNodes.h:208
llvm::ms_demangle::BackrefContext
Definition: MicrosoftDemangle.h:113
llvm::ms_demangle::NBB_None
@ NBB_None
Definition: MicrosoftDemangle.h:128
llvm::ms_demangle::Demangler
Definition: MicrosoftDemangle.h:138
llvm::ms_demangle::Demangler::parseTagUniqueName
TagTypeNode * parseTagUniqueName(StringView &MangledName)
Definition: MicrosoftDemangle.cpp:828
llvm::ms_demangle::QualifierMangleMode::Mangle
@ Mangle
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::ms_demangle::ArenaAllocator
Definition: MicrosoftDemangle.h:26
llvm::ms_demangle::Demangler::parse
SymbolNode * parse(StringView &MangledName)
Definition: MicrosoftDemangle.cpp:802
llvm::ms_demangle::BackrefContext::Max
static constexpr size_t Max
Definition: MicrosoftDemangle.h:114
llvm::ms_demangle::StructorIdentifierNode
Definition: MicrosoftDemangleNodes.h:429
llvm::ms_demangle::NodeArrayNode
Definition: MicrosoftDemangleNodes.h:514
llvm::ms_demangle::NBB_Simple
@ NBB_Simple
Definition: MicrosoftDemangle.h:130
StringView
Definition: StringView.h:25
llvm::ms_demangle::VariableSymbolNode
Definition: MicrosoftDemangleNodes.h:609
llvm::ms_demangle::NBB_Template
@ NBB_Template
Definition: MicrosoftDemangle.h:129
llvm::ms_demangle::TypeNode
Definition: MicrosoftDemangleNodes.h:298
llvm::ms_demangle::BackrefContext::FunctionParamCount
size_t FunctionParamCount
Definition: MicrosoftDemangle.h:117
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::ms_demangle::ArenaAllocator::~ArenaAllocator
~ArenaAllocator()
Definition: MicrosoftDemangle.h:46
llvm::ms_demangle::EncodedStringLiteralNode
Definition: MicrosoftDemangleNodes.h:599
llvm::ms_demangle::FunctionSymbolNode
Definition: MicrosoftDemangleNodes.h:618