1 //===--- Demangler.h - String to Node-Tree Demangling -----------*- C++ -*-===//
2 //
3 // This source file is part of the Swift.org open source project
4 //
5 // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6 // Licensed under Apache License v2.0 with Runtime Library Exception
7 //
8 // See https://swift.org/LICENSE.txt for license information
9 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10 //
11 //===----------------------------------------------------------------------===//
12 //
13 // This file is the compiler-private API of the demangler.
14 // It should only be used within the swift compiler or runtime library, but not
15 // by external tools which use the demangler library (like lldb).
16 //
17 //===----------------------------------------------------------------------===//
18 
19 #ifndef SWIFT_DEMANGLING_DEMANGLER_H
20 #define SWIFT_DEMANGLING_DEMANGLER_H
21 
22 #include "swift/Demangling/Demangle.h"
23 
24 //#define NODE_FACTORY_DEBUGGING
25 
26 using namespace swift::Demangle;
27 using llvm::StringRef;
28 
29 namespace swift {
30 namespace Demangle {
31 
32 class CharVector;
33 
34 /// The allocator for demangling nodes and other demangling-internal stuff.
35 ///
36 /// It implements a simple bump-pointer allocator.
37 class NodeFactory {
38 
39   /// Position in the current slab.
40   char *CurPtr = nullptr;
41 
42   /// The end of the current slab.
43   char *End = nullptr;
44 
45   struct Slab {
46     // The previously allocated slab.
47     Slab *Previous;
48     // Tail allocated memory starts here.
49   };
50 
51   /// The head of the single-linked slab list.
52   Slab *CurrentSlab = nullptr;
53 
54   /// The size of the previously allocated slab.
55   ///
56   /// The slab size can only grow, even clear() does not reset the slab size.
57   /// This initial size is good enough to fit most de-manglings.
58   size_t SlabSize = 100 * sizeof(Node);
59 
align(char * Ptr,size_t Alignment)60   static char *align(char *Ptr, size_t Alignment) {
61     assert(Alignment > 0);
62     return (char*)(((uintptr_t)Ptr + Alignment - 1)
63                      & ~((uintptr_t)Alignment - 1));
64   }
65 
66   static void freeSlabs(Slab *slab);
67 
68   /// If not null, the NodeFactory from which this factory borrowed free memory.
69   NodeFactory *BorrowedFrom = nullptr;
70 
71   /// True if some other NodeFactory borrowed free memory from this factory.
72   bool isBorrowed = false;
73 
74 #ifdef NODE_FACTORY_DEBUGGING
75   size_t allocatedMemory = 0;
76   static int nestingLevel;
indent()77   std::string indent() { return std::string(nestingLevel * 2, ' '); }
78 #endif
79 
80 public:
81 
NodeFactory()82   NodeFactory() {
83 #ifdef NODE_FACTORY_DEBUGGING
84     fprintf(stderr, "%s## New NodeFactory\n", indent().c_str());
85     nestingLevel++;
86 #endif
87   }
88 
89   /// Provide pre-allocated memory, e.g. memory on the stack.
90   ///
91   /// Only if this memory overflows, the factory begins to malloc.
providePreallocatedMemory(char * Memory,size_t Size)92   void providePreallocatedMemory(char *Memory, size_t Size) {
93 #ifdef NODE_FACTORY_DEBUGGING
94     fprintf(stderr, "%s++ provide preallocated memory, size = %zu\n", indent().c_str(), Size);
95 #endif
96     assert(!CurPtr && !End && !CurrentSlab);
97     CurPtr = Memory;
98     End = CurPtr + Size;
99   }
100 
101   /// Borrow free memory from another factory \p BorrowFrom.
102   ///
103   /// While this factory is alive, no allocations can be done in the
104   /// \p BorrowFrom factory.
providePreallocatedMemory(NodeFactory & BorrowFrom)105   void providePreallocatedMemory(NodeFactory &BorrowFrom) {
106     assert(!CurPtr && !End && !CurrentSlab);
107     assert(!BorrowFrom.isBorrowed && !BorrowedFrom);
108     BorrowFrom.isBorrowed = true;
109     BorrowedFrom = &BorrowFrom;
110     CurPtr = BorrowFrom.CurPtr;
111     End = BorrowFrom.End;
112 #ifdef NODE_FACTORY_DEBUGGING
113     fprintf(stderr, "%s++ borrow memory, size = %zu\n", indent().c_str(), (End - CurPtr));
114 #endif
115   }
116 
~NodeFactory()117   virtual ~NodeFactory() {
118     freeSlabs(CurrentSlab);
119 #ifdef NODE_FACTORY_DEBUGGING
120     nestingLevel--;
121     fprintf(stderr, "%s## Delete NodeFactory: allocated memory = %zu\n", indent().c_str(), allocatedMemory)
122 #endif
123     if (BorrowedFrom) {
124       BorrowedFrom->isBorrowed = false;
125     }
126   }
127 
128   virtual void clear();
129 
130   /// Allocates an object of type T or an array of objects of type T.
131   template<typename T> T *Allocate(size_t NumObjects = 1) {
132     assert(!isBorrowed);
133     size_t ObjectSize = NumObjects * sizeof(T);
134     CurPtr = align(CurPtr, alignof(T));
135 #ifdef NODE_FACTORY_DEBUGGING
136     fprintf(stderr, "%salloc %zu, CurPtr = %p\n", indent().c_str(), ObjectSize, (void *)CurPtr)
137     allocatedMemory += ObjectSize;
138 #endif
139 
140     // Do we have enough space in the current slab?
141     if (CurPtr + ObjectSize > End) {
142       // No. We have to malloc a new slab.
143       // We double the slab size for each allocated slab.
144       SlabSize = std::max(SlabSize * 2, ObjectSize + alignof(T));
145       size_t AllocSize = sizeof(Slab) + SlabSize;
146       Slab *newSlab = (Slab *)malloc(AllocSize);
147 
148       // Insert the new slab in the single-linked list of slabs.
149       newSlab->Previous = CurrentSlab;
150       CurrentSlab = newSlab;
151 
152       // Initialize the pointers to the new slab.
153       CurPtr = align((char *)(newSlab + 1), alignof(T));
154       End = (char *)newSlab + AllocSize;
155       assert(CurPtr + ObjectSize <= End);
156 #ifdef NODE_FACTORY_DEBUGGING
157       fprintf(stderr, "%s** new slab %p, allocsize = %zu, CurPtr = %p, End = %p\n",
158             indent().c_str(), newSlab, AllocSize, (void *)CurPtr, (void *)End);
159 #endif
160     }
161     T *AllocatedObj = (T *)CurPtr;
162     CurPtr += ObjectSize;
163     return AllocatedObj;
164   }
165 
166   /// Tries to enlarge the \p Capacity of an array of \p Objects.
167   ///
168   /// If \p Objects is allocated at the end of the current slab and the slab
169   /// has enough free space, the \p Capacity is simply enlarged and no new
170   /// allocation needs to be done.
171   /// Otherwise a new array of objects is allocated and \p Objects is set to the
172   /// new memory address.
173   /// The \p Capacity is enlarged at least by \p MinGrowth, but can also be
174   /// enlarged by a bigger value.
Reallocate(T * & Objects,uint32_t & Capacity,size_t MinGrowth)175   template<typename T> void Reallocate(T *&Objects, uint32_t &Capacity,
176                                        size_t MinGrowth) {
177     assert(!isBorrowed);
178     size_t OldAllocSize = Capacity * sizeof(T);
179     size_t AdditionalAlloc = MinGrowth * sizeof(T);
180 
181 #ifdef NODE_FACTORY_DEBUGGING
182     fprintf(stderr, "%srealloc: capacity = %d (size = %zu), growth = %zu (size = %zu)\n",
183           indent().c_str(), Capacity, OldAllocSize, MinGrowth, AdditionalAlloc);
184 #endif
185     if ((char *)Objects + OldAllocSize == CurPtr
186         && CurPtr + AdditionalAlloc <= End) {
187       // The existing array is at the end of the current slab and there is
188       // enough space. So we are fine.
189       CurPtr += AdditionalAlloc;
190       Capacity += MinGrowth;
191 #ifdef NODE_FACTORY_DEBUGGING
192       fprintf(stderr, "%s** can grow: %p\n", indent().c_str(), (void *)CurPtr);
193       allocatedMemory += AdditionalAlloc;
194 #endif
195       return;
196     }
197     // We need a new allocation.
198     size_t Growth = (MinGrowth >= 4 ? MinGrowth : 4);
199     if (Growth < Capacity * 2)
200       Growth = Capacity * 2;
201     T *NewObjects = Allocate<T>(Capacity + Growth);
202     memcpy(NewObjects, Objects, OldAllocSize);
203     Objects = NewObjects;
204     Capacity += Growth;
205   }
206 
207   /// Creates a node of kind \p K.
208   NodePointer createNode(Node::Kind K);
209 
210   /// Creates a node of kind \p K with an \p Index payload.
211   NodePointer createNode(Node::Kind K, Node::IndexType Index);
212 
213   /// Creates a node of kind \p K with a \p Text payload.
214   ///
215   /// The \p Text string must be already allocated with the Factory and therefore
216   /// it is _not_ copied.
217   NodePointer createNodeWithAllocatedText(Node::Kind K, llvm::StringRef Text);
218 
219   /// Creates a node of kind \p K with a \p Text payload.
220   ///
221   /// The \p Text string is copied.
createNode(Node::Kind K,llvm::StringRef Text)222   NodePointer createNode(Node::Kind K, llvm::StringRef Text) {
223     return createNodeWithAllocatedText(K, Text.copy(*this));
224   }
225 
226   /// Creates a node of kind \p K with a \p Text payload.
227   ///
228   /// The \p Text string is already allocated with the Factory and therefore
229   /// it is _not_ copied.
230   NodePointer createNode(Node::Kind K, const CharVector &Text);
231 
232   /// Creates a node of kind \p K with a \p Text payload, which must be a C
233   /// string literal.
234   ///
235   /// The \p Text string is _not_ copied.
236   NodePointer createNode(Node::Kind K, const char *Text);
237 };
238 
239 /// A vector with a storage managed by a NodeFactory.
240 ///
241 /// This Vector class only provides the minimal functionality needed by the
242 /// Demangler.
243 template<typename T> class Vector {
244 
245 protected:
246   T *Elems = nullptr;
247   uint32_t NumElems = 0;
248   uint32_t Capacity = 0;
249 
250 public:
251   using iterator = T *;
252 
Vector()253   Vector() { }
254 
255   /// Construct a vector with an initial capacity.
Vector(NodeFactory & Factory,size_t InitialCapacity)256   explicit Vector(NodeFactory &Factory, size_t InitialCapacity) {
257     init(Factory, InitialCapacity);
258   }
259 
260   /// Clears the content and re-allocates the buffer with an initial capacity.
init(NodeFactory & Factory,size_t InitialCapacity)261   void init(NodeFactory &Factory, size_t InitialCapacity) {
262     Elems = Factory.Allocate<T>(InitialCapacity);
263     NumElems = 0;
264     Capacity = InitialCapacity;
265   }
266 
free()267   void free() {
268     Capacity = 0;
269     Elems = 0;
270   }
271 
clear()272   void clear() {
273     NumElems = 0;
274   }
275 
begin()276   iterator begin() { return Elems; }
end()277   iterator end() { return Elems + NumElems; }
278 
279   T &operator[](size_t Idx) {
280     assert(Idx < NumElems);
281     return Elems[Idx];
282   }
283 
284   const T &operator[](size_t Idx) const {
285     assert(Idx < NumElems);
286     return Elems[Idx];
287   }
288 
size()289   size_t size() const { return NumElems; }
290 
empty()291   bool empty() const { return NumElems == 0; }
292 
back()293   T &back() { return (*this)[NumElems - 1]; }
294 
resetSize(size_t toPos)295   void resetSize(size_t toPos) {
296     assert(toPos <= NumElems);
297     NumElems = toPos;
298   }
299 
push_back(const T & NewElem,NodeFactory & Factory)300   void push_back(const T &NewElem, NodeFactory &Factory) {
301     if (NumElems >= Capacity)
302       Factory.Reallocate(Elems, Capacity, /*Growth*/ 1);
303     assert(NumElems < Capacity);
304     Elems[NumElems++] = NewElem;
305   }
306 
pop_back_val()307   T pop_back_val() {
308     if (empty())
309       return T();
310     T Val = (*this)[NumElems - 1];
311     NumElems--;
312     return Val;
313   }
314 };
315 
316 /// A vector of chars (a string) with a storage managed by a NodeFactory.
317 ///
318 /// This CharVector class only provides the minimal functionality needed by the
319 /// Demangler.
320 class CharVector : public Vector<char> {
321 public:
322   // Append another string.
323   void append(StringRef Rhs, NodeFactory &Factory);
324 
325   // Append an integer as readable number.
326   void append(int Number, NodeFactory &Factory);
327 
328   // Append an unsigned 64 bit integer as readable number.
329   void append(unsigned long long Number, NodeFactory &Factory);
330 
str()331   StringRef str() const {
332     return StringRef(Elems, NumElems);
333   }
334 };
335 
336 /// Kinds of symbolic reference supported.
337 enum class SymbolicReferenceKind : uint8_t {
338   /// A symbolic reference to a context descriptor, representing the
339   /// (unapplied generic) context.
340   Context,
341   /// A symbolic reference to an accessor function, which can be executed in
342   /// the process to get a pointer to the referenced entity.
343   AccessorFunctionReference,
344 };
345 
346 using SymbolicReferenceResolver_t = NodePointer (SymbolicReferenceKind,
347                                                  Directness,
348                                                  int32_t, const void *);
349 
350 /// The demangler.
351 ///
352 /// It de-mangles a string and it also owns the returned node-tree. This means
353 /// The nodes of the tree only live as long as the Demangler itself.
354 class Demangler : public NodeFactory {
355 protected:
356   StringRef Text;
357   size_t Pos = 0;
358 
359   /// Mangling style where function type would have
360   /// labels attached to it, instead of having them
361   /// as part of the name.
362   bool IsOldFunctionTypeMangling = false;
363 
364   Vector<NodePointer> NodeStack;
365   Vector<NodePointer> Substitutions;
366 
367   static const int MaxNumWords = 26;
368   StringRef Words[MaxNumWords];
369   int NumWords = 0;
370 
371   std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver;
372 
nextIf(StringRef str)373   bool nextIf(StringRef str) {
374     if (!Text.substr(Pos).startswith(str)) return false;
375     Pos += str.size();
376     return true;
377   }
378 
peekChar()379   char peekChar() {
380     if (Pos >= Text.size())
381       return 0;
382     return Text[Pos];
383   }
384 
nextChar()385   char nextChar() {
386     if (Pos >= Text.size())
387       return 0;
388     return Text[Pos++];
389   }
390 
nextIf(char c)391   bool nextIf(char c) {
392     if (peekChar() != c)
393       return false;
394     Pos++;
395     return true;
396   }
397 
pushBack()398   void pushBack() {
399     assert(Pos > 0);
400     Pos--;
401   }
402 
consumeAll()403   StringRef consumeAll() {
404     StringRef str = Text.drop_front(Pos);
405     Pos = Text.size();
406     return str;
407   }
408 
pushNode(NodePointer Nd)409   void pushNode(NodePointer Nd) {
410     NodeStack.push_back(Nd, *this);
411   }
412 
popNode()413   NodePointer popNode() {
414     return NodeStack.pop_back_val();
415   }
416 
popNode(Node::Kind kind)417   NodePointer popNode(Node::Kind kind) {
418     if (NodeStack.empty())
419       return nullptr;
420 
421     Node::Kind NdKind = NodeStack.back()->getKind();
422     if (NdKind != kind)
423       return nullptr;
424 
425     return popNode();
426   }
427 
popNode(Pred pred)428   template <typename Pred> NodePointer popNode(Pred pred) {
429     if (NodeStack.empty())
430       return nullptr;
431 
432     Node::Kind NdKind = NodeStack.back()->getKind();
433     if (!pred(NdKind))
434       return nullptr;
435 
436     return popNode();
437   }
438 
439   /// This class handles preparing the initial state for a demangle job in a reentrant way, pushing the
440   /// existing state back when a demangle job is completed.
441   class DemangleInitRAII {
442     Demangler &Dem;
443     Vector<NodePointer> NodeStack;
444     Vector<NodePointer> Substitutions;
445     int NumWords;
446     StringRef Text;
447     size_t Pos;
448     std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver;
449 
450   public:
451     DemangleInitRAII(Demangler &Dem, StringRef MangledName,
452          std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver);
453     ~DemangleInitRAII();
454   };
455   friend DemangleInitRAII;
456 
addSubstitution(NodePointer Nd)457   void addSubstitution(NodePointer Nd) {
458     if (Nd)
459       Substitutions.push_back(Nd, *this);
460   }
461 
462   NodePointer addChild(NodePointer Parent, NodePointer Child);
463   NodePointer createWithChild(Node::Kind kind, NodePointer Child);
464   NodePointer createType(NodePointer Child);
465   NodePointer createWithChildren(Node::Kind kind, NodePointer Child1,
466                                  NodePointer Child2);
467   NodePointer createWithChildren(Node::Kind kind, NodePointer Child1,
468                                  NodePointer Child2, NodePointer Child3);
469   NodePointer createWithChildren(Node::Kind kind, NodePointer Child1,
470                                  NodePointer Child2, NodePointer Child3,
471                                  NodePointer Child4);
createWithPoppedType(Node::Kind kind)472   NodePointer createWithPoppedType(Node::Kind kind) {
473     return createWithChild(kind, popNode(Node::Kind::Type));
474   }
475 
476   bool parseAndPushNodes();
477 
478   NodePointer changeKind(NodePointer Node, Node::Kind NewKind);
479 
480   NodePointer demangleOperator();
481 
482   int demangleNatural();
483   int demangleIndex();
484   NodePointer demangleIndexAsNode();
485   NodePointer demangleDependentConformanceIndex();
486   NodePointer demangleIdentifier();
487   NodePointer demangleOperatorIdentifier();
488 
489   std::string demangleBridgedMethodParams();
490 
491   NodePointer demangleMultiSubstitutions();
492   NodePointer pushMultiSubstitutions(int RepeatCount, size_t SubstIdx);
493   NodePointer createSwiftType(Node::Kind typeKind, const char *name);
494   NodePointer demangleStandardSubstitution();
495   NodePointer createStandardSubstitution(char Subst);
496   NodePointer demangleLocalIdentifier();
497 
498   NodePointer popModule();
499   NodePointer popContext();
500   NodePointer popTypeAndGetChild();
501   NodePointer popTypeAndGetAnyGeneric();
502   NodePointer demangleBuiltinType();
503   NodePointer demangleAnyGenericType(Node::Kind kind);
504   NodePointer demangleExtensionContext();
505   NodePointer demanglePlainFunction();
506   NodePointer popFunctionType(Node::Kind kind);
507   NodePointer popFunctionParams(Node::Kind kind);
508   NodePointer popFunctionParamLabels(NodePointer FuncType);
509   NodePointer popTuple();
510   NodePointer popTypeList();
511   NodePointer popProtocol();
512   NodePointer demangleBoundGenericType();
513   NodePointer demangleBoundGenericArgs(NodePointer nominalType,
514                                     const Vector<NodePointer> &TypeLists,
515                                     size_t TypeListIdx);
516   NodePointer popAnyProtocolConformanceList();
517   NodePointer demangleRetroactiveConformance();
518   NodePointer demangleInitializer();
519   NodePointer demangleImplParamConvention(Node::Kind ConvKind);
520   NodePointer demangleImplResultConvention(Node::Kind ConvKind);
521   NodePointer demangleImplFunctionType();
522   NodePointer demangleMetatype();
523   NodePointer demanglePrivateContextDescriptor();
524   NodePointer createArchetypeRef(int depth, int i);
525   NodePointer demangleArchetype();
526   NodePointer demangleAssociatedTypeSimple(NodePointer GenericParamIdx);
527   NodePointer demangleAssociatedTypeCompound(NodePointer GenericParamIdx);
528 
529   NodePointer popAssocTypeName();
530   NodePointer popAssocTypePath();
531   NodePointer getDependentGenericParamType(int depth, int index);
532   NodePointer demangleGenericParamIndex();
533   NodePointer popProtocolConformance();
534   NodePointer demangleRetroactiveProtocolConformanceRef();
535   NodePointer popAnyProtocolConformance();
536   NodePointer demangleConcreteProtocolConformance();
537   NodePointer popDependentProtocolConformance();
538   NodePointer demangleDependentProtocolConformanceRoot();
539   NodePointer demangleDependentProtocolConformanceInherited();
540   NodePointer popDependentAssociatedConformance();
541   NodePointer demangleDependentProtocolConformanceAssociated();
542   NodePointer demangleThunkOrSpecialization();
543   NodePointer demangleGenericSpecialization(Node::Kind SpecKind);
544   NodePointer demangleFunctionSpecialization();
545   NodePointer demangleFuncSpecParam(Node::Kind Kind);
546   NodePointer addFuncSpecParamNumber(NodePointer Param,
547                               FunctionSigSpecializationParamKind Kind);
548 
549   NodePointer demangleSpecAttributes(Node::Kind SpecKind);
550 
551   NodePointer demangleWitness();
552   NodePointer demangleSpecialType();
553   NodePointer demangleMetatypeRepresentation();
554   NodePointer demangleAccessor(NodePointer ChildNode);
555   NodePointer demangleFunctionEntity();
556   NodePointer demangleEntity(Node::Kind Kind);
557   NodePointer demangleVariable();
558   NodePointer demangleSubscript();
559   NodePointer demangleProtocolList();
560   NodePointer demangleProtocolListType();
561   NodePointer demangleGenericSignature(bool hasParamCounts);
562   NodePointer demangleGenericRequirement();
563   NodePointer demangleGenericType();
564   NodePointer demangleValueWitness();
565 
566   NodePointer demangleTypeMangling();
567   NodePointer demangleSymbolicReference(unsigned char rawKind);
568 
569   bool demangleBoundGenerics(Vector<NodePointer> &TypeListList,
570                              NodePointer &RetroactiveConformances);
571 
572   void dump();
573 
574 public:
Demangler()575   Demangler() {}
576 
577   void clear() override;
578 
579   /// Demangle the given symbol and return the parse tree.
580   ///
581   /// \param MangledName The mangled symbol string, which start with the
582   /// mangling prefix $S.
583   /// \param SymbolicReferenceResolver A function invoked to resolve symbolic references in
584   /// the string. If null, then symbolic references will cause the demangle to fail.
585   ///
586   /// \returns A parse tree for the demangled string - or a null pointer
587   /// on failure.
588   /// The lifetime of the returned node tree ends with the lifetime of the
589   /// Demangler or with a call of clear().
590   NodePointer demangleSymbol(StringRef MangledName,
591             std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver
592                = nullptr);
593 
594   /// Demangle the given type and return the parse tree.
595   ///
596   /// \param MangledName The mangled type string, which does _not_ start with
597   /// the mangling prefix $S.
598   /// \param SymbolicReferenceResolver A function invoked to resolve symbolic references in
599   /// the string. If null, then symbolic references will cause the demangle to fail.
600   ///
601   /// \returns A parse tree for the demangled string - or a null pointer
602   /// on failure.
603   /// The lifetime of the returned node tree ends with the lifetime of the
604   /// Demangler or with a call of clear().
605   NodePointer demangleType(StringRef MangledName,
606             std::function<SymbolicReferenceResolver_t> SymbolicReferenceResolver
607               = nullptr);
608 };
609 
610 /// A demangler which uses stack space for its initial memory.
611 ///
612 /// The \p Size paramter specifies the size of the stack space.
613 template <size_t Size> class StackAllocatedDemangler : public Demangler {
614   char StackSpace[Size];
615 
616 public:
StackAllocatedDemangler()617   StackAllocatedDemangler() {
618     providePreallocatedMemory(StackSpace, Size);
619   }
620 };
621 
622 NodePointer demangleOldSymbolAsNode(StringRef MangledName,
623                                     NodeFactory &Factory);
624 } // end namespace Demangle
625 } // end namespace swift
626 
627 #endif // SWIFT_DEMANGLING_DEMANGLER_H
628