Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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
 
12
#include "llvm/Demangle/MicrosoftDemangleNodes.h"
13
#include "llvm/Demangle/StringView.h"
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
 
26
class ArenaAllocator {
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
 
46
  ~ArenaAllocator() {
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
 
113
struct BackrefContext {
114
  static constexpr size_t Max = 10;
115
 
116
  TypeNode *FunctionParams[Max];
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.
121
  NamedIdentifierNode *Names[Max];
122
  size_t NamesCount = 0;
123
};
124
 
125
enum class QualifierMangleMode { Drop, Mangle, Result };
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
 
133
enum class FunctionIdentifierCodeGroup { Basic, Under, DoubleUnder };
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
 
147
  TagTypeNode *parseTagUniqueName(StringView &MangledName);
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);
208
  IntrinsicFunctionKind
209
  translateIntrinsicFunctionCode(char CH, FunctionIdentifierCodeGroup Group);
210
  IdentifierNode *demangleFunctionIdentifierCode(StringView &MangledName);
211
  IdentifierNode *
212
  demangleFunctionIdentifierCode(StringView &MangledName,
213
                                 FunctionIdentifierCodeGroup Group);
214
  StructorIdentifierNode *demangleStructorIdentifier(StringView &MangledName,
215
                                                     bool IsDestructor);
216
  ConversionOperatorIdentifierNode *
217
  demangleConversionOperatorIdentifier(StringView &MangledName);
218
  LiteralOperatorIdentifierNode *
219
  demangleLiteralOperatorIdentifier(StringView &MangledName);
220
 
221
  SymbolNode *demangleSpecialIntrinsic(StringView &MangledName);
222
  SpecialTableSymbolNode *
223
  demangleSpecialTableSymbolNode(StringView &MangledName,
224
                                 SpecialIntrinsicKind SIK);
225
  LocalStaticGuardVariableNode *
226
  demangleLocalStaticGuard(StringView &MangledName, bool IsThread);
227
  VariableSymbolNode *demangleUntypedVariable(ArenaAllocator &Arena,
228
                                              StringView &MangledName,
229
                                              StringView VariableName);
230
  VariableSymbolNode *
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