@@ -35,6 +35,8 @@ using llvm::StringRef;
35
35
namespace swift {
36
36
namespace Demangle {
37
37
38
+ class CharVector ;
39
+
38
40
// / The allocator for demangling nodes and other demangling-internal stuff.
39
41
// /
40
42
// / It implements a simple bump-pointer allocator.
@@ -77,15 +79,15 @@ class NodeFactory {
77
79
#endif
78
80
}
79
81
80
- ~NodeFactory () {
82
+ virtual ~NodeFactory () {
81
83
freeSlabs (CurrentSlab);
82
84
#ifdef NODE_FACTORY_DEBUGGING
83
85
std::cerr << " Delete NodeFactory " << this << " \n " ;
84
86
#endif
85
87
}
86
88
87
- void clear ();
88
-
89
+ virtual void clear ();
90
+
89
91
// / Allocates an object of type T or an array of objects of type T.
90
92
template <typename T> T *Allocate (size_t NumObjects = 1 ) {
91
93
size_t ObjectSize = NumObjects * sizeof (T);
@@ -173,13 +175,105 @@ class NodeFactory {
173
175
// / The \p Text string is copied.
174
176
NodePointer createNode (Node::Kind K, llvm::StringRef Text);
175
177
178
+ // / Creates a node of kind \p K with a \p Text payload.
179
+ // /
180
+ // / The \p Text string is already allocted with the Factory and therefore
181
+ // / it is _not_ copied.
182
+ NodePointer createNode (Node::Kind K, const CharVector &Text);
183
+
176
184
// / Creates a node of kind \p K with a \p Text payload, which must be a C
177
185
// / string literal.
178
186
// /
179
187
// / The \p Text string is _not_ copied.
180
188
NodePointer createNode (Node::Kind K, const char *Text);
181
189
};
182
190
191
+ // / A vector with a storage managed by a NodeFactory.
192
+ // /
193
+ // / This Vector class only provides the minimal functionality needed by the
194
+ // / Demangler.
195
+ template <typename T> class Vector {
196
+
197
+ protected:
198
+ T *Elems = nullptr ;
199
+ size_t NumElems = 0 ;
200
+ size_t Capacity = 0 ;
201
+
202
+ public:
203
+
204
+ typedef T *iterator;
205
+
206
+ Vector () { }
207
+
208
+ // / Construct a vector with an inital capacity.
209
+ explicit Vector (NodeFactory &Factory, size_t InitialCapacity) {
210
+ init (Factory, InitialCapacity);
211
+ }
212
+
213
+ // / Clears the content and re-allocates the buffer with an initial capacity.
214
+ void init (NodeFactory &Factory, size_t InitialCapacity) {
215
+ Elems = Factory.Allocate <T>(InitialCapacity);
216
+ NumElems = 0 ;
217
+ Capacity = InitialCapacity;
218
+ }
219
+
220
+ void free () {
221
+ Capacity = 0 ;
222
+ Elems = 0 ;
223
+ }
224
+
225
+ iterator begin () { return Elems; }
226
+ iterator end () { return Elems + NumElems; }
227
+
228
+ T &operator [](size_t Idx) {
229
+ assert (Idx < NumElems);
230
+ return Elems[Idx];
231
+ }
232
+
233
+ const T &operator [](size_t Idx) const {
234
+ assert (Idx < NumElems);
235
+ return Elems[Idx];
236
+ }
237
+
238
+ size_t size () const { return NumElems; }
239
+
240
+ bool empty () const { return NumElems == 0 ; }
241
+
242
+ T &back () { return (*this )[NumElems - 1 ]; }
243
+
244
+ void push_back (const T &NewElem, NodeFactory &Factory) {
245
+ if (NumElems >= Capacity)
246
+ Factory.Reallocate (Elems, Capacity, /* Growth*/ 1 );
247
+ assert (NumElems < Capacity);
248
+ Elems[NumElems++] = NewElem;
249
+ }
250
+
251
+ T pop_back_val () {
252
+ if (empty ())
253
+ return T ();
254
+ T Val = (*this )[NumElems - 1 ];
255
+ NumElems--;
256
+ return Val;
257
+ }
258
+ };
259
+
260
+ // / A vector of chars (a string) with a storage managed by a NodeFactory.
261
+ // /
262
+ // / This CharVector class only provides the minimal functionality needed by the
263
+ // / Demangler.
264
+ class CharVector : public Vector <char > {
265
+ public:
266
+ // Append another string.
267
+ void append (StringRef Rhs, NodeFactory &Factory);
268
+
269
+ // Append an integer as readable number.
270
+ void append (int Number, NodeFactory &Factory);
271
+
272
+ StringRef str () const {
273
+ return StringRef (Elems, NumElems);
274
+ }
275
+ };
276
+
183
277
// / The demangler.
184
278
// /
185
279
// / It de-mangles a string and it also ownes the returned node-tree. This means
@@ -194,22 +288,14 @@ class Demangler : public NodeFactory {
194
288
size_t Pos;
195
289
};
196
290
197
- std::vector <NodeWithPos> NodeStack;
198
- std::vector <NodePointer> Substitutions;
199
- std::vector <unsigned > PendingSubstitutions;
291
+ Vector <NodeWithPos> NodeStack;
292
+ Vector <NodePointer> Substitutions;
293
+ Vector <unsigned > PendingSubstitutions;
200
294
201
295
static const int MaxNumWords = 26 ;
202
296
StringRef Words[MaxNumWords];
203
297
int NumWords = 0 ;
204
298
205
- static NodePointer pop_back_val (std::vector<NodePointer> &NodeVector) {
206
- if (NodeVector.empty ())
207
- return nullptr ;
208
- NodePointer Val = NodeVector.back ();
209
- NodeVector.pop_back ();
210
- return Val;
211
- }
212
-
213
299
bool nextIf (StringRef str) {
214
300
if (!Text.substr (Pos).startswith (str)) return false ;
215
301
Pos += str.size ();
@@ -241,16 +327,11 @@ class Demangler : public NodeFactory {
241
327
}
242
328
243
329
void pushNode (NodePointer Nd) {
244
- NodeStack.push_back ({ Nd, Pos });
330
+ NodeStack.push_back ({ Nd, Pos }, * this );
245
331
}
246
332
247
333
NodePointer popNode () {
248
- if (!NodeStack.empty ()) {
249
- NodePointer Val = NodeStack.back ().Node ;
250
- NodeStack.pop_back ();
251
- return Val;
252
- }
253
- return nullptr ;
334
+ return NodeStack.pop_back_val ().Node ;
254
335
}
255
336
256
337
NodePointer popNode (Node::Kind kind) {
@@ -279,7 +360,7 @@ class Demangler : public NodeFactory {
279
360
280
361
void addSubstitution (NodePointer Nd) {
281
362
if (Nd)
282
- Substitutions.push_back (Nd);
363
+ Substitutions.push_back (Nd, * this );
283
364
}
284
365
285
366
NodePointer addChild (NodePointer Parent, NodePointer Child);
@@ -326,7 +407,7 @@ class Demangler : public NodeFactory {
326
407
NodePointer popProtocol ();
327
408
NodePointer demangleBoundGenericType ();
328
409
NodePointer demangleBoundGenericArgs (NodePointer nominalType,
329
- const std::vector <NodePointer> &TypeLists,
410
+ const Vector <NodePointer> &TypeLists,
330
411
size_t TypeListIdx);
331
412
NodePointer demangleInitializer ();
332
413
NodePointer demangleImplParamConvention ();
@@ -367,6 +448,8 @@ class Demangler : public NodeFactory {
367
448
368
449
public:
369
450
Demangler () {}
451
+
452
+ void clear () override ;
370
453
371
454
// / Demangle the given symbol and return the parse tree.
372
455
// /
0 commit comments