LLVM  14.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 
15 #include "llvm/Demangle/Utility.h"
16 
17 #include <utility>
18 
19 namespace llvm {
20 namespace ms_demangle {
21 // This memory allocator is extremely fast, but it doesn't call dtors
22 // for allocated objects. That means you can't use STL containers
23 // (such as std::vector) with this allocator. But it pays off --
24 // the demangler is 3x faster with this allocator compared to one with
25 // STL containers.
26 constexpr size_t AllocUnit = 4096;
27 
29  struct AllocatorNode {
30  uint8_t *Buf = nullptr;
31  size_t Used = 0;
32  size_t Capacity = 0;
33  AllocatorNode *Next = nullptr;
34  };
35 
36  void addNode(size_t Capacity) {
37  AllocatorNode *NewHead = new AllocatorNode;
38  NewHead->Buf = new uint8_t[Capacity];
39  NewHead->Next = Head;
40  NewHead->Capacity = Capacity;
41  Head = NewHead;
42  NewHead->Used = 0;
43  }
44 
45 public:
46  ArenaAllocator() { addNode(AllocUnit); }
47 
49  while (Head) {
50  assert(Head->Buf);
51  delete[] Head->Buf;
52  AllocatorNode *Next = Head->Next;
53  delete Head;
54  Head = Next;
55  }
56  }
57 
58  char *allocUnalignedBuffer(size_t Size) {
59  assert(Head && Head->Buf);
60 
61  uint8_t *P = Head->Buf + Head->Used;
62 
63  Head->Used += Size;
64  if (Head->Used <= Head->Capacity)
65  return reinterpret_cast<char *>(P);
66 
67  addNode(std::max(AllocUnit, Size));
68  Head->Used = Size;
69  return reinterpret_cast<char *>(Head->Buf);
70  }
71 
72  template <typename T, typename... Args> T *allocArray(size_t Count) {
73  size_t Size = Count * sizeof(T);
74  assert(Head && Head->Buf);
75 
76  size_t P = (size_t)Head->Buf + Head->Used;
77  uintptr_t AlignedP =
78  (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
79  uint8_t *PP = (uint8_t *)AlignedP;
80  size_t Adjustment = AlignedP - P;
81 
82  Head->Used += Size + Adjustment;
83  if (Head->Used <= Head->Capacity)
84  return new (PP) T[Count]();
85 
86  addNode(std::max(AllocUnit, Size));
87  Head->Used = Size;
88  return new (Head->Buf) T[Count]();
89  }
90 
91  template <typename T, typename... Args> T *alloc(Args &&... ConstructorArgs) {
92  constexpr size_t Size = sizeof(T);
93  assert(Head && Head->Buf);
94 
95  size_t P = (size_t)Head->Buf + Head->Used;
96  uintptr_t AlignedP =
97  (((size_t)P + alignof(T) - 1) & ~(size_t)(alignof(T) - 1));
98  uint8_t *PP = (uint8_t *)AlignedP;
99  size_t Adjustment = AlignedP - P;
100 
101  Head->Used += Size + Adjustment;
102  if (Head->Used <= Head->Capacity)
103  return new (PP) T(std::forward<Args>(ConstructorArgs)...);
104 
105  static_assert(Size < AllocUnit, "");
106  addNode(AllocUnit);
107  Head->Used = Size;
108  return new (Head->Buf) T(std::forward<Args>(ConstructorArgs)...);
109  }
110 
111 private:
112  AllocatorNode *Head = nullptr;
113 };
114 
116  static constexpr size_t Max = 10;
117 
119  size_t FunctionParamCount = 0;
120 
121  // The first 10 BackReferences in a mangled name can be back-referenced by
122  // special name @[0-9]. This is a storage for the first 10 BackReferences.
124  size_t NamesCount = 0;
125 };
126 
128 
129 enum NameBackrefBehavior : uint8_t {
130  NBB_None = 0, // don't save any names as backrefs.
131  NBB_Template = 1 << 0, // save template instanations.
132  NBB_Simple = 1 << 1, // save simple names.
133 };
134 
136 
137 // Demangler class takes the main role in demangling symbols.
138 // It has a set of functions to parse mangled symbols into Type instances.
139 // It also has a set of functions to convert Type instances to strings.
140 class Demangler {
141 public:
142  Demangler() = default;
143  virtual ~Demangler() = default;
144 
145  // You are supposed to call parse() first and then check if error is true. If
146  // it is false, call output() to write the formatted name to the given stream.
147  SymbolNode *parse(StringView &MangledName);
148 
150 
151  // True if an error occurred.
152  bool Error = false;
153 
154  void dumpBackReferences();
155 
156 private:
157  SymbolNode *demangleEncodedSymbol(StringView &MangledName,
158  QualifiedNameNode *QN);
159  SymbolNode *demangleDeclarator(StringView &MangledName);
160  SymbolNode *demangleMD5Name(StringView &MangledName);
161  SymbolNode *demangleTypeinfoName(StringView &MangledName);
162 
163  VariableSymbolNode *demangleVariableEncoding(StringView &MangledName,
164  StorageClass SC);
165  FunctionSymbolNode *demangleFunctionEncoding(StringView &MangledName);
166 
167  Qualifiers demanglePointerExtQualifiers(StringView &MangledName);
168 
169  // Parser functions. This is a recursive-descent parser.
170  TypeNode *demangleType(StringView &MangledName, QualifierMangleMode QMM);
171  PrimitiveTypeNode *demanglePrimitiveType(StringView &MangledName);
172  CustomTypeNode *demangleCustomType(StringView &MangledName);
173  TagTypeNode *demangleClassType(StringView &MangledName);
174  PointerTypeNode *demanglePointerType(StringView &MangledName);
175  PointerTypeNode *demangleMemberPointerType(StringView &MangledName);
176  FunctionSignatureNode *demangleFunctionType(StringView &MangledName,
177  bool HasThisQuals);
178 
179  ArrayTypeNode *demangleArrayType(StringView &MangledName);
180 
181  NodeArrayNode *demangleFunctionParameterList(StringView &MangledName,
182  bool &IsVariadic);
183  NodeArrayNode *demangleTemplateParameterList(StringView &MangledName);
184 
185  std::pair<uint64_t, bool> demangleNumber(StringView &MangledName);
186  uint64_t demangleUnsigned(StringView &MangledName);
187  int64_t demangleSigned(StringView &MangledName);
188 
189  void memorizeString(StringView s);
190  void memorizeIdentifier(IdentifierNode *Identifier);
191 
192  /// Allocate a copy of \p Borrowed into memory that we own.
193  StringView copyString(StringView Borrowed);
194 
195  QualifiedNameNode *demangleFullyQualifiedTypeName(StringView &MangledName);
196  QualifiedNameNode *demangleFullyQualifiedSymbolName(StringView &MangledName);
197 
198  IdentifierNode *demangleUnqualifiedTypeName(StringView &MangledName,
199  bool Memorize);
200  IdentifierNode *demangleUnqualifiedSymbolName(StringView &MangledName,
201  NameBackrefBehavior NBB);
202 
203  QualifiedNameNode *demangleNameScopeChain(StringView &MangledName,
204  IdentifierNode *UnqualifiedName);
205  IdentifierNode *demangleNameScopePiece(StringView &MangledName);
206 
207  NamedIdentifierNode *demangleBackRefName(StringView &MangledName);
208  IdentifierNode *demangleTemplateInstantiationName(StringView &MangledName,
209  NameBackrefBehavior NBB);
211  translateIntrinsicFunctionCode(char CH, FunctionIdentifierCodeGroup Group);
212  IdentifierNode *demangleFunctionIdentifierCode(StringView &MangledName);
214  demangleFunctionIdentifierCode(StringView &MangledName,
216  StructorIdentifierNode *demangleStructorIdentifier(StringView &MangledName,
217  bool IsDestructor);
219  demangleConversionOperatorIdentifier(StringView &MangledName);
221  demangleLiteralOperatorIdentifier(StringView &MangledName);
222 
223  SymbolNode *demangleSpecialIntrinsic(StringView &MangledName);
225  demangleSpecialTableSymbolNode(StringView &MangledName,
228  demangleLocalStaticGuard(StringView &MangledName, bool IsThread);
229  VariableSymbolNode *demangleUntypedVariable(ArenaAllocator &Arena,
230  StringView &MangledName,
231  StringView VariableName);
233  demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
234  StringView &MangledName);
235  FunctionSymbolNode *demangleInitFiniStub(StringView &MangledName,
236  bool IsDestructor);
237 
238  NamedIdentifierNode *demangleSimpleName(StringView &MangledName,
239  bool Memorize);
240  NamedIdentifierNode *demangleAnonymousNamespaceName(StringView &MangledName);
241  NamedIdentifierNode *demangleLocallyScopedNamePiece(StringView &MangledName);
242  EncodedStringLiteralNode *demangleStringLiteral(StringView &MangledName);
243  FunctionSymbolNode *demangleVcallThunkNode(StringView &MangledName);
244 
245  StringView demangleSimpleString(StringView &MangledName, bool Memorize);
246 
247  FuncClass demangleFunctionClass(StringView &MangledName);
248  CallingConv demangleCallingConvention(StringView &MangledName);
249  StorageClass demangleVariableStorageClass(StringView &MangledName);
250  bool demangleThrowSpecification(StringView &MangledName);
251  wchar_t demangleWcharLiteral(StringView &MangledName);
252  uint8_t demangleCharLiteral(StringView &MangledName);
253 
254  std::pair<Qualifiers, bool> demangleQualifiers(StringView &MangledName);
255 
256  // Memory allocator.
257  ArenaAllocator Arena;
258 
259  // A single type uses one global back-ref table for all function params.
260  // This means back-refs can even go "into" other types. Examples:
261  //
262  // // Second int* is a back-ref to first.
263  // void foo(int *, int*);
264  //
265  // // Second int* is not a back-ref to first (first is not a function param).
266  // int* foo(int*);
267  //
268  // // Second int* is a back-ref to first (ALL function types share the same
269  // // back-ref map.
270  // using F = void(*)(int*);
271  // F G(int *);
272  BackrefContext Backrefs;
273 };
274 
275 } // namespace ms_demangle
276 } // namespace llvm
277 
278 #endif // LLVM_DEMANGLE_MICROSOFTDEMANGLE_H
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::ms_demangle::ArenaAllocator::allocUnalignedBuffer
char * allocUnalignedBuffer(size_t Size)
Definition: MicrosoftDemangle.h:58
llvm::ms_demangle::NameBackrefBehavior
NameBackrefBehavior
Definition: MicrosoftDemangle.h:129
llvm::ms_demangle::ArrayTypeNode
Definition: MicrosoftDemangleNodes.h:486
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::ms_demangle::BackrefContext::FunctionParams
TypeNode * FunctionParams[Max]
Definition: MicrosoftDemangle.h:118
llvm::ms_demangle::CustomTypeNode
Definition: MicrosoftDemangleNodes.h:507
llvm::ms_demangle::Demangler::dumpBackReferences
void dumpBackReferences()
Definition: MicrosoftDemangle.cpp:2311
llvm::ms_demangle::BackrefContext::NamesCount
size_t NamesCount
Definition: MicrosoftDemangle.h:124
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:135
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:324
llvm::ms_demangle::Demangler::~Demangler
virtual ~Demangler()=default
Utility.h
llvm::ms_demangle::ArenaAllocator::allocArray
T * allocArray(size_t Count)
Definition: MicrosoftDemangle.h:72
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::ms_demangle::Qualifiers
Qualifiers
Definition: MicrosoftDemangleNodes.h:35
size_t
llvm::ms_demangle::QualifiedNameNode
Definition: MicrosoftDemangleNodes.h:527
llvm::ms_demangle::StorageClass
StorageClass
Definition: MicrosoftDemangleNodes.h:46
llvm::ms_demangle::CallingConv
CallingConv
Definition: MicrosoftDemangleNodes.h:59
llvm::PPCISD::SC
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Definition: PPCISelLowering.h:410
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: RustDemangle.cpp:202
llvm::ms_demangle::ArenaAllocator::alloc
T * alloc(Args &&... ConstructorArgs)
Definition: MicrosoftDemangle.h:91
llvm::ms_demangle::LocalStaticGuardVariableNode
Definition: MicrosoftDemangleNodes.h:592
llvm::ms_demangle::QualifierMangleMode::Drop
@ Drop
llvm::ms_demangle::AllocUnit
constexpr size_t AllocUnit
Definition: MicrosoftDemangle.h:26
llvm::ms_demangle::QualifierMangleMode
QualifierMangleMode
Definition: MicrosoftDemangle.h:127
llvm::ms_demangle::IdentifierNode
Definition: MicrosoftDemangleNodes.h:356
llvm::ms_demangle::TagTypeNode
Definition: MicrosoftDemangleNodes.h:476
StringView.h
llvm::ms_demangle::SymbolNode
Definition: MicrosoftDemangleNodes.h:577
llvm::ms_demangle::ConversionOperatorIdentifierNode
Definition: MicrosoftDemangleNodes.h:421
llvm::ms_demangle::NamedIdentifierNode
Definition: MicrosoftDemangleNodes.h:384
llvm::ms_demangle::PrimitiveTypeNode
Definition: MicrosoftDemangleNodes.h:314
uint64_t
llvm::ms_demangle::BackrefContext::Names
NamedIdentifierNode * Names[Max]
Definition: MicrosoftDemangle.h:123
llvm::ms_demangle::LiteralOperatorIdentifierNode
Definition: MicrosoftDemangleNodes.h:402
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:583
MicrosoftDemangleNodes.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::ms_demangle::PointerTypeNode
Definition: MicrosoftDemangleNodes.h:460
llvm::ms_demangle::ArenaAllocator::ArenaAllocator
ArenaAllocator()
Definition: MicrosoftDemangle.h:46
llvm::ms_demangle::FuncClass
FuncClass
Definition: MicrosoftDemangleNodes.h:208
llvm::ms_demangle::BackrefContext
Definition: MicrosoftDemangle.h:115
llvm::ms_demangle::NBB_None
@ NBB_None
Definition: MicrosoftDemangle.h:130
llvm::ms_demangle::Demangler
Definition: MicrosoftDemangle.h:140
DemangleConfig.h
llvm::ms_demangle::Demangler::parseTagUniqueName
TagTypeNode * parseTagUniqueName(StringView &MangledName)
Definition: MicrosoftDemangle.cpp:825
llvm::ms_demangle::QualifierMangleMode::Mangle
@ Mangle
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::ms_demangle::ArenaAllocator
Definition: MicrosoftDemangle.h:28
llvm::ms_demangle::Demangler::parse
SymbolNode * parse(StringView &MangledName)
Definition: MicrosoftDemangle.cpp:799
llvm::ms_demangle::BackrefContext::Max
static constexpr size_t Max
Definition: MicrosoftDemangle.h:116
llvm::ms_demangle::StructorIdentifierNode
Definition: MicrosoftDemangleNodes.h:431
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::ms_demangle::NodeArrayNode
Definition: MicrosoftDemangleNodes.h:516
llvm::ms_demangle::NBB_Simple
@ NBB_Simple
Definition: MicrosoftDemangle.h:132
StringView
Definition: StringView.h:23
llvm::ms_demangle::VariableSymbolNode
Definition: MicrosoftDemangleNodes.h:611
llvm::ms_demangle::NBB_Template
@ NBB_Template
Definition: MicrosoftDemangle.h:131
llvm::ms_demangle::TypeNode
Definition: MicrosoftDemangleNodes.h:300
llvm::ms_demangle::BackrefContext::FunctionParamCount
size_t FunctionParamCount
Definition: MicrosoftDemangle.h:119
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::ms_demangle::ArenaAllocator::~ArenaAllocator
~ArenaAllocator()
Definition: MicrosoftDemangle.h:48
llvm::ms_demangle::EncodedStringLiteralNode
Definition: MicrosoftDemangleNodes.h:601
llvm::ms_demangle::FunctionSymbolNode
Definition: MicrosoftDemangleNodes.h:620