Coverage Report

Created: 2025-08-26 06:39

/src/llvm-project-18.1.8.src/libcxxabi/src/demangle/ItaniumDemangle.h
Line
Count
Source (jump to first uncovered line)
1
//===------------------------- ItaniumDemangle.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
// Generic itanium demangler library.
10
// There are two copies of this file in the source tree.  The one under
11
// libcxxabi is the original and the one under llvm is the copy.  Use
12
// cp-to-llvm.sh to update the copy.  See README.txt for more details.
13
//
14
//===----------------------------------------------------------------------===//
15
16
#ifndef DEMANGLE_ITANIUMDEMANGLE_H
17
#define DEMANGLE_ITANIUMDEMANGLE_H
18
19
#include "DemangleConfig.h"
20
#include "StringViewExtras.h"
21
#include "Utility.h"
22
#include <__cxxabi_config.h>
23
#include <algorithm>
24
#include <cctype>
25
#include <cstdio>
26
#include <cstdlib>
27
#include <cstring>
28
#include <limits>
29
#include <new>
30
#include <string_view>
31
#include <type_traits>
32
#include <utility>
33
34
#ifdef _LIBCXXABI_COMPILER_CLANG
35
#pragma clang diagnostic push
36
#pragma clang diagnostic ignored "-Wunused-template"
37
#endif
38
39
DEMANGLE_NAMESPACE_BEGIN
40
41
template <class T, size_t N> class PODSmallVector {
42
  static_assert(std::is_pod<T>::value,
43
                "T is required to be a plain old data type");
44
45
  T *First = nullptr;
46
  T *Last = nullptr;
47
  T *Cap = nullptr;
48
  T Inline[N] = {0};
49
50
0
  bool isInline() const { return First == Inline; }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::isInline() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::isInline() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::isInline() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::isInline() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::isInline() const
51
52
0
  void clearInline() {
53
0
    First = Inline;
54
0
    Last = Inline;
55
0
    Cap = Inline + N;
56
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::clearInline()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::clearInline()
57
58
0
  void reserve(size_t NewCap) {
59
0
    size_t S = size();
60
0
    if (isInline()) {
61
0
      auto *Tmp = static_cast<T *>(std::malloc(NewCap * sizeof(T)));
62
0
      if (Tmp == nullptr)
63
0
        std::abort();
64
0
      std::copy(First, Last, Tmp);
65
0
      First = Tmp;
66
0
    } else {
67
0
      First = static_cast<T *>(std::realloc(First, NewCap * sizeof(T)));
68
0
      if (First == nullptr)
69
0
        std::abort();
70
0
    }
71
0
    Last = First + S;
72
0
    Cap = First + NewCap;
73
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::reserve(unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::reserve(unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::reserve(unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::reserve(unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::reserve(unsigned long)
74
75
public:
76
0
  PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::PODSmallVector()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::PODSmallVector()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::PODSmallVector()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::PODSmallVector()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::PODSmallVector()
77
78
  PODSmallVector(const PODSmallVector &) = delete;
79
  PODSmallVector &operator=(const PODSmallVector &) = delete;
80
81
  PODSmallVector(PODSmallVector &&Other) : PODSmallVector() {
82
    if (Other.isInline()) {
83
      std::copy(Other.begin(), Other.end(), First);
84
      Last = First + Other.size();
85
      Other.clear();
86
      return;
87
    }
88
89
    First = Other.First;
90
    Last = Other.Last;
91
    Cap = Other.Cap;
92
    Other.clearInline();
93
  }
94
95
0
  PODSmallVector &operator=(PODSmallVector &&Other) {
96
0
    if (Other.isInline()) {
97
0
      if (!isInline()) {
98
0
        std::free(First);
99
0
        clearInline();
100
0
      }
101
0
      std::copy(Other.begin(), Other.end(), First);
102
0
      Last = First + Other.size();
103
0
      Other.clear();
104
0
      return *this;
105
0
    }
106
107
0
    if (isInline()) {
108
0
      First = Other.First;
109
0
      Last = Other.Last;
110
0
      Cap = Other.Cap;
111
0
      Other.clearInline();
112
0
      return *this;
113
0
    }
114
115
0
    std::swap(First, Other.First);
116
0
    std::swap(Last, Other.Last);
117
0
    std::swap(Cap, Other.Cap);
118
0
    Other.clear();
119
0
    return *this;
120
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::operator=((anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::operator=((anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>&&)
121
122
  // NOLINTNEXTLINE(readability-identifier-naming)
123
0
  void push_back(const T &Elem) {
124
0
    if (Last == Cap)
125
0
      reserve(size() * 2);
126
0
    *Last++ = Elem;
127
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::push_back((anonymous namespace)::itanium_demangle::ForwardTemplateReference* const&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::push_back((anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>* const&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::push_back((anonymous namespace)::itanium_demangle::Node* const&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::push_back((anonymous namespace)::itanium_demangle::Node* const&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::push_back((anonymous namespace)::itanium_demangle::Node const* const&)
128
129
  // NOLINTNEXTLINE(readability-identifier-naming)
130
0
  void pop_back() {
131
0
    DEMANGLE_ASSERT(Last != First, "Popping empty vector!");
132
0
    --Last;
133
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::pop_back()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::pop_back()
134
135
0
  void shrinkToSize(size_t Index) {
136
0
    DEMANGLE_ASSERT(Index <= size(), "shrinkToSize() can't expand!");
137
0
    Last = First + Index;
138
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::shrinkToSize(unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::shrinkToSize(unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::shrinkToSize(unsigned long)
139
140
0
  T *begin() { return First; }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::begin()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::begin()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::begin()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::begin()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::begin()
141
0
  T *end() { return Last; }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::end()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::end()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::end()
142
143
0
  bool empty() const { return First == Last; }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::empty() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::empty() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::empty() const
144
0
  size_t size() const { return static_cast<size_t>(Last - First); }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::size() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::size() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::size() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::size() const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::size() const
145
  T &back() {
146
    DEMANGLE_ASSERT(Last != First, "Calling back() on empty vector!");
147
    return *(Last - 1);
148
  }
149
0
  T &operator[](size_t Index) {
150
0
    DEMANGLE_ASSERT(Index < size(), "Invalid access!");
151
0
    return *(begin() + Index);
152
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::operator[](unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::operator[](unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::operator[](unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::operator[](unsigned long)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::operator[](unsigned long)
153
0
  void clear() { Last = First; }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::clear()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::clear()
154
155
0
  ~PODSmallVector() {
156
0
    if (!isInline())
157
0
      std::free(First);
158
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::ForwardTemplateReference*, 4ul>::~PODSmallVector()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>*, 4ul>::~PODSmallVector()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 8ul>::~PODSmallVector()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node*, 32ul>::~PODSmallVector()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::PODSmallVector<(anonymous namespace)::itanium_demangle::Node const*, 8ul>::~PODSmallVector()
159
};
160
161
// Base class of all AST nodes. The AST is built by the parser, then is
162
// traversed by the printLeft/Right functions to produce a demangled string.
163
class Node {
164
public:
165
  enum Kind : unsigned char {
166
#define NODE(NodeKind) K##NodeKind,
167
#include "ItaniumNodes.def"
168
  };
169
170
  /// Three-way bool to track a cached value. Unknown is possible if this node
171
  /// has an unexpanded parameter pack below it that may affect this cache.
172
  enum class Cache : unsigned char { Yes, No, Unknown, };
173
174
  /// Operator precedence for expression nodes. Used to determine required
175
  /// parens in expression emission.
176
  enum class Prec {
177
    Primary,
178
    Postfix,
179
    Unary,
180
    Cast,
181
    PtrMem,
182
    Multiplicative,
183
    Additive,
184
    Shift,
185
    Spaceship,
186
    Relational,
187
    Equality,
188
    And,
189
    Xor,
190
    Ior,
191
    AndIf,
192
    OrIf,
193
    Conditional,
194
    Assign,
195
    Comma,
196
    Default,
197
  };
198
199
private:
200
  Kind K;
201
202
  Prec Precedence : 6;
203
204
  // FIXME: Make these protected.
205
public:
206
  /// Tracks if this node has a component on its right side, in which case we
207
  /// need to call printRight.
208
  Cache RHSComponentCache : 2;
209
210
  /// Track if this node is a (possibly qualified) array type. This can affect
211
  /// how we format the output string.
212
  Cache ArrayCache : 2;
213
214
  /// Track if this node is a (possibly qualified) function type. This can
215
  /// affect how we format the output string.
216
  Cache FunctionCache : 2;
217
218
public:
219
  Node(Kind K_, Prec Precedence_ = Prec::Primary,
220
       Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No,
221
       Cache FunctionCache_ = Cache::No)
222
0
      : K(K_), Precedence(Precedence_), RHSComponentCache(RHSComponentCache_),
223
0
        ArrayCache(ArrayCache_), FunctionCache(FunctionCache_) {}
224
  Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No,
225
       Cache FunctionCache_ = Cache::No)
226
0
      : Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_,
227
0
             FunctionCache_) {}
228
229
  /// Visit the most-derived object corresponding to this object.
230
  template<typename Fn> void visit(Fn F) const;
231
232
  // The following function is provided by all derived classes:
233
  //
234
  // Call F with arguments that, when passed to the constructor of this node,
235
  // would construct an equivalent node.
236
  //template<typename Fn> void match(Fn F) const;
237
238
0
  bool hasRHSComponent(OutputBuffer &OB) const {
239
0
    if (RHSComponentCache != Cache::Unknown)
240
0
      return RHSComponentCache == Cache::Yes;
241
0
    return hasRHSComponentSlow(OB);
242
0
  }
243
244
0
  bool hasArray(OutputBuffer &OB) const {
245
0
    if (ArrayCache != Cache::Unknown)
246
0
      return ArrayCache == Cache::Yes;
247
0
    return hasArraySlow(OB);
248
0
  }
249
250
0
  bool hasFunction(OutputBuffer &OB) const {
251
0
    if (FunctionCache != Cache::Unknown)
252
0
      return FunctionCache == Cache::Yes;
253
0
    return hasFunctionSlow(OB);
254
0
  }
255
256
0
  Kind getKind() const { return K; }
257
258
0
  Prec getPrecedence() const { return Precedence; }
259
260
0
  virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
261
0
  virtual bool hasArraySlow(OutputBuffer &) const { return false; }
262
0
  virtual bool hasFunctionSlow(OutputBuffer &) const { return false; }
263
264
  // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
265
  // get at a node that actually represents some concrete syntax.
266
0
  virtual const Node *getSyntaxNode(OutputBuffer &) const { return this; }
267
268
  // Print this node as an expression operand, surrounding it in parentheses if
269
  // its precedence is [Strictly] weaker than P.
270
  void printAsOperand(OutputBuffer &OB, Prec P = Prec::Default,
271
0
                      bool StrictlyWorse = false) const {
272
0
    bool Paren =
273
0
        unsigned(getPrecedence()) >= unsigned(P) + unsigned(StrictlyWorse);
274
0
    if (Paren)
275
0
      OB.printOpen();
276
0
    print(OB);
277
0
    if (Paren)
278
0
      OB.printClose();
279
0
  }
280
281
0
  void print(OutputBuffer &OB) const {
282
0
    printLeft(OB);
283
0
    if (RHSComponentCache != Cache::No)
284
0
      printRight(OB);
285
0
  }
286
287
  // Print the "left" side of this Node into OutputBuffer.
288
  virtual void printLeft(OutputBuffer &) const = 0;
289
290
  // Print the "right". This distinction is necessary to represent C++ types
291
  // that appear on the RHS of their subtype, such as arrays or functions.
292
  // Since most types don't have such a component, provide a default
293
  // implementation.
294
0
  virtual void printRight(OutputBuffer &) const {}
295
296
0
  virtual std::string_view getBaseName() const { return {}; }
297
298
  // Silence compiler warnings, this dtor will never be called.
299
0
  virtual ~Node() = default;
300
301
#ifndef NDEBUG
302
  DEMANGLE_DUMP_METHOD void dump() const;
303
#endif
304
};
305
306
class NodeArray {
307
  Node **Elements;
308
  size_t NumElements;
309
310
public:
311
0
  NodeArray() : Elements(nullptr), NumElements(0) {}
312
  NodeArray(Node **Elements_, size_t NumElements_)
313
0
      : Elements(Elements_), NumElements(NumElements_) {}
314
315
0
  bool empty() const { return NumElements == 0; }
316
0
  size_t size() const { return NumElements; }
317
318
0
  Node **begin() const { return Elements; }
319
0
  Node **end() const { return Elements + NumElements; }
320
321
0
  Node *operator[](size_t Idx) const { return Elements[Idx]; }
322
323
0
  void printWithComma(OutputBuffer &OB) const {
324
0
    bool FirstElement = true;
325
0
    for (size_t Idx = 0; Idx != NumElements; ++Idx) {
326
0
      size_t BeforeComma = OB.getCurrentPosition();
327
0
      if (!FirstElement)
328
0
        OB += ", ";
329
0
      size_t AfterComma = OB.getCurrentPosition();
330
0
      Elements[Idx]->printAsOperand(OB, Node::Prec::Comma);
331
332
      // Elements[Idx] is an empty parameter pack expansion, we should erase the
333
      // comma we just printed.
334
0
      if (AfterComma == OB.getCurrentPosition()) {
335
0
        OB.setCurrentPosition(BeforeComma);
336
0
        continue;
337
0
      }
338
339
0
      FirstElement = false;
340
0
    }
341
0
  }
342
};
343
344
struct NodeArrayNode : Node {
345
  NodeArray Array;
346
0
  NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {}
347
348
0
  template<typename Fn> void match(Fn F) const { F(Array); }
349
350
0
  void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); }
351
};
352
353
class DotSuffix final : public Node {
354
  const Node *Prefix;
355
  const std::string_view Suffix;
356
357
public:
358
  DotSuffix(const Node *Prefix_, std::string_view Suffix_)
359
0
      : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
360
361
0
  template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
362
363
0
  void printLeft(OutputBuffer &OB) const override {
364
0
    Prefix->print(OB);
365
0
    OB += " (";
366
0
    OB += Suffix;
367
0
    OB += ")";
368
0
  }
369
};
370
371
class VendorExtQualType final : public Node {
372
  const Node *Ty;
373
  std::string_view Ext;
374
  const Node *TA;
375
376
public:
377
  VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
378
0
      : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
379
380
0
  const Node *getTy() const { return Ty; }
381
0
  std::string_view getExt() const { return Ext; }
382
0
  const Node *getTA() const { return TA; }
383
384
0
  template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
385
386
0
  void printLeft(OutputBuffer &OB) const override {
387
0
    Ty->print(OB);
388
0
    OB += " ";
389
0
    OB += Ext;
390
0
    if (TA != nullptr)
391
0
      TA->print(OB);
392
0
  }
393
};
394
395
enum FunctionRefQual : unsigned char {
396
  FrefQualNone,
397
  FrefQualLValue,
398
  FrefQualRValue,
399
};
400
401
enum Qualifiers {
402
  QualNone = 0,
403
  QualConst = 0x1,
404
  QualVolatile = 0x2,
405
  QualRestrict = 0x4,
406
};
407
408
0
inline Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2) {
409
0
  return Q1 = static_cast<Qualifiers>(Q1 | Q2);
410
0
}
411
412
class QualType final : public Node {
413
protected:
414
  const Qualifiers Quals;
415
  const Node *Child;
416
417
0
  void printQuals(OutputBuffer &OB) const {
418
0
    if (Quals & QualConst)
419
0
      OB += " const";
420
0
    if (Quals & QualVolatile)
421
0
      OB += " volatile";
422
0
    if (Quals & QualRestrict)
423
0
      OB += " restrict";
424
0
  }
425
426
public:
427
  QualType(const Node *Child_, Qualifiers Quals_)
428
0
      : Node(KQualType, Child_->RHSComponentCache,
429
0
             Child_->ArrayCache, Child_->FunctionCache),
430
0
        Quals(Quals_), Child(Child_) {}
431
432
0
  Qualifiers getQuals() const { return Quals; }
433
0
  const Node *getChild() const { return Child; }
434
435
0
  template<typename Fn> void match(Fn F) const { F(Child, Quals); }
436
437
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
438
0
    return Child->hasRHSComponent(OB);
439
0
  }
440
0
  bool hasArraySlow(OutputBuffer &OB) const override {
441
0
    return Child->hasArray(OB);
442
0
  }
443
0
  bool hasFunctionSlow(OutputBuffer &OB) const override {
444
0
    return Child->hasFunction(OB);
445
0
  }
446
447
0
  void printLeft(OutputBuffer &OB) const override {
448
0
    Child->printLeft(OB);
449
0
    printQuals(OB);
450
0
  }
451
452
0
  void printRight(OutputBuffer &OB) const override { Child->printRight(OB); }
453
};
454
455
class ConversionOperatorType final : public Node {
456
  const Node *Ty;
457
458
public:
459
  ConversionOperatorType(const Node *Ty_)
460
0
      : Node(KConversionOperatorType), Ty(Ty_) {}
461
462
0
  template<typename Fn> void match(Fn F) const { F(Ty); }
463
464
0
  void printLeft(OutputBuffer &OB) const override {
465
0
    OB += "operator ";
466
0
    Ty->print(OB);
467
0
  }
468
};
469
470
class PostfixQualifiedType final : public Node {
471
  const Node *Ty;
472
  const std::string_view Postfix;
473
474
public:
475
  PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
476
0
      : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
477
478
0
  template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
479
480
0
  void printLeft(OutputBuffer &OB) const override {
481
0
    Ty->printLeft(OB);
482
0
    OB += Postfix;
483
0
  }
484
};
485
486
class NameType final : public Node {
487
  const std::string_view Name;
488
489
public:
490
0
  NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {}
491
492
0
  template<typename Fn> void match(Fn F) const { F(Name); }
493
494
0
  std::string_view getName() const { return Name; }
495
0
  std::string_view getBaseName() const override { return Name; }
496
497
0
  void printLeft(OutputBuffer &OB) const override { OB += Name; }
498
};
499
500
class BitIntType final : public Node {
501
  const Node *Size;
502
  bool Signed;
503
504
public:
505
  BitIntType(const Node *Size_, bool Signed_)
506
0
      : Node(KBitIntType), Size(Size_), Signed(Signed_) {}
507
508
0
  template <typename Fn> void match(Fn F) const { F(Size, Signed); }
509
510
0
  void printLeft(OutputBuffer &OB) const override {
511
0
    if (!Signed)
512
0
      OB += "unsigned ";
513
0
    OB += "_BitInt";
514
0
    OB.printOpen();
515
0
    Size->printAsOperand(OB);
516
0
    OB.printClose();
517
0
  }
518
};
519
520
class ElaboratedTypeSpefType : public Node {
521
  std::string_view Kind;
522
  Node *Child;
523
public:
524
  ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
525
0
      : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
526
527
0
  template<typename Fn> void match(Fn F) const { F(Kind, Child); }
528
529
0
  void printLeft(OutputBuffer &OB) const override {
530
0
    OB += Kind;
531
0
    OB += ' ';
532
0
    Child->print(OB);
533
0
  }
534
};
535
536
class TransformedType : public Node {
537
  std::string_view Transform;
538
  Node *BaseType;
539
public:
540
  TransformedType(std::string_view Transform_, Node *BaseType_)
541
0
      : Node(KTransformedType), Transform(Transform_), BaseType(BaseType_) {}
542
543
0
  template<typename Fn> void match(Fn F) const { F(Transform, BaseType); }
544
545
0
  void printLeft(OutputBuffer &OB) const override {
546
0
    OB += Transform;
547
0
    OB += '(';
548
0
    BaseType->print(OB);
549
0
    OB += ')';
550
0
  }
551
};
552
553
struct AbiTagAttr : Node {
554
  Node *Base;
555
  std::string_view Tag;
556
557
  AbiTagAttr(Node *Base_, std::string_view Tag_)
558
0
      : Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache,
559
0
             Base_->FunctionCache),
560
0
        Base(Base_), Tag(Tag_) {}
561
562
0
  template<typename Fn> void match(Fn F) const { F(Base, Tag); }
563
564
0
  std::string_view getBaseName() const override { return Base->getBaseName(); }
565
566
0
  void printLeft(OutputBuffer &OB) const override {
567
0
    Base->printLeft(OB);
568
0
    OB += "[abi:";
569
0
    OB += Tag;
570
0
    OB += "]";
571
0
  }
572
};
573
574
class EnableIfAttr : public Node {
575
  NodeArray Conditions;
576
public:
577
  EnableIfAttr(NodeArray Conditions_)
578
0
      : Node(KEnableIfAttr), Conditions(Conditions_) {}
579
580
0
  template<typename Fn> void match(Fn F) const { F(Conditions); }
581
582
0
  void printLeft(OutputBuffer &OB) const override {
583
0
    OB += " [enable_if:";
584
0
    Conditions.printWithComma(OB);
585
0
    OB += ']';
586
0
  }
587
};
588
589
class ObjCProtoName : public Node {
590
  const Node *Ty;
591
  std::string_view Protocol;
592
593
  friend class PointerType;
594
595
public:
596
  ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
597
0
      : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
598
599
0
  template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
600
601
0
  bool isObjCObject() const {
602
0
    return Ty->getKind() == KNameType &&
603
0
           static_cast<const NameType *>(Ty)->getName() == "objc_object";
604
0
  }
605
606
0
  void printLeft(OutputBuffer &OB) const override {
607
0
    Ty->print(OB);
608
0
    OB += "<";
609
0
    OB += Protocol;
610
0
    OB += ">";
611
0
  }
612
};
613
614
class PointerType final : public Node {
615
  const Node *Pointee;
616
617
public:
618
  PointerType(const Node *Pointee_)
619
0
      : Node(KPointerType, Pointee_->RHSComponentCache),
620
0
        Pointee(Pointee_) {}
621
622
0
  const Node *getPointee() const { return Pointee; }
623
624
0
  template<typename Fn> void match(Fn F) const { F(Pointee); }
625
626
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
627
0
    return Pointee->hasRHSComponent(OB);
628
0
  }
629
630
0
  void printLeft(OutputBuffer &OB) const override {
631
    // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
632
0
    if (Pointee->getKind() != KObjCProtoName ||
633
0
        !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
634
0
      Pointee->printLeft(OB);
635
0
      if (Pointee->hasArray(OB))
636
0
        OB += " ";
637
0
      if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
638
0
        OB += "(";
639
0
      OB += "*";
640
0
    } else {
641
0
      const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
642
0
      OB += "id<";
643
0
      OB += objcProto->Protocol;
644
0
      OB += ">";
645
0
    }
646
0
  }
647
648
0
  void printRight(OutputBuffer &OB) const override {
649
0
    if (Pointee->getKind() != KObjCProtoName ||
650
0
        !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
651
0
      if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
652
0
        OB += ")";
653
0
      Pointee->printRight(OB);
654
0
    }
655
0
  }
656
};
657
658
enum class ReferenceKind {
659
  LValue,
660
  RValue,
661
};
662
663
// Represents either a LValue or an RValue reference type.
664
class ReferenceType : public Node {
665
  const Node *Pointee;
666
  ReferenceKind RK;
667
668
  mutable bool Printing = false;
669
670
  // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
671
  // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
672
  // other combination collapses to a lvalue ref.
673
  //
674
  // A combination of a TemplateForwardReference and a back-ref Substitution
675
  // from an ill-formed string may have created a cycle; use cycle detection to
676
  // avoid looping forever.
677
0
  std::pair<ReferenceKind, const Node *> collapse(OutputBuffer &OB) const {
678
0
    auto SoFar = std::make_pair(RK, Pointee);
679
    // Track the chain of nodes for the Floyd's 'tortoise and hare'
680
    // cycle-detection algorithm, since getSyntaxNode(S) is impure
681
0
    PODSmallVector<const Node *, 8> Prev;
682
0
    for (;;) {
683
0
      const Node *SN = SoFar.second->getSyntaxNode(OB);
684
0
      if (SN->getKind() != KReferenceType)
685
0
        break;
686
0
      auto *RT = static_cast<const ReferenceType *>(SN);
687
0
      SoFar.second = RT->Pointee;
688
0
      SoFar.first = std::min(SoFar.first, RT->RK);
689
690
      // The middle of Prev is the 'slow' pointer moving at half speed
691
0
      Prev.push_back(SoFar.second);
692
0
      if (Prev.size() > 1 && SoFar.second == Prev[(Prev.size() - 1) / 2]) {
693
        // Cycle detected
694
0
        SoFar.second = nullptr;
695
0
        break;
696
0
      }
697
0
    }
698
0
    return SoFar;
699
0
  }
700
701
public:
702
  ReferenceType(const Node *Pointee_, ReferenceKind RK_)
703
0
      : Node(KReferenceType, Pointee_->RHSComponentCache),
704
0
        Pointee(Pointee_), RK(RK_) {}
705
706
0
  template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
707
708
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
709
0
    return Pointee->hasRHSComponent(OB);
710
0
  }
711
712
0
  void printLeft(OutputBuffer &OB) const override {
713
0
    if (Printing)
714
0
      return;
715
0
    ScopedOverride<bool> SavePrinting(Printing, true);
716
0
    std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
717
0
    if (!Collapsed.second)
718
0
      return;
719
0
    Collapsed.second->printLeft(OB);
720
0
    if (Collapsed.second->hasArray(OB))
721
0
      OB += " ";
722
0
    if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
723
0
      OB += "(";
724
725
0
    OB += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
726
0
  }
727
0
  void printRight(OutputBuffer &OB) const override {
728
0
    if (Printing)
729
0
      return;
730
0
    ScopedOverride<bool> SavePrinting(Printing, true);
731
0
    std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
732
0
    if (!Collapsed.second)
733
0
      return;
734
0
    if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
735
0
      OB += ")";
736
0
    Collapsed.second->printRight(OB);
737
0
  }
738
};
739
740
class PointerToMemberType final : public Node {
741
  const Node *ClassType;
742
  const Node *MemberType;
743
744
public:
745
  PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
746
0
      : Node(KPointerToMemberType, MemberType_->RHSComponentCache),
747
0
        ClassType(ClassType_), MemberType(MemberType_) {}
748
749
0
  template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
750
751
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
752
0
    return MemberType->hasRHSComponent(OB);
753
0
  }
754
755
0
  void printLeft(OutputBuffer &OB) const override {
756
0
    MemberType->printLeft(OB);
757
0
    if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
758
0
      OB += "(";
759
0
    else
760
0
      OB += " ";
761
0
    ClassType->print(OB);
762
0
    OB += "::*";
763
0
  }
764
765
0
  void printRight(OutputBuffer &OB) const override {
766
0
    if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
767
0
      OB += ")";
768
0
    MemberType->printRight(OB);
769
0
  }
770
};
771
772
class ArrayType final : public Node {
773
  const Node *Base;
774
  Node *Dimension;
775
776
public:
777
  ArrayType(const Node *Base_, Node *Dimension_)
778
0
      : Node(KArrayType,
779
0
             /*RHSComponentCache=*/Cache::Yes,
780
0
             /*ArrayCache=*/Cache::Yes),
781
0
        Base(Base_), Dimension(Dimension_) {}
782
783
0
  template<typename Fn> void match(Fn F) const { F(Base, Dimension); }
784
785
0
  bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
786
0
  bool hasArraySlow(OutputBuffer &) const override { return true; }
787
788
0
  void printLeft(OutputBuffer &OB) const override { Base->printLeft(OB); }
789
790
0
  void printRight(OutputBuffer &OB) const override {
791
0
    if (OB.back() != ']')
792
0
      OB += " ";
793
0
    OB += "[";
794
0
    if (Dimension)
795
0
      Dimension->print(OB);
796
0
    OB += "]";
797
0
    Base->printRight(OB);
798
0
  }
799
};
800
801
class FunctionType final : public Node {
802
  const Node *Ret;
803
  NodeArray Params;
804
  Qualifiers CVQuals;
805
  FunctionRefQual RefQual;
806
  const Node *ExceptionSpec;
807
808
public:
809
  FunctionType(const Node *Ret_, NodeArray Params_, Qualifiers CVQuals_,
810
               FunctionRefQual RefQual_, const Node *ExceptionSpec_)
811
0
      : Node(KFunctionType,
812
0
             /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
813
0
             /*FunctionCache=*/Cache::Yes),
814
0
        Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
815
0
        ExceptionSpec(ExceptionSpec_) {}
816
817
0
  template<typename Fn> void match(Fn F) const {
818
0
    F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
819
0
  }
820
821
0
  bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
822
0
  bool hasFunctionSlow(OutputBuffer &) const override { return true; }
823
824
  // Handle C++'s ... quirky decl grammar by using the left & right
825
  // distinction. Consider:
826
  //   int (*f(float))(char) {}
827
  // f is a function that takes a float and returns a pointer to a function
828
  // that takes a char and returns an int. If we're trying to print f, start
829
  // by printing out the return types's left, then print our parameters, then
830
  // finally print right of the return type.
831
0
  void printLeft(OutputBuffer &OB) const override {
832
0
    Ret->printLeft(OB);
833
0
    OB += " ";
834
0
  }
835
836
0
  void printRight(OutputBuffer &OB) const override {
837
0
    OB.printOpen();
838
0
    Params.printWithComma(OB);
839
0
    OB.printClose();
840
0
    Ret->printRight(OB);
841
842
0
    if (CVQuals & QualConst)
843
0
      OB += " const";
844
0
    if (CVQuals & QualVolatile)
845
0
      OB += " volatile";
846
0
    if (CVQuals & QualRestrict)
847
0
      OB += " restrict";
848
849
0
    if (RefQual == FrefQualLValue)
850
0
      OB += " &";
851
0
    else if (RefQual == FrefQualRValue)
852
0
      OB += " &&";
853
854
0
    if (ExceptionSpec != nullptr) {
855
0
      OB += ' ';
856
0
      ExceptionSpec->print(OB);
857
0
    }
858
0
  }
859
};
860
861
class NoexceptSpec : public Node {
862
  const Node *E;
863
public:
864
0
  NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {}
865
866
0
  template<typename Fn> void match(Fn F) const { F(E); }
867
868
0
  void printLeft(OutputBuffer &OB) const override {
869
0
    OB += "noexcept";
870
0
    OB.printOpen();
871
0
    E->printAsOperand(OB);
872
0
    OB.printClose();
873
0
  }
874
};
875
876
class DynamicExceptionSpec : public Node {
877
  NodeArray Types;
878
public:
879
  DynamicExceptionSpec(NodeArray Types_)
880
0
      : Node(KDynamicExceptionSpec), Types(Types_) {}
881
882
0
  template<typename Fn> void match(Fn F) const { F(Types); }
883
884
0
  void printLeft(OutputBuffer &OB) const override {
885
0
    OB += "throw";
886
0
    OB.printOpen();
887
0
    Types.printWithComma(OB);
888
0
    OB.printClose();
889
0
  }
890
};
891
892
/// Represents the explicitly named object parameter.
893
/// E.g.,
894
/// \code{.cpp}
895
///   struct Foo {
896
///     void bar(this Foo && self);
897
///   };
898
/// \endcode
899
class ExplicitObjectParameter final : public Node {
900
  Node *Base;
901
902
public:
903
  ExplicitObjectParameter(Node *Base_)
904
0
      : Node(KExplicitObjectParameter), Base(Base_) {
905
0
    DEMANGLE_ASSERT(
906
0
        Base != nullptr,
907
0
        "Creating an ExplicitObjectParameter without a valid Base Node.");
908
0
  }
909
910
0
  template <typename Fn> void match(Fn F) const { F(Base); }
911
912
0
  void printLeft(OutputBuffer &OB) const override {
913
0
    OB += "this ";
914
0
    Base->print(OB);
915
0
  }
916
};
917
918
class FunctionEncoding final : public Node {
919
  const Node *Ret;
920
  const Node *Name;
921
  NodeArray Params;
922
  const Node *Attrs;
923
  const Node *Requires;
924
  Qualifiers CVQuals;
925
  FunctionRefQual RefQual;
926
927
public:
928
  FunctionEncoding(const Node *Ret_, const Node *Name_, NodeArray Params_,
929
                   const Node *Attrs_, const Node *Requires_,
930
                   Qualifiers CVQuals_, FunctionRefQual RefQual_)
931
0
      : Node(KFunctionEncoding,
932
0
             /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
933
0
             /*FunctionCache=*/Cache::Yes),
934
0
        Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
935
0
        Requires(Requires_), CVQuals(CVQuals_), RefQual(RefQual_) {}
936
937
0
  template<typename Fn> void match(Fn F) const {
938
0
    F(Ret, Name, Params, Attrs, Requires, CVQuals, RefQual);
939
0
  }
940
941
0
  Qualifiers getCVQuals() const { return CVQuals; }
942
0
  FunctionRefQual getRefQual() const { return RefQual; }
943
0
  NodeArray getParams() const { return Params; }
944
0
  const Node *getReturnType() const { return Ret; }
945
946
0
  bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
947
0
  bool hasFunctionSlow(OutputBuffer &) const override { return true; }
948
949
0
  const Node *getName() const { return Name; }
950
951
0
  void printLeft(OutputBuffer &OB) const override {
952
0
    if (Ret) {
953
0
      Ret->printLeft(OB);
954
0
      if (!Ret->hasRHSComponent(OB))
955
0
        OB += " ";
956
0
    }
957
0
    Name->print(OB);
958
0
  }
959
960
0
  void printRight(OutputBuffer &OB) const override {
961
0
    OB.printOpen();
962
0
    Params.printWithComma(OB);
963
0
    OB.printClose();
964
0
    if (Ret)
965
0
      Ret->printRight(OB);
966
967
0
    if (CVQuals & QualConst)
968
0
      OB += " const";
969
0
    if (CVQuals & QualVolatile)
970
0
      OB += " volatile";
971
0
    if (CVQuals & QualRestrict)
972
0
      OB += " restrict";
973
974
0
    if (RefQual == FrefQualLValue)
975
0
      OB += " &";
976
0
    else if (RefQual == FrefQualRValue)
977
0
      OB += " &&";
978
979
0
    if (Attrs != nullptr)
980
0
      Attrs->print(OB);
981
982
0
    if (Requires != nullptr) {
983
0
      OB += " requires ";
984
0
      Requires->print(OB);
985
0
    }
986
0
  }
987
};
988
989
class LiteralOperator : public Node {
990
  const Node *OpName;
991
992
public:
993
  LiteralOperator(const Node *OpName_)
994
0
      : Node(KLiteralOperator), OpName(OpName_) {}
995
996
0
  template<typename Fn> void match(Fn F) const { F(OpName); }
997
998
0
  void printLeft(OutputBuffer &OB) const override {
999
0
    OB += "operator\"\" ";
1000
0
    OpName->print(OB);
1001
0
  }
1002
};
1003
1004
class SpecialName final : public Node {
1005
  const std::string_view Special;
1006
  const Node *Child;
1007
1008
public:
1009
  SpecialName(std::string_view Special_, const Node *Child_)
1010
0
      : Node(KSpecialName), Special(Special_), Child(Child_) {}
1011
1012
0
  template<typename Fn> void match(Fn F) const { F(Special, Child); }
1013
1014
0
  void printLeft(OutputBuffer &OB) const override {
1015
0
    OB += Special;
1016
0
    Child->print(OB);
1017
0
  }
1018
};
1019
1020
class CtorVtableSpecialName final : public Node {
1021
  const Node *FirstType;
1022
  const Node *SecondType;
1023
1024
public:
1025
  CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_)
1026
0
      : Node(KCtorVtableSpecialName),
1027
0
        FirstType(FirstType_), SecondType(SecondType_) {}
1028
1029
0
  template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); }
1030
1031
0
  void printLeft(OutputBuffer &OB) const override {
1032
0
    OB += "construction vtable for ";
1033
0
    FirstType->print(OB);
1034
0
    OB += "-in-";
1035
0
    SecondType->print(OB);
1036
0
  }
1037
};
1038
1039
struct NestedName : Node {
1040
  Node *Qual;
1041
  Node *Name;
1042
1043
  NestedName(Node *Qual_, Node *Name_)
1044
0
      : Node(KNestedName), Qual(Qual_), Name(Name_) {}
1045
1046
0
  template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1047
1048
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1049
1050
0
  void printLeft(OutputBuffer &OB) const override {
1051
0
    Qual->print(OB);
1052
0
    OB += "::";
1053
0
    Name->print(OB);
1054
0
  }
1055
};
1056
1057
struct MemberLikeFriendName : Node {
1058
  Node *Qual;
1059
  Node *Name;
1060
1061
  MemberLikeFriendName(Node *Qual_, Node *Name_)
1062
0
      : Node(KMemberLikeFriendName), Qual(Qual_), Name(Name_) {}
1063
1064
0
  template<typename Fn> void match(Fn F) const { F(Qual, Name); }
1065
1066
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1067
1068
0
  void printLeft(OutputBuffer &OB) const override {
1069
0
    Qual->print(OB);
1070
0
    OB += "::friend ";
1071
0
    Name->print(OB);
1072
0
  }
1073
};
1074
1075
struct ModuleName : Node {
1076
  ModuleName *Parent;
1077
  Node *Name;
1078
  bool IsPartition;
1079
1080
  ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false)
1081
0
      : Node(KModuleName), Parent(Parent_), Name(Name_),
1082
0
        IsPartition(IsPartition_) {}
1083
1084
0
  template <typename Fn> void match(Fn F) const {
1085
0
    F(Parent, Name, IsPartition);
1086
0
  }
1087
1088
0
  void printLeft(OutputBuffer &OB) const override {
1089
0
    if (Parent)
1090
0
      Parent->print(OB);
1091
0
    if (Parent || IsPartition)
1092
0
      OB += IsPartition ? ':' : '.';
1093
0
    Name->print(OB);
1094
0
  }
1095
};
1096
1097
struct ModuleEntity : Node {
1098
  ModuleName *Module;
1099
  Node *Name;
1100
1101
  ModuleEntity(ModuleName *Module_, Node *Name_)
1102
0
      : Node(KModuleEntity), Module(Module_), Name(Name_) {}
1103
1104
0
  template <typename Fn> void match(Fn F) const { F(Module, Name); }
1105
1106
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1107
1108
0
  void printLeft(OutputBuffer &OB) const override {
1109
0
    Name->print(OB);
1110
0
    OB += '@';
1111
0
    Module->print(OB);
1112
0
  }
1113
};
1114
1115
struct LocalName : Node {
1116
  Node *Encoding;
1117
  Node *Entity;
1118
1119
  LocalName(Node *Encoding_, Node *Entity_)
1120
0
      : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
1121
1122
0
  template<typename Fn> void match(Fn F) const { F(Encoding, Entity); }
1123
1124
0
  void printLeft(OutputBuffer &OB) const override {
1125
0
    Encoding->print(OB);
1126
0
    OB += "::";
1127
0
    Entity->print(OB);
1128
0
  }
1129
};
1130
1131
class QualifiedName final : public Node {
1132
  // qualifier::name
1133
  const Node *Qualifier;
1134
  const Node *Name;
1135
1136
public:
1137
  QualifiedName(const Node *Qualifier_, const Node *Name_)
1138
0
      : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
1139
1140
0
  template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
1141
1142
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1143
1144
0
  void printLeft(OutputBuffer &OB) const override {
1145
0
    Qualifier->print(OB);
1146
0
    OB += "::";
1147
0
    Name->print(OB);
1148
0
  }
1149
};
1150
1151
class VectorType final : public Node {
1152
  const Node *BaseType;
1153
  const Node *Dimension;
1154
1155
public:
1156
  VectorType(const Node *BaseType_, const Node *Dimension_)
1157
0
      : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {}
1158
1159
0
  const Node *getBaseType() const { return BaseType; }
1160
0
  const Node *getDimension() const { return Dimension; }
1161
1162
0
  template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); }
1163
1164
0
  void printLeft(OutputBuffer &OB) const override {
1165
0
    BaseType->print(OB);
1166
0
    OB += " vector[";
1167
0
    if (Dimension)
1168
0
      Dimension->print(OB);
1169
0
    OB += "]";
1170
0
  }
1171
};
1172
1173
class PixelVectorType final : public Node {
1174
  const Node *Dimension;
1175
1176
public:
1177
  PixelVectorType(const Node *Dimension_)
1178
0
      : Node(KPixelVectorType), Dimension(Dimension_) {}
1179
1180
0
  template<typename Fn> void match(Fn F) const { F(Dimension); }
1181
1182
0
  void printLeft(OutputBuffer &OB) const override {
1183
    // FIXME: This should demangle as "vector pixel".
1184
0
    OB += "pixel vector[";
1185
0
    Dimension->print(OB);
1186
0
    OB += "]";
1187
0
  }
1188
};
1189
1190
class BinaryFPType final : public Node {
1191
  const Node *Dimension;
1192
1193
public:
1194
  BinaryFPType(const Node *Dimension_)
1195
0
      : Node(KBinaryFPType), Dimension(Dimension_) {}
1196
1197
0
  template<typename Fn> void match(Fn F) const { F(Dimension); }
1198
1199
0
  void printLeft(OutputBuffer &OB) const override {
1200
0
    OB += "_Float";
1201
0
    Dimension->print(OB);
1202
0
  }
1203
};
1204
1205
enum class TemplateParamKind { Type, NonType, Template };
1206
1207
/// An invented name for a template parameter for which we don't have a
1208
/// corresponding template argument.
1209
///
1210
/// This node is created when parsing the <lambda-sig> for a lambda with
1211
/// explicit template arguments, which might be referenced in the parameter
1212
/// types appearing later in the <lambda-sig>.
1213
class SyntheticTemplateParamName final : public Node {
1214
  TemplateParamKind Kind;
1215
  unsigned Index;
1216
1217
public:
1218
  SyntheticTemplateParamName(TemplateParamKind Kind_, unsigned Index_)
1219
0
      : Node(KSyntheticTemplateParamName), Kind(Kind_), Index(Index_) {}
1220
1221
0
  template<typename Fn> void match(Fn F) const { F(Kind, Index); }
1222
1223
0
  void printLeft(OutputBuffer &OB) const override {
1224
0
    switch (Kind) {
1225
0
    case TemplateParamKind::Type:
1226
0
      OB += "$T";
1227
0
      break;
1228
0
    case TemplateParamKind::NonType:
1229
0
      OB += "$N";
1230
0
      break;
1231
0
    case TemplateParamKind::Template:
1232
0
      OB += "$TT";
1233
0
      break;
1234
0
    }
1235
0
    if (Index > 0)
1236
0
      OB << Index - 1;
1237
0
  }
1238
};
1239
1240
class TemplateParamQualifiedArg final : public Node {
1241
  Node *Param;
1242
  Node *Arg;
1243
1244
public:
1245
  TemplateParamQualifiedArg(Node *Param_, Node *Arg_)
1246
0
      : Node(KTemplateParamQualifiedArg), Param(Param_), Arg(Arg_) {}
1247
1248
0
  template <typename Fn> void match(Fn F) const { F(Param, Arg); }
1249
1250
0
  Node *getArg() { return Arg; }
1251
1252
0
  void printLeft(OutputBuffer &OB) const override {
1253
    // Don't print Param to keep the output consistent.
1254
0
    Arg->print(OB);
1255
0
  }
1256
};
1257
1258
/// A template type parameter declaration, 'typename T'.
1259
class TypeTemplateParamDecl final : public Node {
1260
  Node *Name;
1261
1262
public:
1263
  TypeTemplateParamDecl(Node *Name_)
1264
0
      : Node(KTypeTemplateParamDecl, Cache::Yes), Name(Name_) {}
1265
1266
0
  template<typename Fn> void match(Fn F) const { F(Name); }
1267
1268
0
  void printLeft(OutputBuffer &OB) const override { OB += "typename "; }
1269
1270
0
  void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1271
};
1272
1273
/// A constrained template type parameter declaration, 'C<U> T'.
1274
class ConstrainedTypeTemplateParamDecl final : public Node {
1275
  Node *Constraint;
1276
  Node *Name;
1277
1278
public:
1279
  ConstrainedTypeTemplateParamDecl(Node *Constraint_, Node *Name_)
1280
0
      : Node(KConstrainedTypeTemplateParamDecl, Cache::Yes),
1281
0
        Constraint(Constraint_), Name(Name_) {}
1282
1283
0
  template<typename Fn> void match(Fn F) const { F(Constraint, Name); }
1284
1285
0
  void printLeft(OutputBuffer &OB) const override {
1286
0
    Constraint->print(OB);
1287
0
    OB += " ";
1288
0
  }
1289
1290
0
  void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1291
};
1292
1293
/// A non-type template parameter declaration, 'int N'.
1294
class NonTypeTemplateParamDecl final : public Node {
1295
  Node *Name;
1296
  Node *Type;
1297
1298
public:
1299
  NonTypeTemplateParamDecl(Node *Name_, Node *Type_)
1300
0
      : Node(KNonTypeTemplateParamDecl, Cache::Yes), Name(Name_), Type(Type_) {}
1301
1302
0
  template<typename Fn> void match(Fn F) const { F(Name, Type); }
1303
1304
0
  void printLeft(OutputBuffer &OB) const override {
1305
0
    Type->printLeft(OB);
1306
0
    if (!Type->hasRHSComponent(OB))
1307
0
      OB += " ";
1308
0
  }
1309
1310
0
  void printRight(OutputBuffer &OB) const override {
1311
0
    Name->print(OB);
1312
0
    Type->printRight(OB);
1313
0
  }
1314
};
1315
1316
/// A template template parameter declaration,
1317
/// 'template<typename T> typename N'.
1318
class TemplateTemplateParamDecl final : public Node {
1319
  Node *Name;
1320
  NodeArray Params;
1321
  Node *Requires;
1322
1323
public:
1324
  TemplateTemplateParamDecl(Node *Name_, NodeArray Params_, Node *Requires_)
1325
0
      : Node(KTemplateTemplateParamDecl, Cache::Yes), Name(Name_),
1326
0
        Params(Params_), Requires(Requires_) {}
1327
1328
0
  template <typename Fn> void match(Fn F) const { F(Name, Params, Requires); }
1329
1330
0
  void printLeft(OutputBuffer &OB) const override {
1331
0
    ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1332
0
    OB += "template<";
1333
0
    Params.printWithComma(OB);
1334
0
    OB += "> typename ";
1335
0
  }
1336
1337
0
  void printRight(OutputBuffer &OB) const override {
1338
0
    Name->print(OB);
1339
0
    if (Requires != nullptr) {
1340
0
      OB += " requires ";
1341
0
      Requires->print(OB);
1342
0
    }
1343
0
  }
1344
};
1345
1346
/// A template parameter pack declaration, 'typename ...T'.
1347
class TemplateParamPackDecl final : public Node {
1348
  Node *Param;
1349
1350
public:
1351
  TemplateParamPackDecl(Node *Param_)
1352
0
      : Node(KTemplateParamPackDecl, Cache::Yes), Param(Param_) {}
1353
1354
0
  template<typename Fn> void match(Fn F) const { F(Param); }
1355
1356
0
  void printLeft(OutputBuffer &OB) const override {
1357
0
    Param->printLeft(OB);
1358
0
    OB += "...";
1359
0
  }
1360
1361
0
  void printRight(OutputBuffer &OB) const override { Param->printRight(OB); }
1362
};
1363
1364
/// An unexpanded parameter pack (either in the expression or type context). If
1365
/// this AST is correct, this node will have a ParameterPackExpansion node above
1366
/// it.
1367
///
1368
/// This node is created when some <template-args> are found that apply to an
1369
/// <encoding>, and is stored in the TemplateParams table. In order for this to
1370
/// appear in the final AST, it has to referenced via a <template-param> (ie,
1371
/// T_).
1372
class ParameterPack final : public Node {
1373
  NodeArray Data;
1374
1375
  // Setup OutputBuffer for a pack expansion, unless we're already expanding
1376
  // one.
1377
0
  void initializePackExpansion(OutputBuffer &OB) const {
1378
0
    if (OB.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
1379
0
      OB.CurrentPackMax = static_cast<unsigned>(Data.size());
1380
0
      OB.CurrentPackIndex = 0;
1381
0
    }
1382
0
  }
1383
1384
public:
1385
0
  ParameterPack(NodeArray Data_) : Node(KParameterPack), Data(Data_) {
1386
0
    ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
1387
0
    if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1388
0
          return P->ArrayCache == Cache::No;
1389
0
        }))
1390
0
      ArrayCache = Cache::No;
1391
0
    if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1392
0
          return P->FunctionCache == Cache::No;
1393
0
        }))
1394
0
      FunctionCache = Cache::No;
1395
0
    if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
1396
0
          return P->RHSComponentCache == Cache::No;
1397
0
        }))
1398
0
      RHSComponentCache = Cache::No;
1399
0
  }
1400
1401
0
  template<typename Fn> void match(Fn F) const { F(Data); }
1402
1403
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1404
0
    initializePackExpansion(OB);
1405
0
    size_t Idx = OB.CurrentPackIndex;
1406
0
    return Idx < Data.size() && Data[Idx]->hasRHSComponent(OB);
1407
0
  }
1408
0
  bool hasArraySlow(OutputBuffer &OB) const override {
1409
0
    initializePackExpansion(OB);
1410
0
    size_t Idx = OB.CurrentPackIndex;
1411
0
    return Idx < Data.size() && Data[Idx]->hasArray(OB);
1412
0
  }
1413
0
  bool hasFunctionSlow(OutputBuffer &OB) const override {
1414
0
    initializePackExpansion(OB);
1415
0
    size_t Idx = OB.CurrentPackIndex;
1416
0
    return Idx < Data.size() && Data[Idx]->hasFunction(OB);
1417
0
  }
1418
0
  const Node *getSyntaxNode(OutputBuffer &OB) const override {
1419
0
    initializePackExpansion(OB);
1420
0
    size_t Idx = OB.CurrentPackIndex;
1421
0
    return Idx < Data.size() ? Data[Idx]->getSyntaxNode(OB) : this;
1422
0
  }
1423
1424
0
  void printLeft(OutputBuffer &OB) const override {
1425
0
    initializePackExpansion(OB);
1426
0
    size_t Idx = OB.CurrentPackIndex;
1427
0
    if (Idx < Data.size())
1428
0
      Data[Idx]->printLeft(OB);
1429
0
  }
1430
0
  void printRight(OutputBuffer &OB) const override {
1431
0
    initializePackExpansion(OB);
1432
0
    size_t Idx = OB.CurrentPackIndex;
1433
0
    if (Idx < Data.size())
1434
0
      Data[Idx]->printRight(OB);
1435
0
  }
1436
};
1437
1438
/// A variadic template argument. This node represents an occurrence of
1439
/// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1440
/// one of its Elements is. The parser inserts a ParameterPack into the
1441
/// TemplateParams table if the <template-args> this pack belongs to apply to an
1442
/// <encoding>.
1443
class TemplateArgumentPack final : public Node {
1444
  NodeArray Elements;
1445
public:
1446
  TemplateArgumentPack(NodeArray Elements_)
1447
0
      : Node(KTemplateArgumentPack), Elements(Elements_) {}
1448
1449
0
  template<typename Fn> void match(Fn F) const { F(Elements); }
1450
1451
0
  NodeArray getElements() const { return Elements; }
1452
1453
0
  void printLeft(OutputBuffer &OB) const override {
1454
0
    Elements.printWithComma(OB);
1455
0
  }
1456
};
1457
1458
/// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1459
/// which each have Child->ParameterPackSize elements.
1460
class ParameterPackExpansion final : public Node {
1461
  const Node *Child;
1462
1463
public:
1464
  ParameterPackExpansion(const Node *Child_)
1465
0
      : Node(KParameterPackExpansion), Child(Child_) {}
1466
1467
0
  template<typename Fn> void match(Fn F) const { F(Child); }
1468
1469
0
  const Node *getChild() const { return Child; }
1470
1471
0
  void printLeft(OutputBuffer &OB) const override {
1472
0
    constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1473
0
    ScopedOverride<unsigned> SavePackIdx(OB.CurrentPackIndex, Max);
1474
0
    ScopedOverride<unsigned> SavePackMax(OB.CurrentPackMax, Max);
1475
0
    size_t StreamPos = OB.getCurrentPosition();
1476
1477
    // Print the first element in the pack. If Child contains a ParameterPack,
1478
    // it will set up S.CurrentPackMax and print the first element.
1479
0
    Child->print(OB);
1480
1481
    // No ParameterPack was found in Child. This can occur if we've found a pack
1482
    // expansion on a <function-param>.
1483
0
    if (OB.CurrentPackMax == Max) {
1484
0
      OB += "...";
1485
0
      return;
1486
0
    }
1487
1488
    // We found a ParameterPack, but it has no elements. Erase whatever we may
1489
    // of printed.
1490
0
    if (OB.CurrentPackMax == 0) {
1491
0
      OB.setCurrentPosition(StreamPos);
1492
0
      return;
1493
0
    }
1494
1495
    // Else, iterate through the rest of the elements in the pack.
1496
0
    for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) {
1497
0
      OB += ", ";
1498
0
      OB.CurrentPackIndex = I;
1499
0
      Child->print(OB);
1500
0
    }
1501
0
  }
1502
};
1503
1504
class TemplateArgs final : public Node {
1505
  NodeArray Params;
1506
  Node *Requires;
1507
1508
public:
1509
  TemplateArgs(NodeArray Params_, Node *Requires_)
1510
0
      : Node(KTemplateArgs), Params(Params_), Requires(Requires_) {}
1511
1512
0
  template<typename Fn> void match(Fn F) const { F(Params, Requires); }
1513
1514
0
  NodeArray getParams() { return Params; }
1515
1516
0
  void printLeft(OutputBuffer &OB) const override {
1517
0
    ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1518
0
    OB += "<";
1519
0
    Params.printWithComma(OB);
1520
0
    OB += ">";
1521
    // Don't print the requires clause to keep the output simple.
1522
0
  }
1523
};
1524
1525
/// A forward-reference to a template argument that was not known at the point
1526
/// where the template parameter name was parsed in a mangling.
1527
///
1528
/// This is created when demangling the name of a specialization of a
1529
/// conversion function template:
1530
///
1531
/// \code
1532
/// struct A {
1533
///   template<typename T> operator T*();
1534
/// };
1535
/// \endcode
1536
///
1537
/// When demangling a specialization of the conversion function template, we
1538
/// encounter the name of the template (including the \c T) before we reach
1539
/// the template argument list, so we cannot substitute the parameter name
1540
/// for the corresponding argument while parsing. Instead, we create a
1541
/// \c ForwardTemplateReference node that is resolved after we parse the
1542
/// template arguments.
1543
struct ForwardTemplateReference : Node {
1544
  size_t Index;
1545
  Node *Ref = nullptr;
1546
1547
  // If we're currently printing this node. It is possible (though invalid) for
1548
  // a forward template reference to refer to itself via a substitution. This
1549
  // creates a cyclic AST, which will stack overflow printing. To fix this, bail
1550
  // out if more than one print* function is active.
1551
  mutable bool Printing = false;
1552
1553
  ForwardTemplateReference(size_t Index_)
1554
0
      : Node(KForwardTemplateReference, Cache::Unknown, Cache::Unknown,
1555
0
             Cache::Unknown),
1556
0
        Index(Index_) {}
1557
1558
  // We don't provide a matcher for these, because the value of the node is
1559
  // not determined by its construction parameters, and it generally needs
1560
  // special handling.
1561
  template<typename Fn> void match(Fn F) const = delete;
1562
1563
0
  bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1564
0
    if (Printing)
1565
0
      return false;
1566
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1567
0
    return Ref->hasRHSComponent(OB);
1568
0
  }
1569
0
  bool hasArraySlow(OutputBuffer &OB) const override {
1570
0
    if (Printing)
1571
0
      return false;
1572
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1573
0
    return Ref->hasArray(OB);
1574
0
  }
1575
0
  bool hasFunctionSlow(OutputBuffer &OB) const override {
1576
0
    if (Printing)
1577
0
      return false;
1578
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1579
0
    return Ref->hasFunction(OB);
1580
0
  }
1581
0
  const Node *getSyntaxNode(OutputBuffer &OB) const override {
1582
0
    if (Printing)
1583
0
      return this;
1584
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1585
0
    return Ref->getSyntaxNode(OB);
1586
0
  }
1587
1588
0
  void printLeft(OutputBuffer &OB) const override {
1589
0
    if (Printing)
1590
0
      return;
1591
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1592
0
    Ref->printLeft(OB);
1593
0
  }
1594
0
  void printRight(OutputBuffer &OB) const override {
1595
0
    if (Printing)
1596
0
      return;
1597
0
    ScopedOverride<bool> SavePrinting(Printing, true);
1598
0
    Ref->printRight(OB);
1599
0
  }
1600
};
1601
1602
struct NameWithTemplateArgs : Node {
1603
  // name<template_args>
1604
  Node *Name;
1605
  Node *TemplateArgs;
1606
1607
  NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
1608
0
      : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
1609
1610
0
  template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1611
1612
0
  std::string_view getBaseName() const override { return Name->getBaseName(); }
1613
1614
0
  void printLeft(OutputBuffer &OB) const override {
1615
0
    Name->print(OB);
1616
0
    TemplateArgs->print(OB);
1617
0
  }
1618
};
1619
1620
class GlobalQualifiedName final : public Node {
1621
  Node *Child;
1622
1623
public:
1624
  GlobalQualifiedName(Node* Child_)
1625
0
      : Node(KGlobalQualifiedName), Child(Child_) {}
1626
1627
0
  template<typename Fn> void match(Fn F) const { F(Child); }
1628
1629
0
  std::string_view getBaseName() const override { return Child->getBaseName(); }
1630
1631
0
  void printLeft(OutputBuffer &OB) const override {
1632
0
    OB += "::";
1633
0
    Child->print(OB);
1634
0
  }
1635
};
1636
1637
enum class SpecialSubKind {
1638
  allocator,
1639
  basic_string,
1640
  string,
1641
  istream,
1642
  ostream,
1643
  iostream,
1644
};
1645
1646
class SpecialSubstitution;
1647
class ExpandedSpecialSubstitution : public Node {
1648
protected:
1649
  SpecialSubKind SSK;
1650
1651
  ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1652
0
      : Node(K_), SSK(SSK_) {}
1653
public:
1654
  ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1655
0
      : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1656
  inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
1657
1658
0
  template<typename Fn> void match(Fn F) const { F(SSK); }
1659
1660
protected:
1661
0
  bool isInstantiation() const {
1662
0
    return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1663
0
  }
1664
1665
0
  std::string_view getBaseName() const override {
1666
0
    switch (SSK) {
1667
0
    case SpecialSubKind::allocator:
1668
0
      return {"allocator"};
1669
0
    case SpecialSubKind::basic_string:
1670
0
      return {"basic_string"};
1671
0
    case SpecialSubKind::string:
1672
0
      return {"basic_string"};
1673
0
    case SpecialSubKind::istream:
1674
0
      return {"basic_istream"};
1675
0
    case SpecialSubKind::ostream:
1676
0
      return {"basic_ostream"};
1677
0
    case SpecialSubKind::iostream:
1678
0
      return {"basic_iostream"};
1679
0
    }
1680
0
    DEMANGLE_UNREACHABLE;
1681
0
  }
1682
1683
private:
1684
0
  void printLeft(OutputBuffer &OB) const override {
1685
0
    OB << "std::" << getBaseName();
1686
0
    if (isInstantiation()) {
1687
0
      OB << "<char, std::char_traits<char>";
1688
0
      if (SSK == SpecialSubKind::string)
1689
0
        OB << ", std::allocator<char>";
1690
0
      OB << ">";
1691
0
    }
1692
0
  }
1693
};
1694
1695
class SpecialSubstitution final : public ExpandedSpecialSubstitution {
1696
public:
1697
  SpecialSubstitution(SpecialSubKind SSK_)
1698
0
      : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
1699
1700
0
  template<typename Fn> void match(Fn F) const { F(SSK); }
1701
1702
0
  std::string_view getBaseName() const override {
1703
0
    std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
1704
0
    if (isInstantiation()) {
1705
      // The instantiations are typedefs that drop the "basic_" prefix.
1706
0
      DEMANGLE_ASSERT(starts_with(SV, "basic_"), "");
1707
0
      SV.remove_prefix(sizeof("basic_") - 1);
1708
0
    }
1709
0
    return SV;
1710
0
  }
1711
1712
0
  void printLeft(OutputBuffer &OB) const override {
1713
0
    OB << "std::" << getBaseName();
1714
0
  }
1715
};
1716
1717
inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1718
    SpecialSubstitution const *SS)
1719
0
    : ExpandedSpecialSubstitution(SS->SSK) {}
1720
1721
class CtorDtorName final : public Node {
1722
  const Node *Basename;
1723
  const bool IsDtor;
1724
  const int Variant;
1725
1726
public:
1727
  CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
1728
0
      : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1729
0
        Variant(Variant_) {}
1730
1731
0
  template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1732
1733
0
  void printLeft(OutputBuffer &OB) const override {
1734
0
    if (IsDtor)
1735
0
      OB += "~";
1736
0
    OB += Basename->getBaseName();
1737
0
  }
1738
};
1739
1740
class DtorName : public Node {
1741
  const Node *Base;
1742
1743
public:
1744
0
  DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1745
1746
0
  template<typename Fn> void match(Fn F) const { F(Base); }
1747
1748
0
  void printLeft(OutputBuffer &OB) const override {
1749
0
    OB += "~";
1750
0
    Base->printLeft(OB);
1751
0
  }
1752
};
1753
1754
class UnnamedTypeName : public Node {
1755
  const std::string_view Count;
1756
1757
public:
1758
  UnnamedTypeName(std::string_view Count_)
1759
0
      : Node(KUnnamedTypeName), Count(Count_) {}
1760
1761
0
  template<typename Fn> void match(Fn F) const { F(Count); }
1762
1763
0
  void printLeft(OutputBuffer &OB) const override {
1764
0
    OB += "'unnamed";
1765
0
    OB += Count;
1766
0
    OB += "\'";
1767
0
  }
1768
};
1769
1770
class ClosureTypeName : public Node {
1771
  NodeArray TemplateParams;
1772
  const Node *Requires1;
1773
  NodeArray Params;
1774
  const Node *Requires2;
1775
  std::string_view Count;
1776
1777
public:
1778
  ClosureTypeName(NodeArray TemplateParams_, const Node *Requires1_,
1779
                  NodeArray Params_, const Node *Requires2_,
1780
                  std::string_view Count_)
1781
0
      : Node(KClosureTypeName), TemplateParams(TemplateParams_),
1782
0
        Requires1(Requires1_), Params(Params_), Requires2(Requires2_),
1783
0
        Count(Count_) {}
1784
1785
0
  template<typename Fn> void match(Fn F) const {
1786
0
    F(TemplateParams, Requires1, Params, Requires2, Count);
1787
0
  }
1788
1789
0
  void printDeclarator(OutputBuffer &OB) const {
1790
0
    if (!TemplateParams.empty()) {
1791
0
      ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1792
0
      OB += "<";
1793
0
      TemplateParams.printWithComma(OB);
1794
0
      OB += ">";
1795
0
    }
1796
0
    if (Requires1 != nullptr) {
1797
0
      OB += " requires ";
1798
0
      Requires1->print(OB);
1799
0
      OB += " ";
1800
0
    }
1801
0
    OB.printOpen();
1802
0
    Params.printWithComma(OB);
1803
0
    OB.printClose();
1804
0
    if (Requires2 != nullptr) {
1805
0
      OB += " requires ";
1806
0
      Requires2->print(OB);
1807
0
    }
1808
0
  }
1809
1810
0
  void printLeft(OutputBuffer &OB) const override {
1811
    // FIXME: This demangling is not particularly readable.
1812
0
    OB += "\'lambda";
1813
0
    OB += Count;
1814
0
    OB += "\'";
1815
0
    printDeclarator(OB);
1816
0
  }
1817
};
1818
1819
class StructuredBindingName : public Node {
1820
  NodeArray Bindings;
1821
public:
1822
  StructuredBindingName(NodeArray Bindings_)
1823
0
      : Node(KStructuredBindingName), Bindings(Bindings_) {}
1824
1825
0
  template<typename Fn> void match(Fn F) const { F(Bindings); }
1826
1827
0
  void printLeft(OutputBuffer &OB) const override {
1828
0
    OB.printOpen('[');
1829
0
    Bindings.printWithComma(OB);
1830
0
    OB.printClose(']');
1831
0
  }
1832
};
1833
1834
// -- Expression Nodes --
1835
1836
class BinaryExpr : public Node {
1837
  const Node *LHS;
1838
  const std::string_view InfixOperator;
1839
  const Node *RHS;
1840
1841
public:
1842
  BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
1843
             const Node *RHS_, Prec Prec_)
1844
0
      : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
1845
0
        RHS(RHS_) {}
1846
1847
0
  template <typename Fn> void match(Fn F) const {
1848
0
    F(LHS, InfixOperator, RHS, getPrecedence());
1849
0
  }
1850
1851
0
  void printLeft(OutputBuffer &OB) const override {
1852
0
    bool ParenAll = OB.isGtInsideTemplateArgs() &&
1853
0
                    (InfixOperator == ">" || InfixOperator == ">>");
1854
0
    if (ParenAll)
1855
0
      OB.printOpen();
1856
    // Assignment is right associative, with special LHS precedence.
1857
0
    bool IsAssign = getPrecedence() == Prec::Assign;
1858
0
    LHS->printAsOperand(OB, IsAssign ? Prec::OrIf : getPrecedence(), !IsAssign);
1859
    // No space before comma operator
1860
0
    if (!(InfixOperator == ","))
1861
0
      OB += " ";
1862
0
    OB += InfixOperator;
1863
0
    OB += " ";
1864
0
    RHS->printAsOperand(OB, getPrecedence(), IsAssign);
1865
0
    if (ParenAll)
1866
0
      OB.printClose();
1867
0
  }
1868
};
1869
1870
class ArraySubscriptExpr : public Node {
1871
  const Node *Op1;
1872
  const Node *Op2;
1873
1874
public:
1875
  ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_)
1876
0
      : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {}
1877
1878
0
  template <typename Fn> void match(Fn F) const {
1879
0
    F(Op1, Op2, getPrecedence());
1880
0
  }
1881
1882
0
  void printLeft(OutputBuffer &OB) const override {
1883
0
    Op1->printAsOperand(OB, getPrecedence());
1884
0
    OB.printOpen('[');
1885
0
    Op2->printAsOperand(OB);
1886
0
    OB.printClose(']');
1887
0
  }
1888
};
1889
1890
class PostfixExpr : public Node {
1891
  const Node *Child;
1892
  const std::string_view Operator;
1893
1894
public:
1895
  PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
1896
0
      : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
1897
1898
0
  template <typename Fn> void match(Fn F) const {
1899
0
    F(Child, Operator, getPrecedence());
1900
0
  }
1901
1902
0
  void printLeft(OutputBuffer &OB) const override {
1903
0
    Child->printAsOperand(OB, getPrecedence(), true);
1904
0
    OB += Operator;
1905
0
  }
1906
};
1907
1908
class ConditionalExpr : public Node {
1909
  const Node *Cond;
1910
  const Node *Then;
1911
  const Node *Else;
1912
1913
public:
1914
  ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_,
1915
                  Prec Prec_)
1916
0
      : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {}
1917
1918
0
  template <typename Fn> void match(Fn F) const {
1919
0
    F(Cond, Then, Else, getPrecedence());
1920
0
  }
1921
1922
0
  void printLeft(OutputBuffer &OB) const override {
1923
0
    Cond->printAsOperand(OB, getPrecedence());
1924
0
    OB += " ? ";
1925
0
    Then->printAsOperand(OB);
1926
0
    OB += " : ";
1927
0
    Else->printAsOperand(OB, Prec::Assign, true);
1928
0
  }
1929
};
1930
1931
class MemberExpr : public Node {
1932
  const Node *LHS;
1933
  const std::string_view Kind;
1934
  const Node *RHS;
1935
1936
public:
1937
  MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
1938
             Prec Prec_)
1939
0
      : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
1940
1941
0
  template <typename Fn> void match(Fn F) const {
1942
0
    F(LHS, Kind, RHS, getPrecedence());
1943
0
  }
1944
1945
0
  void printLeft(OutputBuffer &OB) const override {
1946
0
    LHS->printAsOperand(OB, getPrecedence(), true);
1947
0
    OB += Kind;
1948
0
    RHS->printAsOperand(OB, getPrecedence(), false);
1949
0
  }
1950
};
1951
1952
class SubobjectExpr : public Node {
1953
  const Node *Type;
1954
  const Node *SubExpr;
1955
  std::string_view Offset;
1956
  NodeArray UnionSelectors;
1957
  bool OnePastTheEnd;
1958
1959
public:
1960
  SubobjectExpr(const Node *Type_, const Node *SubExpr_,
1961
                std::string_view Offset_, NodeArray UnionSelectors_,
1962
                bool OnePastTheEnd_)
1963
0
      : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
1964
0
        UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
1965
1966
0
  template<typename Fn> void match(Fn F) const {
1967
0
    F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
1968
0
  }
1969
1970
0
  void printLeft(OutputBuffer &OB) const override {
1971
0
    SubExpr->print(OB);
1972
0
    OB += ".<";
1973
0
    Type->print(OB);
1974
0
    OB += " at offset ";
1975
0
    if (Offset.empty()) {
1976
0
      OB += "0";
1977
0
    } else if (Offset[0] == 'n') {
1978
0
      OB += "-";
1979
0
      OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
1980
0
    } else {
1981
0
      OB += Offset;
1982
0
    }
1983
0
    OB += ">";
1984
0
  }
1985
};
1986
1987
class EnclosingExpr : public Node {
1988
  const std::string_view Prefix;
1989
  const Node *Infix;
1990
  const std::string_view Postfix;
1991
1992
public:
1993
  EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
1994
                Prec Prec_ = Prec::Primary)
1995
0
      : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
1996
1997
0
  template <typename Fn> void match(Fn F) const {
1998
0
    F(Prefix, Infix, getPrecedence());
1999
0
  }
2000
2001
0
  void printLeft(OutputBuffer &OB) const override {
2002
0
    OB += Prefix;
2003
0
    OB.printOpen();
2004
0
    Infix->print(OB);
2005
0
    OB.printClose();
2006
0
    OB += Postfix;
2007
0
  }
2008
};
2009
2010
class CastExpr : public Node {
2011
  // cast_kind<to>(from)
2012
  const std::string_view CastKind;
2013
  const Node *To;
2014
  const Node *From;
2015
2016
public:
2017
  CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
2018
           Prec Prec_)
2019
0
      : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
2020
2021
0
  template <typename Fn> void match(Fn F) const {
2022
0
    F(CastKind, To, From, getPrecedence());
2023
0
  }
2024
2025
0
  void printLeft(OutputBuffer &OB) const override {
2026
0
    OB += CastKind;
2027
0
    {
2028
0
      ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
2029
0
      OB += "<";
2030
0
      To->printLeft(OB);
2031
0
      OB += ">";
2032
0
    }
2033
0
    OB.printOpen();
2034
0
    From->printAsOperand(OB);
2035
0
    OB.printClose();
2036
0
  }
2037
};
2038
2039
class SizeofParamPackExpr : public Node {
2040
  const Node *Pack;
2041
2042
public:
2043
  SizeofParamPackExpr(const Node *Pack_)
2044
0
      : Node(KSizeofParamPackExpr), Pack(Pack_) {}
2045
2046
0
  template<typename Fn> void match(Fn F) const { F(Pack); }
2047
2048
0
  void printLeft(OutputBuffer &OB) const override {
2049
0
    OB += "sizeof...";
2050
0
    OB.printOpen();
2051
0
    ParameterPackExpansion PPE(Pack);
2052
0
    PPE.printLeft(OB);
2053
0
    OB.printClose();
2054
0
  }
2055
};
2056
2057
class CallExpr : public Node {
2058
  const Node *Callee;
2059
  NodeArray Args;
2060
2061
public:
2062
  CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_)
2063
0
      : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {}
2064
2065
0
  template <typename Fn> void match(Fn F) const {
2066
0
    F(Callee, Args, getPrecedence());
2067
0
  }
2068
2069
0
  void printLeft(OutputBuffer &OB) const override {
2070
0
    Callee->print(OB);
2071
0
    OB.printOpen();
2072
0
    Args.printWithComma(OB);
2073
0
    OB.printClose();
2074
0
  }
2075
};
2076
2077
class NewExpr : public Node {
2078
  // new (expr_list) type(init_list)
2079
  NodeArray ExprList;
2080
  Node *Type;
2081
  NodeArray InitList;
2082
  bool IsGlobal; // ::operator new ?
2083
  bool IsArray;  // new[] ?
2084
public:
2085
  NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
2086
          bool IsArray_, Prec Prec_)
2087
0
      : Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_),
2088
0
        InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
2089
2090
0
  template<typename Fn> void match(Fn F) const {
2091
0
    F(ExprList, Type, InitList, IsGlobal, IsArray, getPrecedence());
2092
0
  }
2093
2094
0
  void printLeft(OutputBuffer &OB) const override {
2095
0
    if (IsGlobal)
2096
0
      OB += "::";
2097
0
    OB += "new";
2098
0
    if (IsArray)
2099
0
      OB += "[]";
2100
0
    if (!ExprList.empty()) {
2101
0
      OB.printOpen();
2102
0
      ExprList.printWithComma(OB);
2103
0
      OB.printClose();
2104
0
    }
2105
0
    OB += " ";
2106
0
    Type->print(OB);
2107
0
    if (!InitList.empty()) {
2108
0
      OB.printOpen();
2109
0
      InitList.printWithComma(OB);
2110
0
      OB.printClose();
2111
0
    }
2112
0
  }
2113
};
2114
2115
class DeleteExpr : public Node {
2116
  Node *Op;
2117
  bool IsGlobal;
2118
  bool IsArray;
2119
2120
public:
2121
  DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_)
2122
0
      : Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_),
2123
0
        IsArray(IsArray_) {}
2124
2125
0
  template <typename Fn> void match(Fn F) const {
2126
0
    F(Op, IsGlobal, IsArray, getPrecedence());
2127
0
  }
2128
2129
0
  void printLeft(OutputBuffer &OB) const override {
2130
0
    if (IsGlobal)
2131
0
      OB += "::";
2132
0
    OB += "delete";
2133
0
    if (IsArray)
2134
0
      OB += "[]";
2135
0
    OB += ' ';
2136
0
    Op->print(OB);
2137
0
  }
2138
};
2139
2140
class PrefixExpr : public Node {
2141
  std::string_view Prefix;
2142
  Node *Child;
2143
2144
public:
2145
  PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
2146
0
      : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
2147
2148
0
  template <typename Fn> void match(Fn F) const {
2149
0
    F(Prefix, Child, getPrecedence());
2150
0
  }
2151
2152
0
  void printLeft(OutputBuffer &OB) const override {
2153
0
    OB += Prefix;
2154
0
    Child->printAsOperand(OB, getPrecedence());
2155
0
  }
2156
};
2157
2158
class FunctionParam : public Node {
2159
  std::string_view Number;
2160
2161
public:
2162
  FunctionParam(std::string_view Number_)
2163
0
      : Node(KFunctionParam), Number(Number_) {}
2164
2165
0
  template<typename Fn> void match(Fn F) const { F(Number); }
2166
2167
0
  void printLeft(OutputBuffer &OB) const override {
2168
0
    OB += "fp";
2169
0
    OB += Number;
2170
0
  }
2171
};
2172
2173
class ConversionExpr : public Node {
2174
  const Node *Type;
2175
  NodeArray Expressions;
2176
2177
public:
2178
  ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_)
2179
0
      : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {}
2180
2181
0
  template <typename Fn> void match(Fn F) const {
2182
0
    F(Type, Expressions, getPrecedence());
2183
0
  }
2184
2185
0
  void printLeft(OutputBuffer &OB) const override {
2186
0
    OB.printOpen();
2187
0
    Type->print(OB);
2188
0
    OB.printClose();
2189
0
    OB.printOpen();
2190
0
    Expressions.printWithComma(OB);
2191
0
    OB.printClose();
2192
0
  }
2193
};
2194
2195
class PointerToMemberConversionExpr : public Node {
2196
  const Node *Type;
2197
  const Node *SubExpr;
2198
  std::string_view Offset;
2199
2200
public:
2201
  PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
2202
                                std::string_view Offset_, Prec Prec_)
2203
0
      : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
2204
0
        SubExpr(SubExpr_), Offset(Offset_) {}
2205
2206
0
  template <typename Fn> void match(Fn F) const {
2207
0
    F(Type, SubExpr, Offset, getPrecedence());
2208
0
  }
2209
2210
0
  void printLeft(OutputBuffer &OB) const override {
2211
0
    OB.printOpen();
2212
0
    Type->print(OB);
2213
0
    OB.printClose();
2214
0
    OB.printOpen();
2215
0
    SubExpr->print(OB);
2216
0
    OB.printClose();
2217
0
  }
2218
};
2219
2220
class InitListExpr : public Node {
2221
  const Node *Ty;
2222
  NodeArray Inits;
2223
public:
2224
  InitListExpr(const Node *Ty_, NodeArray Inits_)
2225
0
      : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
2226
2227
0
  template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
2228
2229
0
  void printLeft(OutputBuffer &OB) const override {
2230
0
    if (Ty)
2231
0
      Ty->print(OB);
2232
0
    OB += '{';
2233
0
    Inits.printWithComma(OB);
2234
0
    OB += '}';
2235
0
  }
2236
};
2237
2238
class BracedExpr : public Node {
2239
  const Node *Elem;
2240
  const Node *Init;
2241
  bool IsArray;
2242
public:
2243
  BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
2244
0
      : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
2245
2246
0
  template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
2247
2248
0
  void printLeft(OutputBuffer &OB) const override {
2249
0
    if (IsArray) {
2250
0
      OB += '[';
2251
0
      Elem->print(OB);
2252
0
      OB += ']';
2253
0
    } else {
2254
0
      OB += '.';
2255
0
      Elem->print(OB);
2256
0
    }
2257
0
    if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2258
0
      OB += " = ";
2259
0
    Init->print(OB);
2260
0
  }
2261
};
2262
2263
class BracedRangeExpr : public Node {
2264
  const Node *First;
2265
  const Node *Last;
2266
  const Node *Init;
2267
public:
2268
  BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
2269
0
      : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
2270
2271
0
  template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
2272
2273
0
  void printLeft(OutputBuffer &OB) const override {
2274
0
    OB += '[';
2275
0
    First->print(OB);
2276
0
    OB += " ... ";
2277
0
    Last->print(OB);
2278
0
    OB += ']';
2279
0
    if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
2280
0
      OB += " = ";
2281
0
    Init->print(OB);
2282
0
  }
2283
};
2284
2285
class FoldExpr : public Node {
2286
  const Node *Pack, *Init;
2287
  std::string_view OperatorName;
2288
  bool IsLeftFold;
2289
2290
public:
2291
  FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
2292
           const Node *Init_)
2293
0
      : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
2294
0
        IsLeftFold(IsLeftFold_) {}
2295
2296
0
  template<typename Fn> void match(Fn F) const {
2297
0
    F(IsLeftFold, OperatorName, Pack, Init);
2298
0
  }
2299
2300
0
  void printLeft(OutputBuffer &OB) const override {
2301
0
    auto PrintPack = [&] {
2302
0
      OB.printOpen();
2303
0
      ParameterPackExpansion(Pack).print(OB);
2304
0
      OB.printClose();
2305
0
    };
2306
2307
0
    OB.printOpen();
2308
    // Either '[init op ]... op pack' or 'pack op ...[ op init]'
2309
    // Refactored to '[(init|pack) op ]...[ op (pack|init)]'
2310
    // Fold expr operands are cast-expressions
2311
0
    if (!IsLeftFold || Init != nullptr) {
2312
      // '(init|pack) op '
2313
0
      if (IsLeftFold)
2314
0
        Init->printAsOperand(OB, Prec::Cast, true);
2315
0
      else
2316
0
        PrintPack();
2317
0
      OB << " " << OperatorName << " ";
2318
0
    }
2319
0
    OB << "...";
2320
0
    if (IsLeftFold || Init != nullptr) {
2321
      // ' op (init|pack)'
2322
0
      OB << " " << OperatorName << " ";
2323
0
      if (IsLeftFold)
2324
0
        PrintPack();
2325
0
      else
2326
0
        Init->printAsOperand(OB, Prec::Cast, true);
2327
0
    }
2328
0
    OB.printClose();
2329
0
  }
2330
};
2331
2332
class ThrowExpr : public Node {
2333
  const Node *Op;
2334
2335
public:
2336
0
  ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
2337
2338
0
  template<typename Fn> void match(Fn F) const { F(Op); }
2339
2340
0
  void printLeft(OutputBuffer &OB) const override {
2341
0
    OB += "throw ";
2342
0
    Op->print(OB);
2343
0
  }
2344
};
2345
2346
class BoolExpr : public Node {
2347
  bool Value;
2348
2349
public:
2350
0
  BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
2351
2352
0
  template<typename Fn> void match(Fn F) const { F(Value); }
2353
2354
0
  void printLeft(OutputBuffer &OB) const override {
2355
0
    OB += Value ? std::string_view("true") : std::string_view("false");
2356
0
  }
2357
};
2358
2359
class StringLiteral : public Node {
2360
  const Node *Type;
2361
2362
public:
2363
0
  StringLiteral(const Node *Type_) : Node(KStringLiteral), Type(Type_) {}
2364
2365
0
  template<typename Fn> void match(Fn F) const { F(Type); }
2366
2367
0
  void printLeft(OutputBuffer &OB) const override {
2368
0
    OB += "\"<";
2369
0
    Type->print(OB);
2370
0
    OB += ">\"";
2371
0
  }
2372
};
2373
2374
class LambdaExpr : public Node {
2375
  const Node *Type;
2376
2377
public:
2378
0
  LambdaExpr(const Node *Type_) : Node(KLambdaExpr), Type(Type_) {}
2379
2380
0
  template<typename Fn> void match(Fn F) const { F(Type); }
2381
2382
0
  void printLeft(OutputBuffer &OB) const override {
2383
0
    OB += "[]";
2384
0
    if (Type->getKind() == KClosureTypeName)
2385
0
      static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB);
2386
0
    OB += "{...}";
2387
0
  }
2388
};
2389
2390
class EnumLiteral : public Node {
2391
  // ty(integer)
2392
  const Node *Ty;
2393
  std::string_view Integer;
2394
2395
public:
2396
  EnumLiteral(const Node *Ty_, std::string_view Integer_)
2397
0
      : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
2398
2399
0
  template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
2400
2401
0
  void printLeft(OutputBuffer &OB) const override {
2402
0
    OB.printOpen();
2403
0
    Ty->print(OB);
2404
0
    OB.printClose();
2405
2406
0
    if (Integer[0] == 'n')
2407
0
      OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
2408
0
    else
2409
0
      OB << Integer;
2410
0
  }
2411
};
2412
2413
class IntegerLiteral : public Node {
2414
  std::string_view Type;
2415
  std::string_view Value;
2416
2417
public:
2418
  IntegerLiteral(std::string_view Type_, std::string_view Value_)
2419
0
      : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
2420
2421
0
  template<typename Fn> void match(Fn F) const { F(Type, Value); }
2422
2423
0
  void printLeft(OutputBuffer &OB) const override {
2424
0
    if (Type.size() > 3) {
2425
0
      OB.printOpen();
2426
0
      OB += Type;
2427
0
      OB.printClose();
2428
0
    }
2429
2430
0
    if (Value[0] == 'n')
2431
0
      OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
2432
0
    else
2433
0
      OB += Value;
2434
2435
0
    if (Type.size() <= 3)
2436
0
      OB += Type;
2437
0
  }
2438
};
2439
2440
class RequiresExpr : public Node {
2441
  NodeArray Parameters;
2442
  NodeArray Requirements;
2443
public:
2444
  RequiresExpr(NodeArray Parameters_, NodeArray Requirements_)
2445
0
      : Node(KRequiresExpr), Parameters(Parameters_),
2446
0
        Requirements(Requirements_) {}
2447
2448
0
  template<typename Fn> void match(Fn F) const { F(Parameters, Requirements); }
2449
2450
0
  void printLeft(OutputBuffer &OB) const override {
2451
0
    OB += "requires";
2452
0
    if (!Parameters.empty()) {
2453
0
      OB += ' ';
2454
0
      OB.printOpen();
2455
0
      Parameters.printWithComma(OB);
2456
0
      OB.printClose();
2457
0
    }
2458
0
    OB += ' ';
2459
0
    OB.printOpen('{');
2460
0
    for (const Node *Req : Requirements) {
2461
0
      Req->print(OB);
2462
0
    }
2463
0
    OB += ' ';
2464
0
    OB.printClose('}');
2465
0
  }
2466
};
2467
2468
class ExprRequirement : public Node {
2469
  const Node *Expr;
2470
  bool IsNoexcept;
2471
  const Node *TypeConstraint;
2472
public:
2473
  ExprRequirement(const Node *Expr_, bool IsNoexcept_,
2474
                  const Node *TypeConstraint_)
2475
0
      : Node(KExprRequirement), Expr(Expr_), IsNoexcept(IsNoexcept_),
2476
0
        TypeConstraint(TypeConstraint_) {}
2477
2478
0
  template <typename Fn> void match(Fn F) const {
2479
0
    F(Expr, IsNoexcept, TypeConstraint);
2480
0
  }
2481
2482
0
  void printLeft(OutputBuffer &OB) const override {
2483
0
    OB += " ";
2484
0
    if (IsNoexcept || TypeConstraint)
2485
0
      OB.printOpen('{');
2486
0
    Expr->print(OB);
2487
0
    if (IsNoexcept || TypeConstraint)
2488
0
      OB.printClose('}');
2489
0
    if (IsNoexcept)
2490
0
      OB += " noexcept";
2491
0
    if (TypeConstraint) {
2492
0
      OB += " -> ";
2493
0
      TypeConstraint->print(OB);
2494
0
    }
2495
0
    OB += ';';
2496
0
  }
2497
};
2498
2499
class TypeRequirement : public Node {
2500
  const Node *Type;
2501
public:
2502
  TypeRequirement(const Node *Type_)
2503
0
      : Node(KTypeRequirement), Type(Type_) {}
2504
2505
0
  template <typename Fn> void match(Fn F) const { F(Type); }
2506
2507
0
  void printLeft(OutputBuffer &OB) const override {
2508
0
    OB += " typename ";
2509
0
    Type->print(OB);
2510
0
    OB += ';';
2511
0
  }
2512
};
2513
2514
class NestedRequirement : public Node {
2515
  const Node *Constraint;
2516
public:
2517
  NestedRequirement(const Node *Constraint_)
2518
0
      : Node(KNestedRequirement), Constraint(Constraint_) {}
2519
2520
0
  template <typename Fn> void match(Fn F) const { F(Constraint); }
2521
2522
0
  void printLeft(OutputBuffer &OB) const override {
2523
0
    OB += " requires ";
2524
0
    Constraint->print(OB);
2525
0
    OB += ';';
2526
0
  }
2527
};
2528
2529
template <class Float> struct FloatData;
2530
2531
namespace float_literal_impl {
2532
0
constexpr Node::Kind getFloatLiteralKind(float *) {
2533
0
  return Node::KFloatLiteral;
2534
0
}
2535
0
constexpr Node::Kind getFloatLiteralKind(double *) {
2536
0
  return Node::KDoubleLiteral;
2537
0
}
2538
0
constexpr Node::Kind getFloatLiteralKind(long double *) {
2539
0
  return Node::KLongDoubleLiteral;
2540
0
}
2541
}
2542
2543
template <class Float> class FloatLiteralImpl : public Node {
2544
  const std::string_view Contents;
2545
2546
  static constexpr Kind KindForClass =
2547
      float_literal_impl::getFloatLiteralKind((Float *)nullptr);
2548
2549
public:
2550
  FloatLiteralImpl(std::string_view Contents_)
2551
0
      : Node(KindForClass), Contents(Contents_) {}
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<float>::FloatLiteralImpl(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<double>::FloatLiteralImpl(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double>::FloatLiteralImpl(std::__1::basic_string_view<char, std::__1::char_traits<char> >)
2552
2553
0
  template<typename Fn> void match(Fn F) const { F(Contents); }
Unexecuted instantiation: cxa_demangle.cpp:void (anonymous namespace)::itanium_demangle::FloatLiteralImpl<float>::match<(anonymous namespace)::DumpVisitor::CtorArgPrinter>((anonymous namespace)::DumpVisitor::CtorArgPrinter) const
Unexecuted instantiation: cxa_demangle.cpp:void (anonymous namespace)::itanium_demangle::FloatLiteralImpl<double>::match<(anonymous namespace)::DumpVisitor::CtorArgPrinter>((anonymous namespace)::DumpVisitor::CtorArgPrinter) const
Unexecuted instantiation: cxa_demangle.cpp:void (anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double>::match<(anonymous namespace)::DumpVisitor::CtorArgPrinter>((anonymous namespace)::DumpVisitor::CtorArgPrinter) const
2554
2555
0
  void printLeft(OutputBuffer &OB) const override {
2556
0
    const size_t N = FloatData<Float>::mangled_size;
2557
0
    if (Contents.size() >= N) {
2558
0
      union {
2559
0
        Float value;
2560
0
        char buf[sizeof(Float)];
2561
0
      };
2562
0
      const char *t = Contents.data();
2563
0
      const char *last = t + N;
2564
0
      char *e = buf;
2565
0
      for (; t != last; ++t, ++e) {
2566
0
        unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2567
0
                                  : static_cast<unsigned>(*t - 'a' + 10);
2568
0
        ++t;
2569
0
        unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
2570
0
                                  : static_cast<unsigned>(*t - 'a' + 10);
2571
0
        *e = static_cast<char>((d1 << 4) + d0);
2572
0
      }
2573
0
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2574
0
      std::reverse(buf, e);
2575
0
#endif
2576
0
      char num[FloatData<Float>::max_demangled_size] = {0};
2577
0
      int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
2578
0
      OB += std::string_view(num, n);
2579
0
    }
2580
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<float>::printLeft((anonymous namespace)::itanium_demangle::OutputBuffer&) const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<double>::printLeft((anonymous namespace)::itanium_demangle::OutputBuffer&) const
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double>::printLeft((anonymous namespace)::itanium_demangle::OutputBuffer&) const
2581
};
2582
2583
using FloatLiteral = FloatLiteralImpl<float>;
2584
using DoubleLiteral = FloatLiteralImpl<double>;
2585
using LongDoubleLiteral = FloatLiteralImpl<long double>;
2586
2587
/// Visit the node. Calls \c F(P), where \c P is the node cast to the
2588
/// appropriate derived class.
2589
template<typename Fn>
2590
0
void Node::visit(Fn F) const {
2591
0
  switch (K) {
2592
0
#define NODE(X)                                                                \
2593
0
  case K##X:                                                                   \
2594
0
    return F(static_cast<const X *>(this));
2595
0
#include "ItaniumNodes.def"
2596
0
  }
2597
0
  DEMANGLE_ASSERT(0, "unknown mangling node kind");
2598
0
}
2599
2600
/// Determine the kind of a node from its type.
2601
template<typename NodeT> struct NodeKind;
2602
#define NODE(X)                                                                \
2603
  template <> struct NodeKind<X> {                                             \
2604
    static constexpr Node::Kind Kind = Node::K##X;                             \
2605
0
    static constexpr const char *name() { return #X; }                         \
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NodeArrayNode>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::DotSuffix>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::VendorExtQualType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::QualType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ConversionOperatorType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PostfixQualifiedType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ElaboratedTypeSpefType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TransformedType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NameType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::AbiTagAttr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::EnableIfAttr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ObjCProtoName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PointerType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ReferenceType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PointerToMemberType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ArrayType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FunctionType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NoexceptSpec>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::DynamicExceptionSpec>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FunctionEncoding>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::LiteralOperator>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SpecialName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::CtorVtableSpecialName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::QualifiedName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NestedName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::MemberLikeFriendName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::LocalName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ModuleName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ModuleEntity>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::VectorType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PixelVectorType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BinaryFPType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BitIntType>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SyntheticTemplateParamName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateParamQualifiedArg>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TypeTemplateParamDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ConstrainedTypeTemplateParamDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NonTypeTemplateParamDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateTemplateParamDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateParamPackDecl>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ParameterPack>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateArgumentPack>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ParameterPackExpansion>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TemplateArgs>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NameWithTemplateArgs>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::GlobalQualifiedName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ExpandedSpecialSubstitution>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SpecialSubstitution>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::CtorDtorName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::DtorName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::UnnamedTypeName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ClosureTypeName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::StructuredBindingName>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BinaryExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ArraySubscriptExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PostfixExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ConditionalExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::MemberExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SubobjectExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::EnclosingExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::CastExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::SizeofParamPackExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::CallExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NewExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::DeleteExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PrefixExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FunctionParam>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ConversionExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::PointerToMemberConversionExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::InitListExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FoldExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ThrowExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BoolExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::StringLiteral>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::LambdaExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::EnumLiteral>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::IntegerLiteral>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<float> >::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<double> >::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double> >::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BracedExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::BracedRangeExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::RequiresExpr>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ExprRequirement>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::TypeRequirement>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::NestedRequirement>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ExplicitObjectParameter>::name()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::NodeKind<(anonymous namespace)::itanium_demangle::ForwardTemplateReference>::name()
2606
  };
2607
#include "ItaniumNodes.def"
2608
2609
template <typename Derived, typename Alloc> struct AbstractManglingParser {
2610
  const char *First;
2611
  const char *Last;
2612
2613
  // Name stack, this is used by the parser to hold temporary names that were
2614
  // parsed. The parser collapses multiple names into new nodes to construct
2615
  // the AST. Once the parser is finished, names.size() == 1.
2616
  PODSmallVector<Node *, 32> Names;
2617
2618
  // Substitution table. Itanium supports name substitutions as a means of
2619
  // compression. The string "S42_" refers to the 44nd entry (base-36) in this
2620
  // table.
2621
  PODSmallVector<Node *, 32> Subs;
2622
2623
  // A list of template argument values corresponding to a template parameter
2624
  // list.
2625
  using TemplateParamList = PODSmallVector<Node *, 8>;
2626
2627
  class ScopedTemplateParamList {
2628
    AbstractManglingParser *Parser;
2629
    size_t OldNumTemplateParamLists;
2630
    TemplateParamList Params;
2631
2632
  public:
2633
    ScopedTemplateParamList(AbstractManglingParser *TheParser)
2634
0
        : Parser(TheParser),
2635
0
          OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
2636
0
      Parser->TemplateParams.push_back(&Params);
2637
0
    }
2638
0
    ~ScopedTemplateParamList() {
2639
0
      DEMANGLE_ASSERT(Parser->TemplateParams.size() >= OldNumTemplateParamLists,
2640
0
                      "");
2641
0
      Parser->TemplateParams.shrinkToSize(OldNumTemplateParamLists);
2642
0
    }
2643
0
    TemplateParamList *params() { return &Params; }
2644
  };
2645
2646
  // Template parameter table. Like the above, but referenced like "T42_".
2647
  // This has a smaller size compared to Subs and Names because it can be
2648
  // stored on the stack.
2649
  TemplateParamList OuterTemplateParams;
2650
2651
  // Lists of template parameters indexed by template parameter depth,
2652
  // referenced like "TL2_4_". If nonempty, element 0 is always
2653
  // OuterTemplateParams; inner elements are always template parameter lists of
2654
  // lambda expressions. For a generic lambda with no explicit template
2655
  // parameter list, the corresponding parameter list pointer will be null.
2656
  PODSmallVector<TemplateParamList *, 4> TemplateParams;
2657
2658
  class SaveTemplateParams {
2659
    AbstractManglingParser *Parser;
2660
    decltype(TemplateParams) OldParams;
2661
    decltype(OuterTemplateParams) OldOuterParams;
2662
2663
  public:
2664
0
    SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
2665
0
      OldParams = std::move(Parser->TemplateParams);
2666
0
      OldOuterParams = std::move(Parser->OuterTemplateParams);
2667
0
      Parser->TemplateParams.clear();
2668
0
      Parser->OuterTemplateParams.clear();
2669
0
    }
2670
0
    ~SaveTemplateParams() {
2671
0
      Parser->TemplateParams = std::move(OldParams);
2672
0
      Parser->OuterTemplateParams = std::move(OldOuterParams);
2673
0
    }
2674
  };
2675
2676
  // Set of unresolved forward <template-param> references. These can occur in a
2677
  // conversion operator's type, and are resolved in the enclosing <encoding>.
2678
  PODSmallVector<ForwardTemplateReference *, 4> ForwardTemplateRefs;
2679
2680
  bool TryToParseTemplateArgs = true;
2681
  bool PermitForwardTemplateReferences = false;
2682
  bool InConstraintExpr = false;
2683
  size_t ParsingLambdaParamsAtLevel = (size_t)-1;
2684
2685
  unsigned NumSyntheticTemplateParameters[3] = {};
2686
2687
  Alloc ASTAllocator;
2688
2689
  AbstractManglingParser(const char *First_, const char *Last_)
2690
0
      : First(First_), Last(Last_) {}
2691
2692
0
  Derived &getDerived() { return static_cast<Derived &>(*this); }
2693
2694
  void reset(const char *First_, const char *Last_) {
2695
    First = First_;
2696
    Last = Last_;
2697
    Names.clear();
2698
    Subs.clear();
2699
    TemplateParams.clear();
2700
    ParsingLambdaParamsAtLevel = (size_t)-1;
2701
    TryToParseTemplateArgs = true;
2702
    PermitForwardTemplateReferences = false;
2703
    for (int I = 0; I != 3; ++I)
2704
      NumSyntheticTemplateParameters[I] = 0;
2705
    ASTAllocator.reset();
2706
  }
2707
2708
0
  template <class T, class... Args> Node *make(Args &&... args) {
2709
0
    return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2710
0
  }
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [31], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [31], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [12], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [12], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [9], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [9], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [14], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [14], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [19], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [19], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [27], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [27], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::CtorVtableSpecialName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [41], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [41], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [18], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [18], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [22], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [22], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [20], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [20], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [25], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [25], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [22]>(char const (&) [22])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ModuleName, (anonymous namespace)::itanium_demangle::ModuleName*&, (anonymous namespace)::itanium_demangle::Node*&, bool&>((anonymous namespace)::itanium_demangle::ModuleName*&, (anonymous namespace)::itanium_demangle::Node*&, bool&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [24], (anonymous namespace)::itanium_demangle::ModuleName*&>(char const (&) [24], (anonymous namespace)::itanium_demangle::ModuleName*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, std::__1::basic_string_view<char, std::__1::char_traits<char> > >(std::__1::basic_string_view<char, std::__1::char_traits<char> >&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ForwardTemplateReference, unsigned long&>(unsigned long&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [5]>(char const (&) [5])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BinaryExpr, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PrefixExpr, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PostfixExpr, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ArraySubscriptExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::MemberExpr, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NewExpr, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, bool&, bool, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, bool&, bool&&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::DeleteExpr, (anonymous namespace)::itanium_demangle::Node*&, bool&, bool, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, bool&, bool&&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::CallExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ConversionExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ConditionalExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::CastExpr, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnclosingExpr, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::IntegerLiteral, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BoolExpr, int>(int&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<float>, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<double>, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FloatLiteralImpl<long double>, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::StringLiteral, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [8]>(char const (&) [8])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::UnnamedTypeName, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SyntheticTemplateParamName, (anonymous namespace)::itanium_demangle::TemplateParamKind&, unsigned int&>((anonymous namespace)::itanium_demangle::TemplateParamKind&, unsigned int&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TypeTemplateParamDecl, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ConstrainedTypeTemplateParamDecl, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NonTypeTemplateParamDecl, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateTemplateParamDecl, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateParamPackDecl, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ClosureTypeName, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [16]>(char const (&) [16])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::LambdaExpr, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnumLiteral, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FunctionParam, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FoldExpr, bool&, std::__1::basic_string_view<char, std::__1::char_traits<char> >, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>(bool&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BracedExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, bool>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, bool&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BracedRangeExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::InitListExpr, decltype(nullptr), (anonymous namespace)::itanium_demangle::NodeArray>(decltype(nullptr)&&, (anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PointerToMemberConversionExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node::Prec&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node::Prec&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnclosingExpr, char const (&) [10], (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec>(char const (&) [10], (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node::Prec&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ExprRequirement, (anonymous namespace)::itanium_demangle::Node*&, bool&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, bool&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TypeRequirement, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NestedRequirement, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::RequiresExpr, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SubobjectExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::NodeArray, bool&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::NodeArray&&, bool&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ParameterPackExpansion, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SizeofParamPackExpr, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnclosingExpr, char const (&) [11], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [11], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NodeArrayNode, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::InitListExpr, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [6]>(char const (&) [6])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ThrowExpr, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::QualifiedName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::DtorName, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ConversionOperatorType, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::LiteralOperator, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::GlobalQualifiedName, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnclosingExpr, char const (&) [9], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [9], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [4]>(char const (&) [4])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialSubstitution, (anonymous namespace)::itanium_demangle::SpecialSubKind&>((anonymous namespace)::itanium_demangle::SpecialSubKind&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::AbiTagAttr, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::StructuredBindingName, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ExpandedSpecialSubstitution, (anonymous namespace)::itanium_demangle::SpecialSubstitution*>((anonymous namespace)::itanium_demangle::SpecialSubstitution*&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::CtorDtorName, (anonymous namespace)::itanium_demangle::Node*&, bool, int&>((anonymous namespace)::itanium_demangle::Node*&, bool&&, int&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ModuleEntity, (anonymous namespace)::itanium_demangle::ModuleName*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::ModuleName*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::MemberLikeFriendName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NestedName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [15]>(char const (&) [15])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::LocalName, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ParameterPack, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateArgs, (anonymous namespace)::itanium_demangle::NodeArray, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::NodeArray&&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameWithTemplateArgs, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateArgumentPack, (anonymous namespace)::itanium_demangle::NodeArray&>((anonymous namespace)::itanium_demangle::NodeArray&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TemplateParamQualifiedArg, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::EnableIfAttr, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ExplicitObjectParameter, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FunctionEncoding, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Qualifiers&, (anonymous namespace)::itanium_demangle::FunctionRefQual&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Qualifiers&, (anonymous namespace)::itanium_demangle::FunctionRefQual&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::DotSuffix, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> > >((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::SpecialName, char const (&) [34], (anonymous namespace)::itanium_demangle::Node*&>(char const (&) [34], (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NoexceptSpec, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::DynamicExceptionSpec, (anonymous namespace)::itanium_demangle::NodeArray>((anonymous namespace)::itanium_demangle::NodeArray&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::FunctionType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Qualifiers&, (anonymous namespace)::itanium_demangle::FunctionRefQual&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::NodeArray&, (anonymous namespace)::itanium_demangle::Qualifiers&, (anonymous namespace)::itanium_demangle::FunctionRefQual&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ObjCProtoName, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::VendorExtQualType, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::QualType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Qualifiers&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Qualifiers&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [12]>(char const (&) [12])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [14]>(char const (&) [14])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [13]>(char const (&) [13])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [10]>(char const (&) [10])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [19]>(char const (&) [19])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [9]>(char const (&) [9])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [18]>(char const (&) [18])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [7]>(char const (&) [7])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::NameType, char const (&) [11]>(char const (&) [11])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::TransformedType, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BinaryFPType, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::BitIntType, (anonymous namespace)::itanium_demangle::Node*&, bool&>((anonymous namespace)::itanium_demangle::Node*&, bool&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PostfixQualifiedType, (anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&>((anonymous namespace)::itanium_demangle::Node*&, std::__1::basic_string_view<char, std::__1::char_traits<char> >&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PixelVectorType, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::VectorType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::VectorType, (anonymous namespace)::itanium_demangle::Node*&, decltype(nullptr)>((anonymous namespace)::itanium_demangle::Node*&, decltype(nullptr)&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ArrayType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PointerToMemberType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ElaboratedTypeSpefType, std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&>(std::__1::basic_string_view<char, std::__1::char_traits<char> >&, (anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PointerType, (anonymous namespace)::itanium_demangle::Node*&>((anonymous namespace)::itanium_demangle::Node*&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::ReferenceType, (anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::ReferenceKind>((anonymous namespace)::itanium_demangle::Node*&, (anonymous namespace)::itanium_demangle::ReferenceKind&&)
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PostfixQualifiedType, (anonymous namespace)::itanium_demangle::Node*&, char const (&) [9]>((anonymous namespace)::itanium_demangle::Node*&, char const (&) [9])
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::make<(anonymous namespace)::itanium_demangle::PostfixQualifiedType, (anonymous namespace)::itanium_demangle::Node*&, char const (&) [11]>((anonymous namespace)::itanium_demangle::Node*&, char const (&) [11])
2711
2712
0
  template <class It> NodeArray makeNodeArray(It begin, It end) {
2713
0
    size_t sz = static_cast<size_t>(end - begin);
2714
0
    void *mem = ASTAllocator.allocateNodeArray(sz);
2715
0
    Node **data = new (mem) Node *[sz];
2716
0
    std::copy(begin, end, data);
2717
0
    return NodeArray(data, sz);
2718
0
  }
2719
2720
0
  NodeArray popTrailingNodeArray(size_t FromPosition) {
2721
0
    DEMANGLE_ASSERT(FromPosition <= Names.size(), "");
2722
0
    NodeArray res =
2723
0
        makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
2724
0
    Names.shrinkToSize(FromPosition);
2725
0
    return res;
2726
0
  }
2727
2728
0
  bool consumeIf(std::string_view S) {
2729
0
    if (starts_with(std::string_view(First, Last - First), S)) {
2730
0
      First += S.size();
2731
0
      return true;
2732
0
    }
2733
0
    return false;
2734
0
  }
2735
2736
0
  bool consumeIf(char C) {
2737
0
    if (First != Last && *First == C) {
2738
0
      ++First;
2739
0
      return true;
2740
0
    }
2741
0
    return false;
2742
0
  }
2743
2744
0
  char consume() { return First != Last ? *First++ : '\0'; }
2745
2746
0
  char look(unsigned Lookahead = 0) const {
2747
0
    if (static_cast<size_t>(Last - First) <= Lookahead)
2748
0
      return '\0';
2749
0
    return First[Lookahead];
2750
0
  }
2751
2752
0
  size_t numLeft() const { return static_cast<size_t>(Last - First); }
2753
2754
  std::string_view parseNumber(bool AllowNegative = false);
2755
  Qualifiers parseCVQualifiers();
2756
  bool parsePositiveInteger(size_t *Out);
2757
  std::string_view parseBareSourceName();
2758
2759
  bool parseSeqId(size_t *Out);
2760
  Node *parseSubstitution();
2761
  Node *parseTemplateParam();
2762
  Node *parseTemplateParamDecl(TemplateParamList *Params);
2763
  Node *parseTemplateArgs(bool TagTemplates = false);
2764
  Node *parseTemplateArg();
2765
2766
0
  bool isTemplateParamDecl() {
2767
0
    return look() == 'T' &&
2768
0
           std::string_view("yptnk").find(look(1)) != std::string_view::npos;
2769
0
  }
2770
2771
  /// Parse the <expression> production.
2772
  Node *parseExpr();
2773
  Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
2774
  Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
2775
  Node *parseIntegerLiteral(std::string_view Lit);
2776
  Node *parseExprPrimary();
2777
  template <class Float> Node *parseFloatingLiteral();
2778
  Node *parseFunctionParam();
2779
  Node *parseConversionExpr();
2780
  Node *parseBracedExpr();
2781
  Node *parseFoldExpr();
2782
  Node *parsePointerToMemberConversionExpr(Node::Prec Prec);
2783
  Node *parseSubobjectExpr();
2784
  Node *parseConstraintExpr();
2785
  Node *parseRequiresExpr();
2786
2787
  /// Parse the <type> production.
2788
  Node *parseType();
2789
  Node *parseFunctionType();
2790
  Node *parseVectorType();
2791
  Node *parseDecltype();
2792
  Node *parseArrayType();
2793
  Node *parsePointerToMemberType();
2794
  Node *parseClassEnumType();
2795
  Node *parseQualifiedType();
2796
2797
  Node *parseEncoding(bool ParseParams = true);
2798
  bool parseCallOffset();
2799
  Node *parseSpecialName();
2800
2801
  /// Holds some extra information about a <name> that is being parsed. This
2802
  /// information is only pertinent if the <name> refers to an <encoding>.
2803
  struct NameState {
2804
    bool CtorDtorConversion = false;
2805
    bool EndsWithTemplateArgs = false;
2806
    Qualifiers CVQualifiers = QualNone;
2807
    FunctionRefQual ReferenceQualifier = FrefQualNone;
2808
    size_t ForwardTemplateRefsBegin;
2809
    bool HasExplicitObjectParameter = false;
2810
2811
    NameState(AbstractManglingParser *Enclosing)
2812
0
        : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2813
  };
2814
2815
0
  bool resolveForwardTemplateRefs(NameState &State) {
2816
0
    size_t I = State.ForwardTemplateRefsBegin;
2817
0
    size_t E = ForwardTemplateRefs.size();
2818
0
    for (; I < E; ++I) {
2819
0
      size_t Idx = ForwardTemplateRefs[I]->Index;
2820
0
      if (TemplateParams.empty() || !TemplateParams[0] ||
2821
0
          Idx >= TemplateParams[0]->size())
2822
0
        return true;
2823
0
      ForwardTemplateRefs[I]->Ref = (*TemplateParams[0])[Idx];
2824
0
    }
2825
0
    ForwardTemplateRefs.shrinkToSize(State.ForwardTemplateRefsBegin);
2826
0
    return false;
2827
0
  }
2828
2829
  /// Parse the <name> production>
2830
  Node *parseName(NameState *State = nullptr);
2831
  Node *parseLocalName(NameState *State);
2832
  Node *parseOperatorName(NameState *State);
2833
  bool parseModuleNameOpt(ModuleName *&Module);
2834
  Node *parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module);
2835
  Node *parseUnnamedTypeName(NameState *State);
2836
  Node *parseSourceName(NameState *State);
2837
  Node *parseUnscopedName(NameState *State, bool *isSubstName);
2838
  Node *parseNestedName(NameState *State);
2839
  Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2840
2841
  Node *parseAbiTags(Node *N);
2842
2843
  struct OperatorInfo {
2844
    enum OIKind : unsigned char {
2845
      Prefix,      // Prefix unary: @ expr
2846
      Postfix,     // Postfix unary: expr @
2847
      Binary,      // Binary: lhs @ rhs
2848
      Array,       // Array index:  lhs [ rhs ]
2849
      Member,      // Member access: lhs @ rhs
2850
      New,         // New
2851
      Del,         // Delete
2852
      Call,        // Function call: expr (expr*)
2853
      CCast,       // C cast: (type)expr
2854
      Conditional, // Conditional: expr ? expr : expr
2855
      NameOnly,    // Overload only, not allowed in expression.
2856
      // Below do not have operator names
2857
      NamedCast, // Named cast, @<type>(expr)
2858
      OfIdOp,    // alignof, sizeof, typeid
2859
2860
      Unnameable = NamedCast,
2861
    };
2862
    char Enc[2];      // Encoding
2863
    OIKind Kind;      // Kind of operator
2864
    bool Flag : 1;    // Entry-specific flag
2865
    Node::Prec Prec : 7; // Precedence
2866
    const char *Name; // Spelling
2867
2868
  public:
2869
    constexpr OperatorInfo(const char (&E)[3], OIKind K, bool F, Node::Prec P,
2870
                           const char *N)
2871
        : Enc{E[0], E[1]}, Kind{K}, Flag{F}, Prec{P}, Name{N} {}
2872
2873
  public:
2874
    bool operator<(const OperatorInfo &Other) const {
2875
      return *this < Other.Enc;
2876
    }
2877
0
    bool operator<(const char *Peek) const {
2878
0
      return Enc[0] < Peek[0] || (Enc[0] == Peek[0] && Enc[1] < Peek[1]);
2879
0
    }
2880
0
    bool operator==(const char *Peek) const {
2881
0
      return Enc[0] == Peek[0] && Enc[1] == Peek[1];
2882
0
    }
2883
0
    bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
2884
2885
  public:
2886
0
    std::string_view getSymbol() const {
2887
0
      std::string_view Res = Name;
2888
0
      if (Kind < Unnameable) {
2889
0
        DEMANGLE_ASSERT(starts_with(Res, "operator"),
2890
0
                        "operator name does not start with 'operator'");
2891
0
        Res.remove_prefix(sizeof("operator") - 1);
2892
0
        if (starts_with(Res, ' '))
2893
0
          Res.remove_prefix(1);
2894
0
      }
2895
0
      return Res;
2896
0
    }
2897
0
    std::string_view getName() const { return Name; }
2898
0
    OIKind getKind() const { return Kind; }
2899
0
    bool getFlag() const { return Flag; }
2900
0
    Node::Prec getPrecedence() const { return Prec; }
2901
  };
2902
  static const OperatorInfo Ops[];
2903
  static const size_t NumOps;
2904
  const OperatorInfo *parseOperatorEncoding();
2905
2906
  /// Parse the <unresolved-name> production.
2907
  Node *parseUnresolvedName(bool Global);
2908
  Node *parseSimpleId();
2909
  Node *parseBaseUnresolvedName();
2910
  Node *parseUnresolvedType();
2911
  Node *parseDestructorName();
2912
2913
  /// Top-level entry point into the parser.
2914
  Node *parse(bool ParseParams = true);
2915
};
2916
2917
const char* parse_discriminator(const char* first, const char* last);
2918
2919
// <name> ::= <nested-name> // N
2920
//        ::= <local-name> # See Scope Encoding below  // Z
2921
//        ::= <unscoped-template-name> <template-args>
2922
//        ::= <unscoped-name>
2923
//
2924
// <unscoped-template-name> ::= <unscoped-name>
2925
//                          ::= <substitution>
2926
template <typename Derived, typename Alloc>
2927
0
Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) {
2928
0
  if (look() == 'N')
2929
0
    return getDerived().parseNestedName(State);
2930
0
  if (look() == 'Z')
2931
0
    return getDerived().parseLocalName(State);
2932
2933
0
  Node *Result = nullptr;
2934
0
  bool IsSubst = false;
2935
2936
0
  Result = getDerived().parseUnscopedName(State, &IsSubst);
2937
0
  if (!Result)
2938
0
    return nullptr;
2939
2940
0
  if (look() == 'I') {
2941
    //        ::= <unscoped-template-name> <template-args>
2942
0
    if (!IsSubst)
2943
      // An unscoped-template-name is substitutable.
2944
0
      Subs.push_back(Result);
2945
0
    Node *TA = getDerived().parseTemplateArgs(State != nullptr);
2946
0
    if (TA == nullptr)
2947
0
      return nullptr;
2948
0
    if (State)
2949
0
      State->EndsWithTemplateArgs = true;
2950
0
    Result = make<NameWithTemplateArgs>(Result, TA);
2951
0
  } else if (IsSubst) {
2952
    // The substitution case must be followed by <template-args>.
2953
0
    return nullptr;
2954
0
  }
2955
2956
0
  return Result;
2957
0
}
2958
2959
// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
2960
//              := Z <function encoding> E s [<discriminator>]
2961
//              := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
2962
template <typename Derived, typename Alloc>
2963
0
Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
2964
0
  if (!consumeIf('Z'))
2965
0
    return nullptr;
2966
0
  Node *Encoding = getDerived().parseEncoding();
2967
0
  if (Encoding == nullptr || !consumeIf('E'))
2968
0
    return nullptr;
2969
2970
0
  if (consumeIf('s')) {
2971
0
    First = parse_discriminator(First, Last);
2972
0
    auto *StringLitName = make<NameType>("string literal");
2973
0
    if (!StringLitName)
2974
0
      return nullptr;
2975
0
    return make<LocalName>(Encoding, StringLitName);
2976
0
  }
2977
2978
  // The template parameters of the inner name are unrelated to those of the
2979
  // enclosing context.
2980
0
  SaveTemplateParams SaveTemplateParamsScope(this);
2981
2982
0
  if (consumeIf('d')) {
2983
0
    parseNumber(true);
2984
0
    if (!consumeIf('_'))
2985
0
      return nullptr;
2986
0
    Node *N = getDerived().parseName(State);
2987
0
    if (N == nullptr)
2988
0
      return nullptr;
2989
0
    return make<LocalName>(Encoding, N);
2990
0
  }
2991
2992
0
  Node *Entity = getDerived().parseName(State);
2993
0
  if (Entity == nullptr)
2994
0
    return nullptr;
2995
0
  First = parse_discriminator(First, Last);
2996
0
  return make<LocalName>(Encoding, Entity);
2997
0
}
2998
2999
// <unscoped-name> ::= <unqualified-name>
3000
//                 ::= St <unqualified-name>   # ::std::
3001
// [*] extension
3002
template <typename Derived, typename Alloc>
3003
Node *
3004
AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
3005
0
                                                          bool *IsSubst) {
3006
3007
0
  Node *Std = nullptr;
3008
0
  if (consumeIf("St")) {
3009
0
    Std = make<NameType>("std");
3010
0
    if (Std == nullptr)
3011
0
      return nullptr;
3012
0
  }
3013
3014
0
  Node *Res = nullptr;
3015
0
  ModuleName *Module = nullptr;
3016
0
  if (look() == 'S') {
3017
0
    Node *S = getDerived().parseSubstitution();
3018
0
    if (!S)
3019
0
      return nullptr;
3020
0
    if (S->getKind() == Node::KModuleName)
3021
0
      Module = static_cast<ModuleName *>(S);
3022
0
    else if (IsSubst && Std == nullptr) {
3023
0
      Res = S;
3024
0
      *IsSubst = true;
3025
0
    } else {
3026
0
      return nullptr;
3027
0
    }
3028
0
  }
3029
3030
0
  if (Res == nullptr || Std != nullptr) {
3031
0
    Res = getDerived().parseUnqualifiedName(State, Std, Module);
3032
0
  }
3033
3034
0
  return Res;
3035
0
}
3036
3037
// <unqualified-name> ::= [<module-name>] F? L? <operator-name> [<abi-tags>]
3038
//                    ::= [<module-name>] <ctor-dtor-name> [<abi-tags>]
3039
//                    ::= [<module-name>] F? L? <source-name> [<abi-tags>]
3040
//                    ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>]
3041
//      # structured binding declaration
3042
//                    ::= [<module-name>] L? DC <source-name>+ E
3043
template <typename Derived, typename Alloc>
3044
Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
3045
0
    NameState *State, Node *Scope, ModuleName *Module) {
3046
0
  if (getDerived().parseModuleNameOpt(Module))
3047
0
    return nullptr;
3048
3049
0
  bool IsMemberLikeFriend = Scope && consumeIf('F');
3050
3051
0
  consumeIf('L');
3052
3053
0
  Node *Result;
3054
0
  if (look() >= '1' && look() <= '9') {
3055
0
    Result = getDerived().parseSourceName(State);
3056
0
  } else if (look() == 'U') {
3057
0
    Result = getDerived().parseUnnamedTypeName(State);
3058
0
  } else if (consumeIf("DC")) {
3059
    // Structured binding
3060
0
    size_t BindingsBegin = Names.size();
3061
0
    do {
3062
0
      Node *Binding = getDerived().parseSourceName(State);
3063
0
      if (Binding == nullptr)
3064
0
        return nullptr;
3065
0
      Names.push_back(Binding);
3066
0
    } while (!consumeIf('E'));
3067
0
    Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
3068
0
  } else if (look() == 'C' || look() == 'D') {
3069
    // A <ctor-dtor-name>.
3070
0
    if (Scope == nullptr || Module != nullptr)
3071
0
      return nullptr;
3072
0
    Result = getDerived().parseCtorDtorName(Scope, State);
3073
0
  } else {
3074
0
    Result = getDerived().parseOperatorName(State);
3075
0
  }
3076
3077
0
  if (Result != nullptr && Module != nullptr)
3078
0
    Result = make<ModuleEntity>(Module, Result);
3079
0
  if (Result != nullptr)
3080
0
    Result = getDerived().parseAbiTags(Result);
3081
0
  if (Result != nullptr && IsMemberLikeFriend)
3082
0
    Result = make<MemberLikeFriendName>(Scope, Result);
3083
0
  else if (Result != nullptr && Scope != nullptr)
3084
0
    Result = make<NestedName>(Scope, Result);
3085
3086
0
  return Result;
3087
0
}
3088
3089
// <module-name> ::= <module-subname>
3090
//     ::= <module-name> <module-subname>
3091
//     ::= <substitution>  # passed in by caller
3092
// <module-subname> ::= W <source-name>
3093
//        ::= W P <source-name>
3094
template <typename Derived, typename Alloc>
3095
bool AbstractManglingParser<Derived, Alloc>::parseModuleNameOpt(
3096
0
    ModuleName *&Module) {
3097
0
  while (consumeIf('W')) {
3098
0
    bool IsPartition = consumeIf('P');
3099
0
    Node *Sub = getDerived().parseSourceName(nullptr);
3100
0
    if (!Sub)
3101
0
      return true;
3102
0
    Module =
3103
0
        static_cast<ModuleName *>(make<ModuleName>(Module, Sub, IsPartition));
3104
0
    Subs.push_back(Module);
3105
0
  }
3106
3107
0
  return false;
3108
0
}
3109
3110
// <unnamed-type-name> ::= Ut [<nonnegative number>] _
3111
//                     ::= <closure-type-name>
3112
//
3113
// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
3114
//
3115
// <lambda-sig> ::= <template-param-decl>* [Q <requires-clause expression>]
3116
//                  <parameter type>+  # or "v" if the lambda has no parameters
3117
template <typename Derived, typename Alloc>
3118
Node *
3119
0
AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
3120
  // <template-params> refer to the innermost <template-args>. Clear out any
3121
  // outer args that we may have inserted into TemplateParams.
3122
0
  if (State != nullptr)
3123
0
    TemplateParams.clear();
3124
3125
0
  if (consumeIf("Ut")) {
3126
0
    std::string_view Count = parseNumber();
3127
0
    if (!consumeIf('_'))
3128
0
      return nullptr;
3129
0
    return make<UnnamedTypeName>(Count);
3130
0
  }
3131
0
  if (consumeIf("Ul")) {
3132
0
    ScopedOverride<size_t> SwapParams(ParsingLambdaParamsAtLevel,
3133
0
                                      TemplateParams.size());
3134
0
    ScopedTemplateParamList LambdaTemplateParams(this);
3135
3136
0
    size_t ParamsBegin = Names.size();
3137
0
    while (getDerived().isTemplateParamDecl()) {
3138
0
      Node *T =
3139
0
          getDerived().parseTemplateParamDecl(LambdaTemplateParams.params());
3140
0
      if (T == nullptr)
3141
0
        return nullptr;
3142
0
      Names.push_back(T);
3143
0
    }
3144
0
    NodeArray TempParams = popTrailingNodeArray(ParamsBegin);
3145
3146
    // FIXME: If TempParams is empty and none of the function parameters
3147
    // includes 'auto', we should remove LambdaTemplateParams from the
3148
    // TemplateParams list. Unfortunately, we don't find out whether there are
3149
    // any 'auto' parameters until too late in an example such as:
3150
    //
3151
    //   template<typename T> void f(
3152
    //       decltype([](decltype([]<typename T>(T v) {}),
3153
    //                   auto) {})) {}
3154
    //   template<typename T> void f(
3155
    //       decltype([](decltype([]<typename T>(T w) {}),
3156
    //                   int) {})) {}
3157
    //
3158
    // Here, the type of v is at level 2 but the type of w is at level 1. We
3159
    // don't find this out until we encounter the type of the next parameter.
3160
    //
3161
    // However, compilers can't actually cope with the former example in
3162
    // practice, and it's likely to be made ill-formed in future, so we don't
3163
    // need to support it here.
3164
    //
3165
    // If we encounter an 'auto' in the function parameter types, we will
3166
    // recreate a template parameter scope for it, but any intervening lambdas
3167
    // will be parsed in the 'wrong' template parameter depth.
3168
0
    if (TempParams.empty())
3169
0
      TemplateParams.pop_back();
3170
3171
0
    Node *Requires1 = nullptr;
3172
0
    if (consumeIf('Q')) {
3173
0
      Requires1 = getDerived().parseConstraintExpr();
3174
0
      if (Requires1 == nullptr)
3175
0
        return nullptr;
3176
0
    }
3177
3178
0
    if (!consumeIf("v")) {
3179
0
      do {
3180
0
        Node *P = getDerived().parseType();
3181
0
        if (P == nullptr)
3182
0
          return nullptr;
3183
0
        Names.push_back(P);
3184
0
      } while (look() != 'E' && look() != 'Q');
3185
0
    }
3186
0
    NodeArray Params = popTrailingNodeArray(ParamsBegin);
3187
3188
0
    Node *Requires2 = nullptr;
3189
0
    if (consumeIf('Q')) {
3190
0
      Requires2 = getDerived().parseConstraintExpr();
3191
0
      if (Requires2 == nullptr)
3192
0
        return nullptr;
3193
0
    }
3194
3195
0
    if (!consumeIf('E'))
3196
0
      return nullptr;
3197
3198
0
    std::string_view Count = parseNumber();
3199
0
    if (!consumeIf('_'))
3200
0
      return nullptr;
3201
0
    return make<ClosureTypeName>(TempParams, Requires1, Params, Requires2,
3202
0
                                 Count);
3203
0
  }
3204
0
  if (consumeIf("Ub")) {
3205
0
    (void)parseNumber();
3206
0
    if (!consumeIf('_'))
3207
0
      return nullptr;
3208
0
    return make<NameType>("'block-literal'");
3209
0
  }
3210
0
  return nullptr;
3211
0
}
3212
3213
// <source-name> ::= <positive length number> <identifier>
3214
template <typename Derived, typename Alloc>
3215
0
Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
3216
0
  size_t Length = 0;
3217
0
  if (parsePositiveInteger(&Length))
3218
0
    return nullptr;
3219
0
  if (numLeft() < Length || Length == 0)
3220
0
    return nullptr;
3221
0
  std::string_view Name(First, Length);
3222
0
  First += Length;
3223
0
  if (starts_with(Name, "_GLOBAL__N"))
3224
0
    return make<NameType>("(anonymous namespace)");
3225
0
  return make<NameType>(Name);
3226
0
}
3227
3228
// Operator encodings
3229
template <typename Derived, typename Alloc>
3230
const typename AbstractManglingParser<
3231
    Derived, Alloc>::OperatorInfo AbstractManglingParser<Derived,
3232
                                                         Alloc>::Ops[] = {
3233
    // Keep ordered by encoding
3234
    {"aN", OperatorInfo::Binary, false, Node::Prec::Assign, "operator&="},
3235
    {"aS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator="},
3236
    {"aa", OperatorInfo::Binary, false, Node::Prec::AndIf, "operator&&"},
3237
    {"ad", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator&"},
3238
    {"an", OperatorInfo::Binary, false, Node::Prec::And, "operator&"},
3239
    {"at", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "alignof "},
3240
    {"aw", OperatorInfo::NameOnly, false, Node::Prec::Primary,
3241
     "operator co_await"},
3242
    {"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
3243
    {"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
3244
    {"cl", OperatorInfo::Call, false, Node::Prec::Postfix, "operator()"},
3245
    {"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
3246
    {"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
3247
    {"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
3248
    {"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
3249
    {"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
3250
     "operator delete[]"},
3251
    {"dc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "dynamic_cast"},
3252
    {"de", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator*"},
3253
    {"dl", OperatorInfo::Del, /*Ary*/ false, Node::Prec::Unary,
3254
     "operator delete"},
3255
    {"ds", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3256
     "operator.*"},
3257
    {"dt", OperatorInfo::Member, /*Named*/ false, Node::Prec::Postfix,
3258
     "operator."},
3259
    {"dv", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/"},
3260
    {"eO", OperatorInfo::Binary, false, Node::Prec::Assign, "operator^="},
3261
    {"eo", OperatorInfo::Binary, false, Node::Prec::Xor, "operator^"},
3262
    {"eq", OperatorInfo::Binary, false, Node::Prec::Equality, "operator=="},
3263
    {"ge", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>="},
3264
    {"gt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>"},
3265
    {"ix", OperatorInfo::Array, false, Node::Prec::Postfix, "operator[]"},
3266
    {"lS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator<<="},
3267
    {"le", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<="},
3268
    {"ls", OperatorInfo::Binary, false, Node::Prec::Shift, "operator<<"},
3269
    {"lt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<"},
3270
    {"mI", OperatorInfo::Binary, false, Node::Prec::Assign, "operator-="},
3271
    {"mL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator*="},
3272
    {"mi", OperatorInfo::Binary, false, Node::Prec::Additive, "operator-"},
3273
    {"ml", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3274
     "operator*"},
3275
    {"mm", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator--"},
3276
    {"na", OperatorInfo::New, /*Ary*/ true, Node::Prec::Unary,
3277
     "operator new[]"},
3278
    {"ne", OperatorInfo::Binary, false, Node::Prec::Equality, "operator!="},
3279
    {"ng", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator-"},
3280
    {"nt", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator!"},
3281
    {"nw", OperatorInfo::New, /*Ary*/ false, Node::Prec::Unary, "operator new"},
3282
    {"oR", OperatorInfo::Binary, false, Node::Prec::Assign, "operator|="},
3283
    {"oo", OperatorInfo::Binary, false, Node::Prec::OrIf, "operator||"},
3284
    {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"},
3285
    {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="},
3286
    {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"},
3287
    {"pm", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3288
     "operator->*"},
3289
    {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"},
3290
    {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"},
3291
    {"pt", OperatorInfo::Member, /*Named*/ true, Node::Prec::Postfix,
3292
     "operator->"},
3293
    {"qu", OperatorInfo::Conditional, false, Node::Prec::Conditional,
3294
     "operator?"},
3295
    {"rM", OperatorInfo::Binary, false, Node::Prec::Assign, "operator%="},
3296
    {"rS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator>>="},
3297
    {"rc", OperatorInfo::NamedCast, false, Node::Prec::Postfix,
3298
     "reinterpret_cast"},
3299
    {"rm", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3300
     "operator%"},
3301
    {"rs", OperatorInfo::Binary, false, Node::Prec::Shift, "operator>>"},
3302
    {"sc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "static_cast"},
3303
    {"ss", OperatorInfo::Binary, false, Node::Prec::Spaceship, "operator<=>"},
3304
    {"st", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "sizeof "},
3305
    {"sz", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "sizeof "},
3306
    {"te", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Postfix,
3307
     "typeid "},
3308
    {"ti", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Postfix, "typeid "},
3309
};
3310
template <typename Derived, typename Alloc>
3311
const size_t AbstractManglingParser<Derived, Alloc>::NumOps = sizeof(Ops) /
3312
                                                              sizeof(Ops[0]);
3313
3314
// If the next 2 chars are an operator encoding, consume them and return their
3315
// OperatorInfo.  Otherwise return nullptr.
3316
template <typename Derived, typename Alloc>
3317
const typename AbstractManglingParser<Derived, Alloc>::OperatorInfo *
3318
0
AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
3319
0
  if (numLeft() < 2)
3320
0
    return nullptr;
3321
3322
  // We can't use lower_bound as that can link to symbols in the C++ library,
3323
  // and this must remain independant of that.
3324
0
  size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
3325
0
  while (upper != lower) {
3326
0
    size_t middle = (upper + lower) / 2;
3327
0
    if (Ops[middle] < First)
3328
0
      lower = middle + 1;
3329
0
    else
3330
0
      upper = middle;
3331
0
  }
3332
0
  if (Ops[lower] != First)
3333
0
    return nullptr;
3334
3335
0
  First += 2;
3336
0
  return &Ops[lower];
3337
0
}
3338
3339
//   <operator-name> ::= See parseOperatorEncoding()
3340
//                   ::= li <source-name>  # operator ""
3341
//                   ::= v <digit> <source-name>  # vendor extended operator
3342
template <typename Derived, typename Alloc>
3343
Node *
3344
0
AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
3345
0
  if (const auto *Op = parseOperatorEncoding()) {
3346
0
    if (Op->getKind() == OperatorInfo::CCast) {
3347
      //              ::= cv <type>    # (cast)
3348
0
      ScopedOverride<bool> SaveTemplate(TryToParseTemplateArgs, false);
3349
      // If we're parsing an encoding, State != nullptr and the conversion
3350
      // operators' <type> could have a <template-param> that refers to some
3351
      // <template-arg>s further ahead in the mangled name.
3352
0
      ScopedOverride<bool> SavePermit(PermitForwardTemplateReferences,
3353
0
                                      PermitForwardTemplateReferences ||
3354
0
                                          State != nullptr);
3355
0
      Node *Ty = getDerived().parseType();
3356
0
      if (Ty == nullptr)
3357
0
        return nullptr;
3358
0
      if (State) State->CtorDtorConversion = true;
3359
0
      return make<ConversionOperatorType>(Ty);
3360
0
    }
3361
3362
0
    if (Op->getKind() >= OperatorInfo::Unnameable)
3363
      /* Not a nameable operator.  */
3364
0
      return nullptr;
3365
0
    if (Op->getKind() == OperatorInfo::Member && !Op->getFlag())
3366
      /* Not a nameable MemberExpr */
3367
0
      return nullptr;
3368
3369
0
    return make<NameType>(Op->getName());
3370
0
  }
3371
3372
0
  if (consumeIf("li")) {
3373
    //                   ::= li <source-name>  # operator ""
3374
0
    Node *SN = getDerived().parseSourceName(State);
3375
0
    if (SN == nullptr)
3376
0
      return nullptr;
3377
0
    return make<LiteralOperator>(SN);
3378
0
  }
3379
3380
0
  if (consumeIf('v')) {
3381
    // ::= v <digit> <source-name>        # vendor extended operator
3382
0
    if (look() >= '0' && look() <= '9') {
3383
0
      First++;
3384
0
      Node *SN = getDerived().parseSourceName(State);
3385
0
      if (SN == nullptr)
3386
0
        return nullptr;
3387
0
      return make<ConversionOperatorType>(SN);
3388
0
    }
3389
0
    return nullptr;
3390
0
  }
3391
3392
0
  return nullptr;
3393
0
}
3394
3395
// <ctor-dtor-name> ::= C1  # complete object constructor
3396
//                  ::= C2  # base object constructor
3397
//                  ::= C3  # complete object allocating constructor
3398
//   extension      ::= C4  # gcc old-style "[unified]" constructor
3399
//   extension      ::= C5  # the COMDAT used for ctors
3400
//                  ::= D0  # deleting destructor
3401
//                  ::= D1  # complete object destructor
3402
//                  ::= D2  # base object destructor
3403
//   extension      ::= D4  # gcc old-style "[unified]" destructor
3404
//   extension      ::= D5  # the COMDAT used for dtors
3405
template <typename Derived, typename Alloc>
3406
Node *
3407
AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3408
0
                                                          NameState *State) {
3409
0
  if (SoFar->getKind() == Node::KSpecialSubstitution) {
3410
    // Expand the special substitution.
3411
0
    SoFar = make<ExpandedSpecialSubstitution>(
3412
0
        static_cast<SpecialSubstitution *>(SoFar));
3413
0
    if (!SoFar)
3414
0
      return nullptr;
3415
0
  }
3416
3417
0
  if (consumeIf('C')) {
3418
0
    bool IsInherited = consumeIf('I');
3419
0
    if (look() != '1' && look() != '2' && look() != '3' && look() != '4' &&
3420
0
        look() != '5')
3421
0
      return nullptr;
3422
0
    int Variant = look() - '0';
3423
0
    ++First;
3424
0
    if (State) State->CtorDtorConversion = true;
3425
0
    if (IsInherited) {
3426
0
      if (getDerived().parseName(State) == nullptr)
3427
0
        return nullptr;
3428
0
    }
3429
0
    return make<CtorDtorName>(SoFar, /*IsDtor=*/false, Variant);
3430
0
  }
3431
3432
0
  if (look() == 'D' && (look(1) == '0' || look(1) == '1' || look(1) == '2' ||
3433
0
                        look(1) == '4' || look(1) == '5')) {
3434
0
    int Variant = look(1) - '0';
3435
0
    First += 2;
3436
0
    if (State) State->CtorDtorConversion = true;
3437
0
    return make<CtorDtorName>(SoFar, /*IsDtor=*/true, Variant);
3438
0
  }
3439
3440
0
  return nullptr;
3441
0
}
3442
3443
// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix>
3444
//      <unqualified-name> E
3445
//               ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix>
3446
//                <template-args> E
3447
//
3448
// <prefix> ::= <prefix> <unqualified-name>
3449
//          ::= <template-prefix> <template-args>
3450
//          ::= <template-param>
3451
//          ::= <decltype>
3452
//          ::= # empty
3453
//          ::= <substitution>
3454
//          ::= <prefix> <data-member-prefix>
3455
// [*] extension
3456
//
3457
// <data-member-prefix> := <member source-name> [<template-args>] M
3458
//
3459
// <template-prefix> ::= <prefix> <template unqualified-name>
3460
//                   ::= <template-param>
3461
//                   ::= <substitution>
3462
template <typename Derived, typename Alloc>
3463
Node *
3464
0
AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
3465
0
  if (!consumeIf('N'))
3466
0
    return nullptr;
3467
3468
  // 'H' specifies that the encoding that follows
3469
  // has an explicit object parameter.
3470
0
  if (!consumeIf('H')) {
3471
0
    Qualifiers CVTmp = parseCVQualifiers();
3472
0
    if (State)
3473
0
      State->CVQualifiers = CVTmp;
3474
3475
0
    if (consumeIf('O')) {
3476
0
      if (State)
3477
0
        State->ReferenceQualifier = FrefQualRValue;
3478
0
    } else if (consumeIf('R')) {
3479
0
      if (State)
3480
0
        State->ReferenceQualifier = FrefQualLValue;
3481
0
    } else {
3482
0
      if (State)
3483
0
        State->ReferenceQualifier = FrefQualNone;
3484
0
    }
3485
0
  } else if (State) {
3486
0
    State->HasExplicitObjectParameter = true;
3487
0
  }
3488
3489
0
  Node *SoFar = nullptr;
3490
0
  while (!consumeIf('E')) {
3491
0
    if (State)
3492
      // Only set end-with-template on the case that does that.
3493
0
      State->EndsWithTemplateArgs = false;
3494
3495
0
    if (look() == 'T') {
3496
      //          ::= <template-param>
3497
0
      if (SoFar != nullptr)
3498
0
        return nullptr; // Cannot have a prefix.
3499
0
      SoFar = getDerived().parseTemplateParam();
3500
0
    } else if (look() == 'I') {
3501
      //          ::= <template-prefix> <template-args>
3502
0
      if (SoFar == nullptr)
3503
0
        return nullptr; // Must have a prefix.
3504
0
      Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3505
0
      if (TA == nullptr)
3506
0
        return nullptr;
3507
0
      if (SoFar->getKind() == Node::KNameWithTemplateArgs)
3508
        // Semantically <template-args> <template-args> cannot be generated by a
3509
        // C++ entity.  There will always be [something like] a name between
3510
        // them.
3511
0
        return nullptr;
3512
0
      if (State)
3513
0
        State->EndsWithTemplateArgs = true;
3514
0
      SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3515
0
    } else if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
3516
      //          ::= <decltype>
3517
0
      if (SoFar != nullptr)
3518
0
        return nullptr; // Cannot have a prefix.
3519
0
      SoFar = getDerived().parseDecltype();
3520
0
    } else {
3521
0
      ModuleName *Module = nullptr;
3522
3523
0
      if (look() == 'S') {
3524
        //          ::= <substitution>
3525
0
        Node *S = nullptr;
3526
0
        if (look(1) == 't') {
3527
0
          First += 2;
3528
0
          S = make<NameType>("std");
3529
0
        } else {
3530
0
          S = getDerived().parseSubstitution();
3531
0
        }
3532
0
        if (!S)
3533
0
          return nullptr;
3534
0
        if (S->getKind() == Node::KModuleName) {
3535
0
          Module = static_cast<ModuleName *>(S);
3536
0
        } else if (SoFar != nullptr) {
3537
0
          return nullptr; // Cannot have a prefix.
3538
0
        } else {
3539
0
          SoFar = S;
3540
0
          continue; // Do not push a new substitution.
3541
0
        }
3542
0
      }
3543
3544
      //          ::= [<prefix>] <unqualified-name>
3545
0
      SoFar = getDerived().parseUnqualifiedName(State, SoFar, Module);
3546
0
    }
3547
3548
0
    if (SoFar == nullptr)
3549
0
      return nullptr;
3550
0
    Subs.push_back(SoFar);
3551
3552
    // No longer used.
3553
    // <data-member-prefix> := <member source-name> [<template-args>] M
3554
0
    consumeIf('M');
3555
0
  }
3556
3557
0
  if (SoFar == nullptr || Subs.empty())
3558
0
    return nullptr;
3559
3560
0
  Subs.pop_back();
3561
0
  return SoFar;
3562
0
}
3563
3564
// <simple-id> ::= <source-name> [ <template-args> ]
3565
template <typename Derived, typename Alloc>
3566
0
Node *AbstractManglingParser<Derived, Alloc>::parseSimpleId() {
3567
0
  Node *SN = getDerived().parseSourceName(/*NameState=*/nullptr);
3568
0
  if (SN == nullptr)
3569
0
    return nullptr;
3570
0
  if (look() == 'I') {
3571
0
    Node *TA = getDerived().parseTemplateArgs();
3572
0
    if (TA == nullptr)
3573
0
      return nullptr;
3574
0
    return make<NameWithTemplateArgs>(SN, TA);
3575
0
  }
3576
0
  return SN;
3577
0
}
3578
3579
// <destructor-name> ::= <unresolved-type>  # e.g., ~T or ~decltype(f())
3580
//                   ::= <simple-id>        # e.g., ~A<2*N>
3581
template <typename Derived, typename Alloc>
3582
0
Node *AbstractManglingParser<Derived, Alloc>::parseDestructorName() {
3583
0
  Node *Result;
3584
0
  if (std::isdigit(look()))
3585
0
    Result = getDerived().parseSimpleId();
3586
0
  else
3587
0
    Result = getDerived().parseUnresolvedType();
3588
0
  if (Result == nullptr)
3589
0
    return nullptr;
3590
0
  return make<DtorName>(Result);
3591
0
}
3592
3593
// <unresolved-type> ::= <template-param>
3594
//                   ::= <decltype>
3595
//                   ::= <substitution>
3596
template <typename Derived, typename Alloc>
3597
0
Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedType() {
3598
0
  if (look() == 'T') {
3599
0
    Node *TP = getDerived().parseTemplateParam();
3600
0
    if (TP == nullptr)
3601
0
      return nullptr;
3602
0
    Subs.push_back(TP);
3603
0
    return TP;
3604
0
  }
3605
0
  if (look() == 'D') {
3606
0
    Node *DT = getDerived().parseDecltype();
3607
0
    if (DT == nullptr)
3608
0
      return nullptr;
3609
0
    Subs.push_back(DT);
3610
0
    return DT;
3611
0
  }
3612
0
  return getDerived().parseSubstitution();
3613
0
}
3614
3615
// <base-unresolved-name> ::= <simple-id>                                # unresolved name
3616
//          extension     ::= <operator-name>                            # unresolved operator-function-id
3617
//          extension     ::= <operator-name> <template-args>            # unresolved operator template-id
3618
//                        ::= on <operator-name>                         # unresolved operator-function-id
3619
//                        ::= on <operator-name> <template-args>         # unresolved operator template-id
3620
//                        ::= dn <destructor-name>                       # destructor or pseudo-destructor;
3621
//                                                                         # e.g. ~X or ~X<N-1>
3622
template <typename Derived, typename Alloc>
3623
0
Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3624
0
  if (std::isdigit(look()))
3625
0
    return getDerived().parseSimpleId();
3626
3627
0
  if (consumeIf("dn"))
3628
0
    return getDerived().parseDestructorName();
3629
3630
0
  consumeIf("on");
3631
3632
0
  Node *Oper = getDerived().parseOperatorName(/*NameState=*/nullptr);
3633
0
  if (Oper == nullptr)
3634
0
    return nullptr;
3635
0
  if (look() == 'I') {
3636
0
    Node *TA = getDerived().parseTemplateArgs();
3637
0
    if (TA == nullptr)
3638
0
      return nullptr;
3639
0
    return make<NameWithTemplateArgs>(Oper, TA);
3640
0
  }
3641
0
  return Oper;
3642
0
}
3643
3644
// <unresolved-name>
3645
//  extension        ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3646
//                   ::= [gs] <base-unresolved-name>                     # x or (with "gs") ::x
3647
//                   ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3648
//                                                                       # A::x, N::y, A<T>::z; "gs" means leading "::"
3649
// [gs] has been parsed by caller.
3650
//                   ::= sr <unresolved-type> <base-unresolved-name>     # T::x / decltype(p)::x
3651
//  extension        ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3652
//                                                                       # T::N::x /decltype(p)::N::x
3653
//  (ignored)        ::= srN <unresolved-type>  <unresolved-qualifier-level>+ E <base-unresolved-name>
3654
//
3655
// <unresolved-qualifier-level> ::= <simple-id>
3656
template <typename Derived, typename Alloc>
3657
0
Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
3658
0
  Node *SoFar = nullptr;
3659
3660
  // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
3661
  // srN <unresolved-type>                   <unresolved-qualifier-level>+ E <base-unresolved-name>
3662
0
  if (consumeIf("srN")) {
3663
0
    SoFar = getDerived().parseUnresolvedType();
3664
0
    if (SoFar == nullptr)
3665
0
      return nullptr;
3666
3667
0
    if (look() == 'I') {
3668
0
      Node *TA = getDerived().parseTemplateArgs();
3669
0
      if (TA == nullptr)
3670
0
        return nullptr;
3671
0
      SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3672
0
      if (!SoFar)
3673
0
        return nullptr;
3674
0
    }
3675
3676
0
    while (!consumeIf('E')) {
3677
0
      Node *Qual = getDerived().parseSimpleId();
3678
0
      if (Qual == nullptr)
3679
0
        return nullptr;
3680
0
      SoFar = make<QualifiedName>(SoFar, Qual);
3681
0
      if (!SoFar)
3682
0
        return nullptr;
3683
0
    }
3684
3685
0
    Node *Base = getDerived().parseBaseUnresolvedName();
3686
0
    if (Base == nullptr)
3687
0
      return nullptr;
3688
0
    return make<QualifiedName>(SoFar, Base);
3689
0
  }
3690
3691
  // [gs] <base-unresolved-name>                     # x or (with "gs") ::x
3692
0
  if (!consumeIf("sr")) {
3693
0
    SoFar = getDerived().parseBaseUnresolvedName();
3694
0
    if (SoFar == nullptr)
3695
0
      return nullptr;
3696
0
    if (Global)
3697
0
      SoFar = make<GlobalQualifiedName>(SoFar);
3698
0
    return SoFar;
3699
0
  }
3700
3701
  // [gs] sr <unresolved-qualifier-level>+ E   <base-unresolved-name>
3702
0
  if (std::isdigit(look())) {
3703
0
    do {
3704
0
      Node *Qual = getDerived().parseSimpleId();
3705
0
      if (Qual == nullptr)
3706
0
        return nullptr;
3707
0
      if (SoFar)
3708
0
        SoFar = make<QualifiedName>(SoFar, Qual);
3709
0
      else if (Global)
3710
0
        SoFar = make<GlobalQualifiedName>(Qual);
3711
0
      else
3712
0
        SoFar = Qual;
3713
0
      if (!SoFar)
3714
0
        return nullptr;
3715
0
    } while (!consumeIf('E'));
3716
0
  }
3717
  //      sr <unresolved-type>                 <base-unresolved-name>
3718
  //      sr <unresolved-type> <template-args> <base-unresolved-name>
3719
0
  else {
3720
0
    SoFar = getDerived().parseUnresolvedType();
3721
0
    if (SoFar == nullptr)
3722
0
      return nullptr;
3723
3724
0
    if (look() == 'I') {
3725
0
      Node *TA = getDerived().parseTemplateArgs();
3726
0
      if (TA == nullptr)
3727
0
        return nullptr;
3728
0
      SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3729
0
      if (!SoFar)
3730
0
        return nullptr;
3731
0
    }
3732
0
  }
3733
3734
0
  DEMANGLE_ASSERT(SoFar != nullptr, "");
3735
3736
0
  Node *Base = getDerived().parseBaseUnresolvedName();
3737
0
  if (Base == nullptr)
3738
0
    return nullptr;
3739
0
  return make<QualifiedName>(SoFar, Base);
3740
0
}
3741
3742
// <abi-tags> ::= <abi-tag> [<abi-tags>]
3743
// <abi-tag> ::= B <source-name>
3744
template <typename Derived, typename Alloc>
3745
0
Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3746
0
  while (consumeIf('B')) {
3747
0
    std::string_view SN = parseBareSourceName();
3748
0
    if (SN.empty())
3749
0
      return nullptr;
3750
0
    N = make<AbiTagAttr>(N, SN);
3751
0
    if (!N)
3752
0
      return nullptr;
3753
0
  }
3754
0
  return N;
3755
0
}
3756
3757
// <number> ::= [n] <non-negative decimal integer>
3758
template <typename Alloc, typename Derived>
3759
std::string_view
3760
0
AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
3761
0
  const char *Tmp = First;
3762
0
  if (AllowNegative)
3763
0
    consumeIf('n');
3764
0
  if (numLeft() == 0 || !std::isdigit(*First))
3765
0
    return std::string_view();
3766
0
  while (numLeft() != 0 && std::isdigit(*First))
3767
0
    ++First;
3768
0
  return std::string_view(Tmp, First - Tmp);
3769
0
}
3770
3771
// <positive length number> ::= [0-9]*
3772
template <typename Alloc, typename Derived>
3773
0
bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
3774
0
  *Out = 0;
3775
0
  if (look() < '0' || look() > '9')
3776
0
    return true;
3777
0
  while (look() >= '0' && look() <= '9') {
3778
0
    *Out *= 10;
3779
0
    *Out += static_cast<size_t>(consume() - '0');
3780
0
  }
3781
0
  return false;
3782
0
}
3783
3784
template <typename Alloc, typename Derived>
3785
0
std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3786
0
  size_t Int = 0;
3787
0
  if (parsePositiveInteger(&Int) || numLeft() < Int)
3788
0
    return {};
3789
0
  std::string_view R(First, Int);
3790
0
  First += Int;
3791
0
  return R;
3792
0
}
3793
3794
// <function-type> ::= [<CV-qualifiers>] [<exception-spec>] [Dx] F [Y] <bare-function-type> [<ref-qualifier>] E
3795
//
3796
// <exception-spec> ::= Do                # non-throwing exception-specification (e.g., noexcept, throw())
3797
//                  ::= DO <expression> E # computed (instantiation-dependent) noexcept
3798
//                  ::= Dw <type>+ E      # dynamic exception specification with instantiation-dependent types
3799
//
3800
// <ref-qualifier> ::= R                   # & ref-qualifier
3801
// <ref-qualifier> ::= O                   # && ref-qualifier
3802
template <typename Derived, typename Alloc>
3803
0
Node *AbstractManglingParser<Derived, Alloc>::parseFunctionType() {
3804
0
  Qualifiers CVQuals = parseCVQualifiers();
3805
3806
0
  Node *ExceptionSpec = nullptr;
3807
0
  if (consumeIf("Do")) {
3808
0
    ExceptionSpec = make<NameType>("noexcept");
3809
0
    if (!ExceptionSpec)
3810
0
      return nullptr;
3811
0
  } else if (consumeIf("DO")) {
3812
0
    Node *E = getDerived().parseExpr();
3813
0
    if (E == nullptr || !consumeIf('E'))
3814
0
      return nullptr;
3815
0
    ExceptionSpec = make<NoexceptSpec>(E);
3816
0
    if (!ExceptionSpec)
3817
0
      return nullptr;
3818
0
  } else if (consumeIf("Dw")) {
3819
0
    size_t SpecsBegin = Names.size();
3820
0
    while (!consumeIf('E')) {
3821
0
      Node *T = getDerived().parseType();
3822
0
      if (T == nullptr)
3823
0
        return nullptr;
3824
0
      Names.push_back(T);
3825
0
    }
3826
0
    ExceptionSpec =
3827
0
      make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
3828
0
    if (!ExceptionSpec)
3829
0
      return nullptr;
3830
0
  }
3831
3832
0
  consumeIf("Dx"); // transaction safe
3833
3834
0
  if (!consumeIf('F'))
3835
0
    return nullptr;
3836
0
  consumeIf('Y'); // extern "C"
3837
0
  Node *ReturnType = getDerived().parseType();
3838
0
  if (ReturnType == nullptr)
3839
0
    return nullptr;
3840
3841
0
  FunctionRefQual ReferenceQualifier = FrefQualNone;
3842
0
  size_t ParamsBegin = Names.size();
3843
0
  while (true) {
3844
0
    if (consumeIf('E'))
3845
0
      break;
3846
0
    if (consumeIf('v'))
3847
0
      continue;
3848
0
    if (consumeIf("RE")) {
3849
0
      ReferenceQualifier = FrefQualLValue;
3850
0
      break;
3851
0
    }
3852
0
    if (consumeIf("OE")) {
3853
0
      ReferenceQualifier = FrefQualRValue;
3854
0
      break;
3855
0
    }
3856
0
    Node *T = getDerived().parseType();
3857
0
    if (T == nullptr)
3858
0
      return nullptr;
3859
0
    Names.push_back(T);
3860
0
  }
3861
3862
0
  NodeArray Params = popTrailingNodeArray(ParamsBegin);
3863
0
  return make<FunctionType>(ReturnType, Params, CVQuals,
3864
0
                            ReferenceQualifier, ExceptionSpec);
3865
0
}
3866
3867
// extension:
3868
// <vector-type>           ::= Dv <positive dimension number> _ <extended element type>
3869
//                         ::= Dv [<dimension expression>] _ <element type>
3870
// <extended element type> ::= <element type>
3871
//                         ::= p # AltiVec vector pixel
3872
template <typename Derived, typename Alloc>
3873
0
Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
3874
0
  if (!consumeIf("Dv"))
3875
0
    return nullptr;
3876
0
  if (look() >= '1' && look() <= '9') {
3877
0
    Node *DimensionNumber = make<NameType>(parseNumber());
3878
0
    if (!DimensionNumber)
3879
0
      return nullptr;
3880
0
    if (!consumeIf('_'))
3881
0
      return nullptr;
3882
0
    if (consumeIf('p'))
3883
0
      return make<PixelVectorType>(DimensionNumber);
3884
0
    Node *ElemType = getDerived().parseType();
3885
0
    if (ElemType == nullptr)
3886
0
      return nullptr;
3887
0
    return make<VectorType>(ElemType, DimensionNumber);
3888
0
  }
3889
3890
0
  if (!consumeIf('_')) {
3891
0
    Node *DimExpr = getDerived().parseExpr();
3892
0
    if (!DimExpr)
3893
0
      return nullptr;
3894
0
    if (!consumeIf('_'))
3895
0
      return nullptr;
3896
0
    Node *ElemType = getDerived().parseType();
3897
0
    if (!ElemType)
3898
0
      return nullptr;
3899
0
    return make<VectorType>(ElemType, DimExpr);
3900
0
  }
3901
0
  Node *ElemType = getDerived().parseType();
3902
0
  if (!ElemType)
3903
0
    return nullptr;
3904
0
  return make<VectorType>(ElemType, /*Dimension=*/nullptr);
3905
0
}
3906
3907
// <decltype>  ::= Dt <expression> E  # decltype of an id-expression or class member access (C++0x)
3908
//             ::= DT <expression> E  # decltype of an expression (C++0x)
3909
template <typename Derived, typename Alloc>
3910
0
Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() {
3911
0
  if (!consumeIf('D'))
3912
0
    return nullptr;
3913
0
  if (!consumeIf('t') && !consumeIf('T'))
3914
0
    return nullptr;
3915
0
  Node *E = getDerived().parseExpr();
3916
0
  if (E == nullptr)
3917
0
    return nullptr;
3918
0
  if (!consumeIf('E'))
3919
0
    return nullptr;
3920
0
  return make<EnclosingExpr>("decltype", E);
3921
0
}
3922
3923
// <array-type> ::= A <positive dimension number> _ <element type>
3924
//              ::= A [<dimension expression>] _ <element type>
3925
template <typename Derived, typename Alloc>
3926
0
Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
3927
0
  if (!consumeIf('A'))
3928
0
    return nullptr;
3929
3930
0
  Node *Dimension = nullptr;
3931
3932
0
  if (std::isdigit(look())) {
3933
0
    Dimension = make<NameType>(parseNumber());
3934
0
    if (!Dimension)
3935
0
      return nullptr;
3936
0
    if (!consumeIf('_'))
3937
0
      return nullptr;
3938
0
  } else if (!consumeIf('_')) {
3939
0
    Node *DimExpr = getDerived().parseExpr();
3940
0
    if (DimExpr == nullptr)
3941
0
      return nullptr;
3942
0
    if (!consumeIf('_'))
3943
0
      return nullptr;
3944
0
    Dimension = DimExpr;
3945
0
  }
3946
3947
0
  Node *Ty = getDerived().parseType();
3948
0
  if (Ty == nullptr)
3949
0
    return nullptr;
3950
0
  return make<ArrayType>(Ty, Dimension);
3951
0
}
3952
3953
// <pointer-to-member-type> ::= M <class type> <member type>
3954
template <typename Derived, typename Alloc>
3955
0
Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
3956
0
  if (!consumeIf('M'))
3957
0
    return nullptr;
3958
0
  Node *ClassType = getDerived().parseType();
3959
0
  if (ClassType == nullptr)
3960
0
    return nullptr;
3961
0
  Node *MemberType = getDerived().parseType();
3962
0
  if (MemberType == nullptr)
3963
0
    return nullptr;
3964
0
  return make<PointerToMemberType>(ClassType, MemberType);
3965
0
}
3966
3967
// <class-enum-type> ::= <name>     # non-dependent type name, dependent type name, or dependent typename-specifier
3968
//                   ::= Ts <name>  # dependent elaborated type specifier using 'struct' or 'class'
3969
//                   ::= Tu <name>  # dependent elaborated type specifier using 'union'
3970
//                   ::= Te <name>  # dependent elaborated type specifier using 'enum'
3971
template <typename Derived, typename Alloc>
3972
0
Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
3973
0
  std::string_view ElabSpef;
3974
0
  if (consumeIf("Ts"))
3975
0
    ElabSpef = "struct";
3976
0
  else if (consumeIf("Tu"))
3977
0
    ElabSpef = "union";
3978
0
  else if (consumeIf("Te"))
3979
0
    ElabSpef = "enum";
3980
3981
0
  Node *Name = getDerived().parseName();
3982
0
  if (Name == nullptr)
3983
0
    return nullptr;
3984
3985
0
  if (!ElabSpef.empty())
3986
0
    return make<ElaboratedTypeSpefType>(ElabSpef, Name);
3987
3988
0
  return Name;
3989
0
}
3990
3991
// <qualified-type>     ::= <qualifiers> <type>
3992
// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
3993
// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
3994
template <typename Derived, typename Alloc>
3995
0
Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
3996
0
  if (consumeIf('U')) {
3997
0
    std::string_view Qual = parseBareSourceName();
3998
0
    if (Qual.empty())
3999
0
      return nullptr;
4000
4001
    // extension            ::= U <objc-name> <objc-type>  # objc-type<identifier>
4002
0
    if (starts_with(Qual, "objcproto")) {
4003
0
      constexpr size_t Len = sizeof("objcproto") - 1;
4004
0
      std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
4005
0
      std::string_view Proto;
4006
0
      {
4007
0
        ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
4008
0
            SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
4009
0
        Proto = parseBareSourceName();
4010
0
      }
4011
0
      if (Proto.empty())
4012
0
        return nullptr;
4013
0
      Node *Child = getDerived().parseQualifiedType();
4014
0
      if (Child == nullptr)
4015
0
        return nullptr;
4016
0
      return make<ObjCProtoName>(Child, Proto);
4017
0
    }
4018
4019
0
    Node *TA = nullptr;
4020
0
    if (look() == 'I') {
4021
0
      TA = getDerived().parseTemplateArgs();
4022
0
      if (TA == nullptr)
4023
0
        return nullptr;
4024
0
    }
4025
4026
0
    Node *Child = getDerived().parseQualifiedType();
4027
0
    if (Child == nullptr)
4028
0
      return nullptr;
4029
0
    return make<VendorExtQualType>(Child, Qual, TA);
4030
0
  }
4031
4032
0
  Qualifiers Quals = parseCVQualifiers();
4033
0
  Node *Ty = getDerived().parseType();
4034
0
  if (Ty == nullptr)
4035
0
    return nullptr;
4036
0
  if (Quals != QualNone)
4037
0
    Ty = make<QualType>(Ty, Quals);
4038
0
  return Ty;
4039
0
}
4040
4041
// <type>      ::= <builtin-type>
4042
//             ::= <qualified-type>
4043
//             ::= <function-type>
4044
//             ::= <class-enum-type>
4045
//             ::= <array-type>
4046
//             ::= <pointer-to-member-type>
4047
//             ::= <template-param>
4048
//             ::= <template-template-param> <template-args>
4049
//             ::= <decltype>
4050
//             ::= P <type>        # pointer
4051
//             ::= R <type>        # l-value reference
4052
//             ::= O <type>        # r-value reference (C++11)
4053
//             ::= C <type>        # complex pair (C99)
4054
//             ::= G <type>        # imaginary (C99)
4055
//             ::= <substitution>  # See Compression below
4056
// extension   ::= U <objc-name> <objc-type>  # objc-type<identifier>
4057
// extension   ::= <vector-type> # <vector-type> starts with Dv
4058
//
4059
// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier>  # k0 = 9 + <number of digits in k1> + k1
4060
// <objc-type> ::= <source-name>  # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
4061
template <typename Derived, typename Alloc>
4062
0
Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4063
0
  Node *Result = nullptr;
4064
4065
0
  switch (look()) {
4066
  //             ::= <qualified-type>
4067
0
  case 'r':
4068
0
  case 'V':
4069
0
  case 'K': {
4070
0
    unsigned AfterQuals = 0;
4071
0
    if (look(AfterQuals) == 'r') ++AfterQuals;
4072
0
    if (look(AfterQuals) == 'V') ++AfterQuals;
4073
0
    if (look(AfterQuals) == 'K') ++AfterQuals;
4074
4075
0
    if (look(AfterQuals) == 'F' ||
4076
0
        (look(AfterQuals) == 'D' &&
4077
0
         (look(AfterQuals + 1) == 'o' || look(AfterQuals + 1) == 'O' ||
4078
0
          look(AfterQuals + 1) == 'w' || look(AfterQuals + 1) == 'x'))) {
4079
0
      Result = getDerived().parseFunctionType();
4080
0
      break;
4081
0
    }
4082
0
    DEMANGLE_FALLTHROUGH;
4083
0
  }
4084
0
  case 'U': {
4085
0
    Result = getDerived().parseQualifiedType();
4086
0
    break;
4087
0
  }
4088
  // <builtin-type> ::= v    # void
4089
0
  case 'v':
4090
0
    ++First;
4091
0
    return make<NameType>("void");
4092
  //                ::= w    # wchar_t
4093
0
  case 'w':
4094
0
    ++First;
4095
0
    return make<NameType>("wchar_t");
4096
  //                ::= b    # bool
4097
0
  case 'b':
4098
0
    ++First;
4099
0
    return make<NameType>("bool");
4100
  //                ::= c    # char
4101
0
  case 'c':
4102
0
    ++First;
4103
0
    return make<NameType>("char");
4104
  //                ::= a    # signed char
4105
0
  case 'a':
4106
0
    ++First;
4107
0
    return make<NameType>("signed char");
4108
  //                ::= h    # unsigned char
4109
0
  case 'h':
4110
0
    ++First;
4111
0
    return make<NameType>("unsigned char");
4112
  //                ::= s    # short
4113
0
  case 's':
4114
0
    ++First;
4115
0
    return make<NameType>("short");
4116
  //                ::= t    # unsigned short
4117
0
  case 't':
4118
0
    ++First;
4119
0
    return make<NameType>("unsigned short");
4120
  //                ::= i    # int
4121
0
  case 'i':
4122
0
    ++First;
4123
0
    return make<NameType>("int");
4124
  //                ::= j    # unsigned int
4125
0
  case 'j':
4126
0
    ++First;
4127
0
    return make<NameType>("unsigned int");
4128
  //                ::= l    # long
4129
0
  case 'l':
4130
0
    ++First;
4131
0
    return make<NameType>("long");
4132
  //                ::= m    # unsigned long
4133
0
  case 'm':
4134
0
    ++First;
4135
0
    return make<NameType>("unsigned long");
4136
  //                ::= x    # long long, __int64
4137
0
  case 'x':
4138
0
    ++First;
4139
0
    return make<NameType>("long long");
4140
  //                ::= y    # unsigned long long, __int64
4141
0
  case 'y':
4142
0
    ++First;
4143
0
    return make<NameType>("unsigned long long");
4144
  //                ::= n    # __int128
4145
0
  case 'n':
4146
0
    ++First;
4147
0
    return make<NameType>("__int128");
4148
  //                ::= o    # unsigned __int128
4149
0
  case 'o':
4150
0
    ++First;
4151
0
    return make<NameType>("unsigned __int128");
4152
  //                ::= f    # float
4153
0
  case 'f':
4154
0
    ++First;
4155
0
    return make<NameType>("float");
4156
  //                ::= d    # double
4157
0
  case 'd':
4158
0
    ++First;
4159
0
    return make<NameType>("double");
4160
  //                ::= e    # long double, __float80
4161
0
  case 'e':
4162
0
    ++First;
4163
0
    return make<NameType>("long double");
4164
  //                ::= g    # __float128
4165
0
  case 'g':
4166
0
    ++First;
4167
0
    return make<NameType>("__float128");
4168
  //                ::= z    # ellipsis
4169
0
  case 'z':
4170
0
    ++First;
4171
0
    return make<NameType>("...");
4172
4173
  // <builtin-type> ::= u <source-name>    # vendor extended type
4174
0
  case 'u': {
4175
0
    ++First;
4176
0
    std::string_view Res = parseBareSourceName();
4177
0
    if (Res.empty())
4178
0
      return nullptr;
4179
    // Typically, <builtin-type>s are not considered substitution candidates,
4180
    // but the exception to that exception is vendor extended types (Itanium C++
4181
    // ABI 5.9.1).
4182
0
    if (consumeIf('I')) {
4183
0
      Node *BaseType = parseType();
4184
0
      if (BaseType == nullptr)
4185
0
        return nullptr;
4186
0
      if (!consumeIf('E'))
4187
0
        return nullptr;
4188
0
      Result = make<TransformedType>(Res, BaseType);
4189
0
    } else
4190
0
      Result = make<NameType>(Res);
4191
0
    break;
4192
0
  }
4193
0
  case 'D':
4194
0
    switch (look(1)) {
4195
    //                ::= Dd   # IEEE 754r decimal floating point (64 bits)
4196
0
    case 'd':
4197
0
      First += 2;
4198
0
      return make<NameType>("decimal64");
4199
    //                ::= De   # IEEE 754r decimal floating point (128 bits)
4200
0
    case 'e':
4201
0
      First += 2;
4202
0
      return make<NameType>("decimal128");
4203
    //                ::= Df   # IEEE 754r decimal floating point (32 bits)
4204
0
    case 'f':
4205
0
      First += 2;
4206
0
      return make<NameType>("decimal32");
4207
    //                ::= Dh   # IEEE 754r half-precision floating point (16 bits)
4208
0
    case 'h':
4209
0
      First += 2;
4210
0
      return make<NameType>("half");
4211
    //                ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
4212
0
    case 'F': {
4213
0
      First += 2;
4214
0
      Node *DimensionNumber = make<NameType>(parseNumber());
4215
0
      if (!DimensionNumber)
4216
0
        return nullptr;
4217
0
      if (!consumeIf('_'))
4218
0
        return nullptr;
4219
0
      return make<BinaryFPType>(DimensionNumber);
4220
0
    }
4221
    //                ::= DB <number> _                             # C23 signed _BitInt(N)
4222
    //                ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
4223
    //                ::= DU <number> _                             # C23 unsigned _BitInt(N)
4224
    //                ::= DU <instantiation-dependent expression> _ # C23 unsigned _BitInt(N)
4225
0
    case 'B':
4226
0
    case 'U': {
4227
0
      bool Signed = look(1) == 'B';
4228
0
      First += 2;
4229
0
      Node *Size = std::isdigit(look()) ? make<NameType>(parseNumber())
4230
0
                                        : getDerived().parseExpr();
4231
0
      if (!Size)
4232
0
        return nullptr;
4233
0
      if (!consumeIf('_'))
4234
0
        return nullptr;
4235
0
      return make<BitIntType>(Size, Signed);
4236
0
    }
4237
    //                ::= Di   # char32_t
4238
0
    case 'i':
4239
0
      First += 2;
4240
0
      return make<NameType>("char32_t");
4241
    //                ::= Ds   # char16_t
4242
0
    case 's':
4243
0
      First += 2;
4244
0
      return make<NameType>("char16_t");
4245
    //                ::= Du   # char8_t (C++2a, not yet in the Itanium spec)
4246
0
    case 'u':
4247
0
      First += 2;
4248
0
      return make<NameType>("char8_t");
4249
    //                ::= Da   # auto (in dependent new-expressions)
4250
0
    case 'a':
4251
0
      First += 2;
4252
0
      return make<NameType>("auto");
4253
    //                ::= Dc   # decltype(auto)
4254
0
    case 'c':
4255
0
      First += 2;
4256
0
      return make<NameType>("decltype(auto)");
4257
    //                ::= Dk <type-constraint> # constrained auto
4258
    //                ::= DK <type-constraint> # constrained decltype(auto)
4259
0
    case 'k':
4260
0
    case 'K': {
4261
0
      std::string_view Kind = look(1) == 'k' ? " auto" : " decltype(auto)";
4262
0
      First += 2;
4263
0
      Node *Constraint = getDerived().parseName();
4264
0
      if (!Constraint)
4265
0
        return nullptr;
4266
0
      return make<PostfixQualifiedType>(Constraint, Kind);
4267
0
    }
4268
    //                ::= Dn   # std::nullptr_t (i.e., decltype(nullptr))
4269
0
    case 'n':
4270
0
      First += 2;
4271
0
      return make<NameType>("std::nullptr_t");
4272
4273
    //             ::= <decltype>
4274
0
    case 't':
4275
0
    case 'T': {
4276
0
      Result = getDerived().parseDecltype();
4277
0
      break;
4278
0
    }
4279
    // extension   ::= <vector-type> # <vector-type> starts with Dv
4280
0
    case 'v': {
4281
0
      Result = getDerived().parseVectorType();
4282
0
      break;
4283
0
    }
4284
    //           ::= Dp <type>       # pack expansion (C++0x)
4285
0
    case 'p': {
4286
0
      First += 2;
4287
0
      Node *Child = getDerived().parseType();
4288
0
      if (!Child)
4289
0
        return nullptr;
4290
0
      Result = make<ParameterPackExpansion>(Child);
4291
0
      break;
4292
0
    }
4293
    // Exception specifier on a function type.
4294
0
    case 'o':
4295
0
    case 'O':
4296
0
    case 'w':
4297
    // Transaction safe function type.
4298
0
    case 'x':
4299
0
      Result = getDerived().parseFunctionType();
4300
0
      break;
4301
0
    }
4302
0
    break;
4303
  //             ::= <function-type>
4304
0
  case 'F': {
4305
0
    Result = getDerived().parseFunctionType();
4306
0
    break;
4307
0
  }
4308
  //             ::= <array-type>
4309
0
  case 'A': {
4310
0
    Result = getDerived().parseArrayType();
4311
0
    break;
4312
0
  }
4313
  //             ::= <pointer-to-member-type>
4314
0
  case 'M': {
4315
0
    Result = getDerived().parsePointerToMemberType();
4316
0
    break;
4317
0
  }
4318
  //             ::= <template-param>
4319
0
  case 'T': {
4320
    // This could be an elaborate type specifier on a <class-enum-type>.
4321
0
    if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
4322
0
      Result = getDerived().parseClassEnumType();
4323
0
      break;
4324
0
    }
4325
4326
0
    Result = getDerived().parseTemplateParam();
4327
0
    if (Result == nullptr)
4328
0
      return nullptr;
4329
4330
    // Result could be either of:
4331
    //   <type>        ::= <template-param>
4332
    //   <type>        ::= <template-template-param> <template-args>
4333
    //
4334
    //   <template-template-param> ::= <template-param>
4335
    //                             ::= <substitution>
4336
    //
4337
    // If this is followed by some <template-args>, and we're permitted to
4338
    // parse them, take the second production.
4339
4340
0
    if (TryToParseTemplateArgs && look() == 'I') {
4341
0
      Node *TA = getDerived().parseTemplateArgs();
4342
0
      if (TA == nullptr)
4343
0
        return nullptr;
4344
0
      Result = make<NameWithTemplateArgs>(Result, TA);
4345
0
    }
4346
0
    break;
4347
0
  }
4348
  //             ::= P <type>        # pointer
4349
0
  case 'P': {
4350
0
    ++First;
4351
0
    Node *Ptr = getDerived().parseType();
4352
0
    if (Ptr == nullptr)
4353
0
      return nullptr;
4354
0
    Result = make<PointerType>(Ptr);
4355
0
    break;
4356
0
  }
4357
  //             ::= R <type>        # l-value reference
4358
0
  case 'R': {
4359
0
    ++First;
4360
0
    Node *Ref = getDerived().parseType();
4361
0
    if (Ref == nullptr)
4362
0
      return nullptr;
4363
0
    Result = make<ReferenceType>(Ref, ReferenceKind::LValue);
4364
0
    break;
4365
0
  }
4366
  //             ::= O <type>        # r-value reference (C++11)
4367
0
  case 'O': {
4368
0
    ++First;
4369
0
    Node *Ref = getDerived().parseType();
4370
0
    if (Ref == nullptr)
4371
0
      return nullptr;
4372
0
    Result = make<ReferenceType>(Ref, ReferenceKind::RValue);
4373
0
    break;
4374
0
  }
4375
  //             ::= C <type>        # complex pair (C99)
4376
0
  case 'C': {
4377
0
    ++First;
4378
0
    Node *P = getDerived().parseType();
4379
0
    if (P == nullptr)
4380
0
      return nullptr;
4381
0
    Result = make<PostfixQualifiedType>(P, " complex");
4382
0
    break;
4383
0
  }
4384
  //             ::= G <type>        # imaginary (C99)
4385
0
  case 'G': {
4386
0
    ++First;
4387
0
    Node *P = getDerived().parseType();
4388
0
    if (P == nullptr)
4389
0
      return P;
4390
0
    Result = make<PostfixQualifiedType>(P, " imaginary");
4391
0
    break;
4392
0
  }
4393
  //             ::= <substitution>  # See Compression below
4394
0
  case 'S': {
4395
0
    if (look(1) != 't') {
4396
0
      bool IsSubst = false;
4397
0
      Result = getDerived().parseUnscopedName(nullptr, &IsSubst);
4398
0
      if (!Result)
4399
0
        return nullptr;
4400
4401
      // Sub could be either of:
4402
      //   <type>        ::= <substitution>
4403
      //   <type>        ::= <template-template-param> <template-args>
4404
      //
4405
      //   <template-template-param> ::= <template-param>
4406
      //                             ::= <substitution>
4407
      //
4408
      // If this is followed by some <template-args>, and we're permitted to
4409
      // parse them, take the second production.
4410
4411
0
      if (look() == 'I' && (!IsSubst || TryToParseTemplateArgs)) {
4412
0
        if (!IsSubst)
4413
0
          Subs.push_back(Result);
4414
0
        Node *TA = getDerived().parseTemplateArgs();
4415
0
        if (TA == nullptr)
4416
0
          return nullptr;
4417
0
        Result = make<NameWithTemplateArgs>(Result, TA);
4418
0
      } else if (IsSubst) {
4419
        // If all we parsed was a substitution, don't re-insert into the
4420
        // substitution table.
4421
0
        return Result;
4422
0
      }
4423
0
      break;
4424
0
    }
4425
0
    DEMANGLE_FALLTHROUGH;
4426
0
  }
4427
  //        ::= <class-enum-type>
4428
0
  default: {
4429
0
    Result = getDerived().parseClassEnumType();
4430
0
    break;
4431
0
  }
4432
0
  }
4433
4434
  // If we parsed a type, insert it into the substitution table. Note that all
4435
  // <builtin-type>s and <substitution>s have already bailed out, because they
4436
  // don't get substitutions.
4437
0
  if (Result != nullptr)
4438
0
    Subs.push_back(Result);
4439
0
  return Result;
4440
0
}
4441
4442
template <typename Derived, typename Alloc>
4443
Node *
4444
AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
4445
0
                                                        Node::Prec Prec) {
4446
0
  Node *E = getDerived().parseExpr();
4447
0
  if (E == nullptr)
4448
0
    return nullptr;
4449
0
  return make<PrefixExpr>(Kind, E, Prec);
4450
0
}
4451
4452
template <typename Derived, typename Alloc>
4453
Node *
4454
AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
4455
0
                                                        Node::Prec Prec) {
4456
0
  Node *LHS = getDerived().parseExpr();
4457
0
  if (LHS == nullptr)
4458
0
    return nullptr;
4459
0
  Node *RHS = getDerived().parseExpr();
4460
0
  if (RHS == nullptr)
4461
0
    return nullptr;
4462
0
  return make<BinaryExpr>(LHS, Kind, RHS, Prec);
4463
0
}
4464
4465
template <typename Derived, typename Alloc>
4466
Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
4467
0
    std::string_view Lit) {
4468
0
  std::string_view Tmp = parseNumber(true);
4469
0
  if (!Tmp.empty() && consumeIf('E'))
4470
0
    return make<IntegerLiteral>(Lit, Tmp);
4471
0
  return nullptr;
4472
0
}
4473
4474
// <CV-Qualifiers> ::= [r] [V] [K]
4475
template <typename Alloc, typename Derived>
4476
0
Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
4477
0
  Qualifiers CVR = QualNone;
4478
0
  if (consumeIf('r'))
4479
0
    CVR |= QualRestrict;
4480
0
  if (consumeIf('V'))
4481
0
    CVR |= QualVolatile;
4482
0
  if (consumeIf('K'))
4483
0
    CVR |= QualConst;
4484
0
  return CVR;
4485
0
}
4486
4487
// <function-param> ::= fp <top-level CV-Qualifiers> _                                     # L == 0, first parameter
4488
//                  ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _   # L == 0, second and later parameters
4489
//                  ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _         # L > 0, first parameter
4490
//                  ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _   # L > 0, second and later parameters
4491
//                  ::= fpT      # 'this' expression (not part of standard?)
4492
template <typename Derived, typename Alloc>
4493
0
Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4494
0
  if (consumeIf("fpT"))
4495
0
    return make<NameType>("this");
4496
0
  if (consumeIf("fp")) {
4497
0
    parseCVQualifiers();
4498
0
    std::string_view Num = parseNumber();
4499
0
    if (!consumeIf('_'))
4500
0
      return nullptr;
4501
0
    return make<FunctionParam>(Num);
4502
0
  }
4503
0
  if (consumeIf("fL")) {
4504
0
    if (parseNumber().empty())
4505
0
      return nullptr;
4506
0
    if (!consumeIf('p'))
4507
0
      return nullptr;
4508
0
    parseCVQualifiers();
4509
0
    std::string_view Num = parseNumber();
4510
0
    if (!consumeIf('_'))
4511
0
      return nullptr;
4512
0
    return make<FunctionParam>(Num);
4513
0
  }
4514
0
  return nullptr;
4515
0
}
4516
4517
// cv <type> <expression>                               # conversion with one argument
4518
// cv <type> _ <expression>* E                          # conversion with a different number of arguments
4519
template <typename Derived, typename Alloc>
4520
Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() {
4521
  if (!consumeIf("cv"))
4522
    return nullptr;
4523
  Node *Ty;
4524
  {
4525
    ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4526
    Ty = getDerived().parseType();
4527
  }
4528
4529
  if (Ty == nullptr)
4530
    return nullptr;
4531
4532
  if (consumeIf('_')) {
4533
    size_t ExprsBegin = Names.size();
4534
    while (!consumeIf('E')) {
4535
      Node *E = getDerived().parseExpr();
4536
      if (E == nullptr)
4537
        return E;
4538
      Names.push_back(E);
4539
    }
4540
    NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
4541
    return make<ConversionExpr>(Ty, Exprs);
4542
  }
4543
4544
  Node *E[1] = {getDerived().parseExpr()};
4545
  if (E[0] == nullptr)
4546
    return nullptr;
4547
  return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
4548
}
4549
4550
// <expr-primary> ::= L <type> <value number> E                          # integer literal
4551
//                ::= L <type> <value float> E                           # floating literal
4552
//                ::= L <string type> E                                  # string literal
4553
//                ::= L <nullptr type> E                                 # nullptr literal (i.e., "LDnE")
4554
//                ::= L <lambda type> E                                  # lambda expression
4555
// FIXME:         ::= L <type> <real-part float> _ <imag-part float> E   # complex floating point literal (C 2000)
4556
//                ::= L <mangled-name> E                                 # external name
4557
template <typename Derived, typename Alloc>
4558
0
Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4559
0
  if (!consumeIf('L'))
4560
0
    return nullptr;
4561
0
  switch (look()) {
4562
0
  case 'w':
4563
0
    ++First;
4564
0
    return getDerived().parseIntegerLiteral("wchar_t");
4565
0
  case 'b':
4566
0
    if (consumeIf("b0E"))
4567
0
      return make<BoolExpr>(0);
4568
0
    if (consumeIf("b1E"))
4569
0
      return make<BoolExpr>(1);
4570
0
    return nullptr;
4571
0
  case 'c':
4572
0
    ++First;
4573
0
    return getDerived().parseIntegerLiteral("char");
4574
0
  case 'a':
4575
0
    ++First;
4576
0
    return getDerived().parseIntegerLiteral("signed char");
4577
0
  case 'h':
4578
0
    ++First;
4579
0
    return getDerived().parseIntegerLiteral("unsigned char");
4580
0
  case 's':
4581
0
    ++First;
4582
0
    return getDerived().parseIntegerLiteral("short");
4583
0
  case 't':
4584
0
    ++First;
4585
0
    return getDerived().parseIntegerLiteral("unsigned short");
4586
0
  case 'i':
4587
0
    ++First;
4588
0
    return getDerived().parseIntegerLiteral("");
4589
0
  case 'j':
4590
0
    ++First;
4591
0
    return getDerived().parseIntegerLiteral("u");
4592
0
  case 'l':
4593
0
    ++First;
4594
0
    return getDerived().parseIntegerLiteral("l");
4595
0
  case 'm':
4596
0
    ++First;
4597
0
    return getDerived().parseIntegerLiteral("ul");
4598
0
  case 'x':
4599
0
    ++First;
4600
0
    return getDerived().parseIntegerLiteral("ll");
4601
0
  case 'y':
4602
0
    ++First;
4603
0
    return getDerived().parseIntegerLiteral("ull");
4604
0
  case 'n':
4605
0
    ++First;
4606
0
    return getDerived().parseIntegerLiteral("__int128");
4607
0
  case 'o':
4608
0
    ++First;
4609
0
    return getDerived().parseIntegerLiteral("unsigned __int128");
4610
0
  case 'f':
4611
0
    ++First;
4612
0
    return getDerived().template parseFloatingLiteral<float>();
4613
0
  case 'd':
4614
0
    ++First;
4615
0
    return getDerived().template parseFloatingLiteral<double>();
4616
0
  case 'e':
4617
0
    ++First;
4618
#if defined(__powerpc__) || defined(__s390__)
4619
    // Handle cases where long doubles encoded with e have the same size
4620
    // and representation as doubles.
4621
    return getDerived().template parseFloatingLiteral<double>();
4622
#else
4623
0
    return getDerived().template parseFloatingLiteral<long double>();
4624
0
#endif
4625
0
  case '_':
4626
0
    if (consumeIf("_Z")) {
4627
0
      Node *R = getDerived().parseEncoding();
4628
0
      if (R != nullptr && consumeIf('E'))
4629
0
        return R;
4630
0
    }
4631
0
    return nullptr;
4632
0
  case 'A': {
4633
0
    Node *T = getDerived().parseType();
4634
0
    if (T == nullptr)
4635
0
      return nullptr;
4636
    // FIXME: We need to include the string contents in the mangling.
4637
0
    if (consumeIf('E'))
4638
0
      return make<StringLiteral>(T);
4639
0
    return nullptr;
4640
0
  }
4641
0
  case 'D':
4642
0
    if (consumeIf("Dn") && (consumeIf('0'), consumeIf('E')))
4643
0
      return make<NameType>("nullptr");
4644
0
    return nullptr;
4645
0
  case 'T':
4646
    // Invalid mangled name per
4647
    //   http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4648
0
    return nullptr;
4649
0
  case 'U': {
4650
    // FIXME: Should we support LUb... for block literals?
4651
0
    if (look(1) != 'l')
4652
0
      return nullptr;
4653
0
    Node *T = parseUnnamedTypeName(nullptr);
4654
0
    if (!T || !consumeIf('E'))
4655
0
      return nullptr;
4656
0
    return make<LambdaExpr>(T);
4657
0
  }
4658
0
  default: {
4659
    // might be named type
4660
0
    Node *T = getDerived().parseType();
4661
0
    if (T == nullptr)
4662
0
      return nullptr;
4663
0
    std::string_view N = parseNumber(/*AllowNegative=*/true);
4664
0
    if (N.empty())
4665
0
      return nullptr;
4666
0
    if (!consumeIf('E'))
4667
0
      return nullptr;
4668
0
    return make<EnumLiteral>(T, N);
4669
0
  }
4670
0
  }
4671
0
}
4672
4673
// <braced-expression> ::= <expression>
4674
//                     ::= di <field source-name> <braced-expression>    # .name = expr
4675
//                     ::= dx <index expression> <braced-expression>     # [expr] = expr
4676
//                     ::= dX <range begin expression> <range end expression> <braced-expression>
4677
template <typename Derived, typename Alloc>
4678
0
Node *AbstractManglingParser<Derived, Alloc>::parseBracedExpr() {
4679
0
  if (look() == 'd') {
4680
0
    switch (look(1)) {
4681
0
    case 'i': {
4682
0
      First += 2;
4683
0
      Node *Field = getDerived().parseSourceName(/*NameState=*/nullptr);
4684
0
      if (Field == nullptr)
4685
0
        return nullptr;
4686
0
      Node *Init = getDerived().parseBracedExpr();
4687
0
      if (Init == nullptr)
4688
0
        return nullptr;
4689
0
      return make<BracedExpr>(Field, Init, /*isArray=*/false);
4690
0
    }
4691
0
    case 'x': {
4692
0
      First += 2;
4693
0
      Node *Index = getDerived().parseExpr();
4694
0
      if (Index == nullptr)
4695
0
        return nullptr;
4696
0
      Node *Init = getDerived().parseBracedExpr();
4697
0
      if (Init == nullptr)
4698
0
        return nullptr;
4699
0
      return make<BracedExpr>(Index, Init, /*isArray=*/true);
4700
0
    }
4701
0
    case 'X': {
4702
0
      First += 2;
4703
0
      Node *RangeBegin = getDerived().parseExpr();
4704
0
      if (RangeBegin == nullptr)
4705
0
        return nullptr;
4706
0
      Node *RangeEnd = getDerived().parseExpr();
4707
0
      if (RangeEnd == nullptr)
4708
0
        return nullptr;
4709
0
      Node *Init = getDerived().parseBracedExpr();
4710
0
      if (Init == nullptr)
4711
0
        return nullptr;
4712
0
      return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4713
0
    }
4714
0
    }
4715
0
  }
4716
0
  return getDerived().parseExpr();
4717
0
}
4718
4719
// (not yet in the spec)
4720
// <fold-expr> ::= fL <binary-operator-name> <expression> <expression>
4721
//             ::= fR <binary-operator-name> <expression> <expression>
4722
//             ::= fl <binary-operator-name> <expression>
4723
//             ::= fr <binary-operator-name> <expression>
4724
template <typename Derived, typename Alloc>
4725
0
Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
4726
0
  if (!consumeIf('f'))
4727
0
    return nullptr;
4728
4729
0
  bool IsLeftFold = false, HasInitializer = false;
4730
0
  switch (look()) {
4731
0
  default:
4732
0
    return nullptr;
4733
0
  case 'L':
4734
0
    IsLeftFold = true;
4735
0
    HasInitializer = true;
4736
0
    break;
4737
0
  case 'R':
4738
0
    HasInitializer = true;
4739
0
    break;
4740
0
  case 'l':
4741
0
    IsLeftFold = true;
4742
0
    break;
4743
0
  case 'r':
4744
0
    break;
4745
0
  }
4746
0
  ++First;
4747
4748
0
  const auto *Op = parseOperatorEncoding();
4749
0
  if (!Op)
4750
0
    return nullptr;
4751
0
  if (!(Op->getKind() == OperatorInfo::Binary
4752
0
        || (Op->getKind() == OperatorInfo::Member
4753
0
            && Op->getName().back() == '*')))
4754
0
    return nullptr;
4755
4756
0
  Node *Pack = getDerived().parseExpr();
4757
0
  if (Pack == nullptr)
4758
0
    return nullptr;
4759
4760
0
  Node *Init = nullptr;
4761
0
  if (HasInitializer) {
4762
0
    Init = getDerived().parseExpr();
4763
0
    if (Init == nullptr)
4764
0
      return nullptr;
4765
0
  }
4766
4767
0
  if (IsLeftFold && Init)
4768
0
    std::swap(Pack, Init);
4769
4770
0
  return make<FoldExpr>(IsLeftFold, Op->getSymbol(), Pack, Init);
4771
0
}
4772
4773
// <expression> ::= mc <parameter type> <expr> [<offset number>] E
4774
//
4775
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
4776
template <typename Derived, typename Alloc>
4777
Node *
4778
AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
4779
0
    Node::Prec Prec) {
4780
0
  Node *Ty = getDerived().parseType();
4781
0
  if (!Ty)
4782
0
    return nullptr;
4783
0
  Node *Expr = getDerived().parseExpr();
4784
0
  if (!Expr)
4785
0
    return nullptr;
4786
0
  std::string_view Offset = getDerived().parseNumber(true);
4787
0
  if (!consumeIf('E'))
4788
0
    return nullptr;
4789
0
  return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
4790
0
}
4791
4792
// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
4793
// <union-selector> ::= _ [<number>]
4794
//
4795
// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
4796
template <typename Derived, typename Alloc>
4797
0
Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
4798
0
  Node *Ty = getDerived().parseType();
4799
0
  if (!Ty)
4800
0
    return nullptr;
4801
0
  Node *Expr = getDerived().parseExpr();
4802
0
  if (!Expr)
4803
0
    return nullptr;
4804
0
  std::string_view Offset = getDerived().parseNumber(true);
4805
0
  size_t SelectorsBegin = Names.size();
4806
0
  while (consumeIf('_')) {
4807
0
    Node *Selector = make<NameType>(parseNumber());
4808
0
    if (!Selector)
4809
0
      return nullptr;
4810
0
    Names.push_back(Selector);
4811
0
  }
4812
0
  bool OnePastTheEnd = consumeIf('p');
4813
0
  if (!consumeIf('E'))
4814
0
    return nullptr;
4815
0
  return make<SubobjectExpr>(
4816
0
      Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
4817
0
}
4818
4819
template <typename Derived, typename Alloc>
4820
0
Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
4821
  // Within this expression, all enclosing template parameter lists are in
4822
  // scope.
4823
0
  ScopedOverride<bool> SaveInConstraintExpr(InConstraintExpr, true);
4824
0
  return getDerived().parseExpr();
4825
0
}
4826
4827
template <typename Derived, typename Alloc>
4828
0
Node *AbstractManglingParser<Derived, Alloc>::parseRequiresExpr() {
4829
0
  NodeArray Params;
4830
0
  if (consumeIf("rQ")) {
4831
    // <expression> ::= rQ <bare-function-type> _ <requirement>+ E
4832
0
    size_t ParamsBegin = Names.size();
4833
0
    while (!consumeIf('_')) {
4834
0
      Node *Type = getDerived().parseType();
4835
0
      if (Type == nullptr)
4836
0
        return nullptr;
4837
0
      Names.push_back(Type);
4838
0
    }
4839
0
    Params = popTrailingNodeArray(ParamsBegin);
4840
0
  } else if (!consumeIf("rq")) {
4841
    // <expression> ::= rq <requirement>+ E
4842
0
    return nullptr;
4843
0
  }
4844
4845
0
  size_t ReqsBegin = Names.size();
4846
0
  do {
4847
0
    Node *Constraint = nullptr;
4848
0
    if (consumeIf('X')) {
4849
      // <requirement> ::= X <expression> [N] [R <type-constraint>]
4850
0
      Node *Expr = getDerived().parseExpr();
4851
0
      if (Expr == nullptr)
4852
0
        return nullptr;
4853
0
      bool Noexcept = consumeIf('N');
4854
0
      Node *TypeReq = nullptr;
4855
0
      if (consumeIf('R')) {
4856
0
        TypeReq = getDerived().parseName();
4857
0
        if (TypeReq == nullptr)
4858
0
          return nullptr;
4859
0
      }
4860
0
      Constraint = make<ExprRequirement>(Expr, Noexcept, TypeReq);
4861
0
    } else if (consumeIf('T')) {
4862
      // <requirement> ::= T <type>
4863
0
      Node *Type = getDerived().parseType();
4864
0
      if (Type == nullptr)
4865
0
        return nullptr;
4866
0
      Constraint = make<TypeRequirement>(Type);
4867
0
    } else if (consumeIf('Q')) {
4868
      // <requirement> ::= Q <constraint-expression>
4869
      //
4870
      // FIXME: We use <expression> instead of <constraint-expression>. Either
4871
      // the requires expression is already inside a constraint expression, in
4872
      // which case it makes no difference, or we're in a requires-expression
4873
      // that might be partially-substituted, where the language behavior is
4874
      // not yet settled and clang mangles after substitution.
4875
0
      Node *NestedReq = getDerived().parseExpr();
4876
0
      if (NestedReq == nullptr)
4877
0
        return nullptr;
4878
0
      Constraint = make<NestedRequirement>(NestedReq);
4879
0
    }
4880
0
    if (Constraint == nullptr)
4881
0
      return nullptr;
4882
0
    Names.push_back(Constraint);
4883
0
  } while (!consumeIf('E'));
4884
4885
0
  return make<RequiresExpr>(Params, popTrailingNodeArray(ReqsBegin));
4886
0
}
4887
4888
// <expression> ::= <unary operator-name> <expression>
4889
//              ::= <binary operator-name> <expression> <expression>
4890
//              ::= <ternary operator-name> <expression> <expression> <expression>
4891
//              ::= cl <expression>+ E                                   # call
4892
//              ::= cv <type> <expression>                               # conversion with one argument
4893
//              ::= cv <type> _ <expression>* E                          # conversion with a different number of arguments
4894
//              ::= [gs] nw <expression>* _ <type> E                     # new (expr-list) type
4895
//              ::= [gs] nw <expression>* _ <type> <initializer>         # new (expr-list) type (init)
4896
//              ::= [gs] na <expression>* _ <type> E                     # new[] (expr-list) type
4897
//              ::= [gs] na <expression>* _ <type> <initializer>         # new[] (expr-list) type (init)
4898
//              ::= [gs] dl <expression>                                 # delete expression
4899
//              ::= [gs] da <expression>                                 # delete[] expression
4900
//              ::= pp_ <expression>                                     # prefix ++
4901
//              ::= mm_ <expression>                                     # prefix --
4902
//              ::= ti <type>                                            # typeid (type)
4903
//              ::= te <expression>                                      # typeid (expression)
4904
//              ::= dc <type> <expression>                               # dynamic_cast<type> (expression)
4905
//              ::= sc <type> <expression>                               # static_cast<type> (expression)
4906
//              ::= cc <type> <expression>                               # const_cast<type> (expression)
4907
//              ::= rc <type> <expression>                               # reinterpret_cast<type> (expression)
4908
//              ::= st <type>                                            # sizeof (a type)
4909
//              ::= sz <expression>                                      # sizeof (an expression)
4910
//              ::= at <type>                                            # alignof (a type)
4911
//              ::= az <expression>                                      # alignof (an expression)
4912
//              ::= nx <expression>                                      # noexcept (expression)
4913
//              ::= <template-param>
4914
//              ::= <function-param>
4915
//              ::= dt <expression> <unresolved-name>                    # expr.name
4916
//              ::= pt <expression> <unresolved-name>                    # expr->name
4917
//              ::= ds <expression> <expression>                         # expr.*expr
4918
//              ::= sZ <template-param>                                  # size of a parameter pack
4919
//              ::= sZ <function-param>                                  # size of a function parameter pack
4920
//              ::= sP <template-arg>* E                                 # sizeof...(T), size of a captured template parameter pack from an alias template
4921
//              ::= sp <expression>                                      # pack expansion
4922
//              ::= tw <expression>                                      # throw expression
4923
//              ::= tr                                                   # throw with no operand (rethrow)
4924
//              ::= <unresolved-name>                                    # f(p), N::f(p), ::f(p),
4925
//                                                                       # freestanding dependent name (e.g., T::x),
4926
//                                                                       # objectless nonstatic member reference
4927
//              ::= fL <binary-operator-name> <expression> <expression>
4928
//              ::= fR <binary-operator-name> <expression> <expression>
4929
//              ::= fl <binary-operator-name> <expression>
4930
//              ::= fr <binary-operator-name> <expression>
4931
//              ::= <expr-primary>
4932
template <typename Derived, typename Alloc>
4933
0
Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
4934
0
  bool Global = consumeIf("gs");
4935
4936
0
  const auto *Op = parseOperatorEncoding();
4937
0
  if (Op) {
4938
0
    auto Sym = Op->getSymbol();
4939
0
    switch (Op->getKind()) {
4940
0
    case OperatorInfo::Binary:
4941
      // Binary operator: lhs @ rhs
4942
0
      return getDerived().parseBinaryExpr(Sym, Op->getPrecedence());
4943
0
    case OperatorInfo::Prefix:
4944
      // Prefix unary operator: @ expr
4945
0
      return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
4946
0
    case OperatorInfo::Postfix: {
4947
      // Postfix unary operator: expr @
4948
0
      if (consumeIf('_'))
4949
0
        return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
4950
0
      Node *Ex = getDerived().parseExpr();
4951
0
      if (Ex == nullptr)
4952
0
        return nullptr;
4953
0
      return make<PostfixExpr>(Ex, Sym, Op->getPrecedence());
4954
0
    }
4955
0
    case OperatorInfo::Array: {
4956
      // Array Index:  lhs [ rhs ]
4957
0
      Node *Base = getDerived().parseExpr();
4958
0
      if (Base == nullptr)
4959
0
        return nullptr;
4960
0
      Node *Index = getDerived().parseExpr();
4961
0
      if (Index == nullptr)
4962
0
        return nullptr;
4963
0
      return make<ArraySubscriptExpr>(Base, Index, Op->getPrecedence());
4964
0
    }
4965
0
    case OperatorInfo::Member: {
4966
      // Member access lhs @ rhs
4967
0
      Node *LHS = getDerived().parseExpr();
4968
0
      if (LHS == nullptr)
4969
0
        return nullptr;
4970
0
      Node *RHS = getDerived().parseExpr();
4971
0
      if (RHS == nullptr)
4972
0
        return nullptr;
4973
0
      return make<MemberExpr>(LHS, Sym, RHS, Op->getPrecedence());
4974
0
    }
4975
0
    case OperatorInfo::New: {
4976
      // New
4977
      // # new (expr-list) type [(init)]
4978
      // [gs] nw <expression>* _ <type> [pi <expression>*] E
4979
      // # new[] (expr-list) type [(init)]
4980
      // [gs] na <expression>* _ <type> [pi <expression>*] E
4981
0
      size_t Exprs = Names.size();
4982
0
      while (!consumeIf('_')) {
4983
0
        Node *Ex = getDerived().parseExpr();
4984
0
        if (Ex == nullptr)
4985
0
          return nullptr;
4986
0
        Names.push_back(Ex);
4987
0
      }
4988
0
      NodeArray ExprList = popTrailingNodeArray(Exprs);
4989
0
      Node *Ty = getDerived().parseType();
4990
0
      if (Ty == nullptr)
4991
0
        return nullptr;
4992
0
      bool HaveInits = consumeIf("pi");
4993
0
      size_t InitsBegin = Names.size();
4994
0
      while (!consumeIf('E')) {
4995
0
        if (!HaveInits)
4996
0
          return nullptr;
4997
0
        Node *Init = getDerived().parseExpr();
4998
0
        if (Init == nullptr)
4999
0
          return Init;
5000
0
        Names.push_back(Init);
5001
0
      }
5002
0
      NodeArray Inits = popTrailingNodeArray(InitsBegin);
5003
0
      return make<NewExpr>(ExprList, Ty, Inits, Global,
5004
0
                           /*IsArray=*/Op->getFlag(), Op->getPrecedence());
5005
0
    }
5006
0
    case OperatorInfo::Del: {
5007
      // Delete
5008
0
      Node *Ex = getDerived().parseExpr();
5009
0
      if (Ex == nullptr)
5010
0
        return nullptr;
5011
0
      return make<DeleteExpr>(Ex, Global, /*IsArray=*/Op->getFlag(),
5012
0
                              Op->getPrecedence());
5013
0
    }
5014
0
    case OperatorInfo::Call: {
5015
      // Function Call
5016
0
      Node *Callee = getDerived().parseExpr();
5017
0
      if (Callee == nullptr)
5018
0
        return nullptr;
5019
0
      size_t ExprsBegin = Names.size();
5020
0
      while (!consumeIf('E')) {
5021
0
        Node *E = getDerived().parseExpr();
5022
0
        if (E == nullptr)
5023
0
          return nullptr;
5024
0
        Names.push_back(E);
5025
0
      }
5026
0
      return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
5027
0
                            Op->getPrecedence());
5028
0
    }
5029
0
    case OperatorInfo::CCast: {
5030
      // C Cast: (type)expr
5031
0
      Node *Ty;
5032
0
      {
5033
0
        ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
5034
0
        Ty = getDerived().parseType();
5035
0
      }
5036
0
      if (Ty == nullptr)
5037
0
        return nullptr;
5038
5039
0
      size_t ExprsBegin = Names.size();
5040
0
      bool IsMany = consumeIf('_');
5041
0
      while (!consumeIf('E')) {
5042
0
        Node *E = getDerived().parseExpr();
5043
0
        if (E == nullptr)
5044
0
          return E;
5045
0
        Names.push_back(E);
5046
0
        if (!IsMany)
5047
0
          break;
5048
0
      }
5049
0
      NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
5050
0
      if (!IsMany && Exprs.size() != 1)
5051
0
        return nullptr;
5052
0
      return make<ConversionExpr>(Ty, Exprs, Op->getPrecedence());
5053
0
    }
5054
0
    case OperatorInfo::Conditional: {
5055
      // Conditional operator: expr ? expr : expr
5056
0
      Node *Cond = getDerived().parseExpr();
5057
0
      if (Cond == nullptr)
5058
0
        return nullptr;
5059
0
      Node *LHS = getDerived().parseExpr();
5060
0
      if (LHS == nullptr)
5061
0
        return nullptr;
5062
0
      Node *RHS = getDerived().parseExpr();
5063
0
      if (RHS == nullptr)
5064
0
        return nullptr;
5065
0
      return make<ConditionalExpr>(Cond, LHS, RHS, Op->getPrecedence());
5066
0
    }
5067
0
    case OperatorInfo::NamedCast: {
5068
      // Named cast operation, @<type>(expr)
5069
0
      Node *Ty = getDerived().parseType();
5070
0
      if (Ty == nullptr)
5071
0
        return nullptr;
5072
0
      Node *Ex = getDerived().parseExpr();
5073
0
      if (Ex == nullptr)
5074
0
        return nullptr;
5075
0
      return make<CastExpr>(Sym, Ty, Ex, Op->getPrecedence());
5076
0
    }
5077
0
    case OperatorInfo::OfIdOp: {
5078
      // [sizeof/alignof/typeid] ( <type>|<expr> )
5079
0
      Node *Arg =
5080
0
          Op->getFlag() ? getDerived().parseType() : getDerived().parseExpr();
5081
0
      if (!Arg)
5082
0
        return nullptr;
5083
0
      return make<EnclosingExpr>(Sym, Arg, Op->getPrecedence());
5084
0
    }
5085
0
    case OperatorInfo::NameOnly: {
5086
      // Not valid as an expression operand.
5087
0
      return nullptr;
5088
0
    }
5089
0
    }
5090
0
    DEMANGLE_UNREACHABLE;
5091
0
  }
5092
5093
0
  if (numLeft() < 2)
5094
0
    return nullptr;
5095
5096
0
  if (look() == 'L')
5097
0
    return getDerived().parseExprPrimary();
5098
0
  if (look() == 'T')
5099
0
    return getDerived().parseTemplateParam();
5100
0
  if (look() == 'f') {
5101
    // Disambiguate a fold expression from a <function-param>.
5102
0
    if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
5103
0
      return getDerived().parseFunctionParam();
5104
0
    return getDerived().parseFoldExpr();
5105
0
  }
5106
0
  if (consumeIf("il")) {
5107
0
    size_t InitsBegin = Names.size();
5108
0
    while (!consumeIf('E')) {
5109
0
      Node *E = getDerived().parseBracedExpr();
5110
0
      if (E == nullptr)
5111
0
        return nullptr;
5112
0
      Names.push_back(E);
5113
0
    }
5114
0
    return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
5115
0
  }
5116
0
  if (consumeIf("mc"))
5117
0
    return parsePointerToMemberConversionExpr(Node::Prec::Unary);
5118
0
  if (consumeIf("nx")) {
5119
0
    Node *Ex = getDerived().parseExpr();
5120
0
    if (Ex == nullptr)
5121
0
      return Ex;
5122
0
    return make<EnclosingExpr>("noexcept ", Ex, Node::Prec::Unary);
5123
0
  }
5124
0
  if (look() == 'r' && (look(1) == 'q' || look(1) == 'Q'))
5125
0
    return parseRequiresExpr();
5126
0
  if (consumeIf("so"))
5127
0
    return parseSubobjectExpr();
5128
0
  if (consumeIf("sp")) {
5129
0
    Node *Child = getDerived().parseExpr();
5130
0
    if (Child == nullptr)
5131
0
      return nullptr;
5132
0
    return make<ParameterPackExpansion>(Child);
5133
0
  }
5134
0
  if (consumeIf("sZ")) {
5135
0
    if (look() == 'T') {
5136
0
      Node *R = getDerived().parseTemplateParam();
5137
0
      if (R == nullptr)
5138
0
        return nullptr;
5139
0
      return make<SizeofParamPackExpr>(R);
5140
0
    }
5141
0
    Node *FP = getDerived().parseFunctionParam();
5142
0
    if (FP == nullptr)
5143
0
      return nullptr;
5144
0
    return make<EnclosingExpr>("sizeof... ", FP);
5145
0
  }
5146
0
  if (consumeIf("sP")) {
5147
0
    size_t ArgsBegin = Names.size();
5148
0
    while (!consumeIf('E')) {
5149
0
      Node *Arg = getDerived().parseTemplateArg();
5150
0
      if (Arg == nullptr)
5151
0
        return nullptr;
5152
0
      Names.push_back(Arg);
5153
0
    }
5154
0
    auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
5155
0
    if (!Pack)
5156
0
      return nullptr;
5157
0
    return make<EnclosingExpr>("sizeof... ", Pack);
5158
0
  }
5159
0
  if (consumeIf("tl")) {
5160
0
    Node *Ty = getDerived().parseType();
5161
0
    if (Ty == nullptr)
5162
0
      return nullptr;
5163
0
    size_t InitsBegin = Names.size();
5164
0
    while (!consumeIf('E')) {
5165
0
      Node *E = getDerived().parseBracedExpr();
5166
0
      if (E == nullptr)
5167
0
        return nullptr;
5168
0
      Names.push_back(E);
5169
0
    }
5170
0
    return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
5171
0
  }
5172
0
  if (consumeIf("tr"))
5173
0
    return make<NameType>("throw");
5174
0
  if (consumeIf("tw")) {
5175
0
    Node *Ex = getDerived().parseExpr();
5176
0
    if (Ex == nullptr)
5177
0
      return nullptr;
5178
0
    return make<ThrowExpr>(Ex);
5179
0
  }
5180
0
  if (consumeIf('u')) {
5181
0
    Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
5182
0
    if (!Name)
5183
0
      return nullptr;
5184
    // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
5185
    // standard encoding expects a <template-arg>, and would be otherwise be
5186
    // interpreted as <type> node 'short' or 'ellipsis'. However, neither
5187
    // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
5188
    // actual conflict here.
5189
0
    bool IsUUID = false;
5190
0
    Node *UUID = nullptr;
5191
0
    if (Name->getBaseName() == "__uuidof") {
5192
0
      if (consumeIf('t')) {
5193
0
        UUID = getDerived().parseType();
5194
0
        IsUUID = true;
5195
0
      } else if (consumeIf('z')) {
5196
0
        UUID = getDerived().parseExpr();
5197
0
        IsUUID = true;
5198
0
      }
5199
0
    }
5200
0
    size_t ExprsBegin = Names.size();
5201
0
    if (IsUUID) {
5202
0
      if (UUID == nullptr)
5203
0
        return nullptr;
5204
0
      Names.push_back(UUID);
5205
0
    } else {
5206
0
      while (!consumeIf('E')) {
5207
0
        Node *E = getDerived().parseTemplateArg();
5208
0
        if (E == nullptr)
5209
0
          return E;
5210
0
        Names.push_back(E);
5211
0
      }
5212
0
    }
5213
0
    return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
5214
0
                          Node::Prec::Postfix);
5215
0
  }
5216
5217
  // Only unresolved names remain.
5218
0
  return getDerived().parseUnresolvedName(Global);
5219
0
}
5220
5221
// <call-offset> ::= h <nv-offset> _
5222
//               ::= v <v-offset> _
5223
//
5224
// <nv-offset> ::= <offset number>
5225
//               # non-virtual base override
5226
//
5227
// <v-offset>  ::= <offset number> _ <virtual offset number>
5228
//               # virtual base override, with vcall offset
5229
template <typename Alloc, typename Derived>
5230
0
bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() {
5231
  // Just scan through the call offset, we never add this information into the
5232
  // output.
5233
0
  if (consumeIf('h'))
5234
0
    return parseNumber(true).empty() || !consumeIf('_');
5235
0
  if (consumeIf('v'))
5236
0
    return parseNumber(true).empty() || !consumeIf('_') ||
5237
0
           parseNumber(true).empty() || !consumeIf('_');
5238
0
  return true;
5239
0
}
5240
5241
// <special-name> ::= TV <type>    # virtual table
5242
//                ::= TT <type>    # VTT structure (construction vtable index)
5243
//                ::= TI <type>    # typeinfo structure
5244
//                ::= TS <type>    # typeinfo name (null-terminated byte string)
5245
//                ::= Tc <call-offset> <call-offset> <base encoding>
5246
//                    # base is the nominal target function of thunk
5247
//                    # first call-offset is 'this' adjustment
5248
//                    # second call-offset is result adjustment
5249
//                ::= T <call-offset> <base encoding>
5250
//                    # base is the nominal target function of thunk
5251
//                # Guard variable for one-time initialization
5252
//                ::= GV <object name>
5253
//                                     # No <type>
5254
//                ::= TW <object name> # Thread-local wrapper
5255
//                ::= TH <object name> # Thread-local initialization
5256
//                ::= GR <object name> _             # First temporary
5257
//                ::= GR <object name> <seq-id> _    # Subsequent temporaries
5258
//                # construction vtable for second-in-first
5259
//      extension ::= TC <first type> <number> _ <second type>
5260
//      extension ::= GR <object name> # reference temporary for object
5261
//      extension ::= GI <module name> # module global initializer
5262
template <typename Derived, typename Alloc>
5263
0
Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
5264
0
  switch (look()) {
5265
0
  case 'T':
5266
0
    switch (look(1)) {
5267
    // TA <template-arg>    # template parameter object
5268
    //
5269
    // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
5270
0
    case 'A': {
5271
0
      First += 2;
5272
0
      Node *Arg = getDerived().parseTemplateArg();
5273
0
      if (Arg == nullptr)
5274
0
        return nullptr;
5275
0
      return make<SpecialName>("template parameter object for ", Arg);
5276
0
    }
5277
    // TV <type>    # virtual table
5278
0
    case 'V': {
5279
0
      First += 2;
5280
0
      Node *Ty = getDerived().parseType();
5281
0
      if (Ty == nullptr)
5282
0
        return nullptr;
5283
0
      return make<SpecialName>("vtable for ", Ty);
5284
0
    }
5285
    // TT <type>    # VTT structure (construction vtable index)
5286
0
    case 'T': {
5287
0
      First += 2;
5288
0
      Node *Ty = getDerived().parseType();
5289
0
      if (Ty == nullptr)
5290
0
        return nullptr;
5291
0
      return make<SpecialName>("VTT for ", Ty);
5292
0
    }
5293
    // TI <type>    # typeinfo structure
5294
0
    case 'I': {
5295
0
      First += 2;
5296
0
      Node *Ty = getDerived().parseType();
5297
0
      if (Ty == nullptr)
5298
0
        return nullptr;
5299
0
      return make<SpecialName>("typeinfo for ", Ty);
5300
0
    }
5301
    // TS <type>    # typeinfo name (null-terminated byte string)
5302
0
    case 'S': {
5303
0
      First += 2;
5304
0
      Node *Ty = getDerived().parseType();
5305
0
      if (Ty == nullptr)
5306
0
        return nullptr;
5307
0
      return make<SpecialName>("typeinfo name for ", Ty);
5308
0
    }
5309
    // Tc <call-offset> <call-offset> <base encoding>
5310
0
    case 'c': {
5311
0
      First += 2;
5312
0
      if (parseCallOffset() || parseCallOffset())
5313
0
        return nullptr;
5314
0
      Node *Encoding = getDerived().parseEncoding();
5315
0
      if (Encoding == nullptr)
5316
0
        return nullptr;
5317
0
      return make<SpecialName>("covariant return thunk to ", Encoding);
5318
0
    }
5319
    // extension ::= TC <first type> <number> _ <second type>
5320
    //               # construction vtable for second-in-first
5321
0
    case 'C': {
5322
0
      First += 2;
5323
0
      Node *FirstType = getDerived().parseType();
5324
0
      if (FirstType == nullptr)
5325
0
        return nullptr;
5326
0
      if (parseNumber(true).empty() || !consumeIf('_'))
5327
0
        return nullptr;
5328
0
      Node *SecondType = getDerived().parseType();
5329
0
      if (SecondType == nullptr)
5330
0
        return nullptr;
5331
0
      return make<CtorVtableSpecialName>(SecondType, FirstType);
5332
0
    }
5333
    // TW <object name> # Thread-local wrapper
5334
0
    case 'W': {
5335
0
      First += 2;
5336
0
      Node *Name = getDerived().parseName();
5337
0
      if (Name == nullptr)
5338
0
        return nullptr;
5339
0
      return make<SpecialName>("thread-local wrapper routine for ", Name);
5340
0
    }
5341
    // TH <object name> # Thread-local initialization
5342
0
    case 'H': {
5343
0
      First += 2;
5344
0
      Node *Name = getDerived().parseName();
5345
0
      if (Name == nullptr)
5346
0
        return nullptr;
5347
0
      return make<SpecialName>("thread-local initialization routine for ", Name);
5348
0
    }
5349
    // T <call-offset> <base encoding>
5350
0
    default: {
5351
0
      ++First;
5352
0
      bool IsVirt = look() == 'v';
5353
0
      if (parseCallOffset())
5354
0
        return nullptr;
5355
0
      Node *BaseEncoding = getDerived().parseEncoding();
5356
0
      if (BaseEncoding == nullptr)
5357
0
        return nullptr;
5358
0
      if (IsVirt)
5359
0
        return make<SpecialName>("virtual thunk to ", BaseEncoding);
5360
0
      else
5361
0
        return make<SpecialName>("non-virtual thunk to ", BaseEncoding);
5362
0
    }
5363
0
    }
5364
0
  case 'G':
5365
0
    switch (look(1)) {
5366
    // GV <object name> # Guard variable for one-time initialization
5367
0
    case 'V': {
5368
0
      First += 2;
5369
0
      Node *Name = getDerived().parseName();
5370
0
      if (Name == nullptr)
5371
0
        return nullptr;
5372
0
      return make<SpecialName>("guard variable for ", Name);
5373
0
    }
5374
    // GR <object name> # reference temporary for object
5375
    // GR <object name> _             # First temporary
5376
    // GR <object name> <seq-id> _    # Subsequent temporaries
5377
0
    case 'R': {
5378
0
      First += 2;
5379
0
      Node *Name = getDerived().parseName();
5380
0
      if (Name == nullptr)
5381
0
        return nullptr;
5382
0
      size_t Count;
5383
0
      bool ParsedSeqId = !parseSeqId(&Count);
5384
0
      if (!consumeIf('_') && ParsedSeqId)
5385
0
        return nullptr;
5386
0
      return make<SpecialName>("reference temporary for ", Name);
5387
0
    }
5388
    // GI <module-name> v
5389
0
    case 'I': {
5390
0
      First += 2;
5391
0
      ModuleName *Module = nullptr;
5392
0
      if (getDerived().parseModuleNameOpt(Module))
5393
0
        return nullptr;
5394
0
      if (Module == nullptr)
5395
0
        return nullptr;
5396
0
      return make<SpecialName>("initializer for module ", Module);
5397
0
    }
5398
0
    }
5399
0
  }
5400
0
  return nullptr;
5401
0
}
5402
5403
// <encoding> ::= <function name> <bare-function-type>
5404
//                    [`Q` <requires-clause expr>]
5405
//            ::= <data name>
5406
//            ::= <special-name>
5407
template <typename Derived, typename Alloc>
5408
0
Node *AbstractManglingParser<Derived, Alloc>::parseEncoding(bool ParseParams) {
5409
  // The template parameters of an encoding are unrelated to those of the
5410
  // enclosing context.
5411
0
  SaveTemplateParams SaveTemplateParamsScope(this);
5412
5413
0
  if (look() == 'G' || look() == 'T')
5414
0
    return getDerived().parseSpecialName();
5415
5416
0
  auto IsEndOfEncoding = [&] {
5417
    // The set of chars that can potentially follow an <encoding> (none of which
5418
    // can start a <type>). Enumerating these allows us to avoid speculative
5419
    // parsing.
5420
0
    return numLeft() == 0 || look() == 'E' || look() == '.' || look() == '_';
5421
0
  };
5422
5423
0
  NameState NameInfo(this);
5424
0
  Node *Name = getDerived().parseName(&NameInfo);
5425
0
  if (Name == nullptr)
5426
0
    return nullptr;
5427
5428
0
  if (resolveForwardTemplateRefs(NameInfo))
5429
0
    return nullptr;
5430
5431
0
  if (IsEndOfEncoding())
5432
0
    return Name;
5433
5434
  // ParseParams may be false at the top level only, when called from parse().
5435
  // For example in the mangled name _Z3fooILZ3BarEET_f, ParseParams may be
5436
  // false when demangling 3fooILZ3BarEET_f but is always true when demangling
5437
  // 3Bar.
5438
0
  if (!ParseParams) {
5439
0
    while (consume())
5440
0
      ;
5441
0
    return Name;
5442
0
  }
5443
5444
0
  Node *Attrs = nullptr;
5445
0
  if (consumeIf("Ua9enable_ifI")) {
5446
0
    size_t BeforeArgs = Names.size();
5447
0
    while (!consumeIf('E')) {
5448
0
      Node *Arg = getDerived().parseTemplateArg();
5449
0
      if (Arg == nullptr)
5450
0
        return nullptr;
5451
0
      Names.push_back(Arg);
5452
0
    }
5453
0
    Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
5454
0
    if (!Attrs)
5455
0
      return nullptr;
5456
0
  }
5457
5458
0
  Node *ReturnType = nullptr;
5459
0
  if (!NameInfo.CtorDtorConversion && NameInfo.EndsWithTemplateArgs) {
5460
0
    ReturnType = getDerived().parseType();
5461
0
    if (ReturnType == nullptr)
5462
0
      return nullptr;
5463
0
  }
5464
5465
0
  NodeArray Params;
5466
0
  if (!consumeIf('v')) {
5467
0
    size_t ParamsBegin = Names.size();
5468
0
    do {
5469
0
      Node *Ty = getDerived().parseType();
5470
0
      if (Ty == nullptr)
5471
0
        return nullptr;
5472
5473
0
      const bool IsFirstParam = ParamsBegin == Names.size();
5474
0
      if (NameInfo.HasExplicitObjectParameter && IsFirstParam)
5475
0
        Ty = make<ExplicitObjectParameter>(Ty);
5476
5477
0
      if (Ty == nullptr)
5478
0
        return nullptr;
5479
5480
0
      Names.push_back(Ty);
5481
0
    } while (!IsEndOfEncoding() && look() != 'Q');
5482
0
    Params = popTrailingNodeArray(ParamsBegin);
5483
0
  }
5484
5485
0
  Node *Requires = nullptr;
5486
0
  if (consumeIf('Q')) {
5487
0
    Requires = getDerived().parseConstraintExpr();
5488
0
    if (!Requires)
5489
0
      return nullptr;
5490
0
  }
5491
5492
0
  return make<FunctionEncoding>(ReturnType, Name, Params, Attrs, Requires,
5493
0
                                NameInfo.CVQualifiers,
5494
0
                                NameInfo.ReferenceQualifier);
5495
0
}
5496
5497
template <class Float>
5498
struct FloatData;
5499
5500
template <>
5501
struct FloatData<float>
5502
{
5503
    static const size_t mangled_size = 8;
5504
    static const size_t max_demangled_size = 24;
5505
    static constexpr const char* spec = "%af";
5506
};
5507
5508
template <>
5509
struct FloatData<double>
5510
{
5511
    static const size_t mangled_size = 16;
5512
    static const size_t max_demangled_size = 32;
5513
    static constexpr const char* spec = "%a";
5514
};
5515
5516
template <>
5517
struct FloatData<long double>
5518
{
5519
#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
5520
    defined(__wasm__) || defined(__riscv) || defined(__loongarch__) || \
5521
    defined(__ve__)
5522
    static const size_t mangled_size = 32;
5523
#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
5524
    static const size_t mangled_size = 16;
5525
#else
5526
    static const size_t mangled_size = 20;  // May need to be adjusted to 16 or 24 on other platforms
5527
#endif
5528
    // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
5529
    // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
5530
    // Negatives are one character longer than positives.
5531
    // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
5532
    // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
5533
    static const size_t max_demangled_size = 42;
5534
    static constexpr const char *spec = "%LaL";
5535
};
5536
5537
template <typename Alloc, typename Derived>
5538
template <class Float>
5539
0
Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
5540
0
  const size_t N = FloatData<Float>::mangled_size;
5541
0
  if (numLeft() <= N)
5542
0
    return nullptr;
5543
0
  std::string_view Data(First, N);
5544
0
  for (char C : Data)
5545
0
    if (!std::isxdigit(C))
5546
0
      return nullptr;
5547
0
  First += N;
5548
0
  if (!consumeIf('E'))
5549
0
    return nullptr;
5550
0
  return make<FloatLiteralImpl<Float>>(Data);
5551
0
}
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::parseFloatingLiteral<float>()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::parseFloatingLiteral<double>()
Unexecuted instantiation: cxa_demangle.cpp:(anonymous namespace)::itanium_demangle::Node* (anonymous namespace)::itanium_demangle::AbstractManglingParser<(anonymous namespace)::itanium_demangle::ManglingParser<(anonymous namespace)::DefaultAllocator>, (anonymous namespace)::DefaultAllocator>::parseFloatingLiteral<long double>()
5552
5553
// <seq-id> ::= <0-9A-Z>+
5554
template <typename Alloc, typename Derived>
5555
0
bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) {
5556
0
  if (!(look() >= '0' && look() <= '9') &&
5557
0
      !(look() >= 'A' && look() <= 'Z'))
5558
0
    return true;
5559
5560
0
  size_t Id = 0;
5561
0
  while (true) {
5562
0
    if (look() >= '0' && look() <= '9') {
5563
0
      Id *= 36;
5564
0
      Id += static_cast<size_t>(look() - '0');
5565
0
    } else if (look() >= 'A' && look() <= 'Z') {
5566
0
      Id *= 36;
5567
0
      Id += static_cast<size_t>(look() - 'A') + 10;
5568
0
    } else {
5569
0
      *Out = Id;
5570
0
      return false;
5571
0
    }
5572
0
    ++First;
5573
0
  }
5574
0
}
5575
5576
// <substitution> ::= S <seq-id> _
5577
//                ::= S_
5578
// <substitution> ::= Sa # ::std::allocator
5579
// <substitution> ::= Sb # ::std::basic_string
5580
// <substitution> ::= Ss # ::std::basic_string < char,
5581
//                                               ::std::char_traits<char>,
5582
//                                               ::std::allocator<char> >
5583
// <substitution> ::= Si # ::std::basic_istream<char,  std::char_traits<char> >
5584
// <substitution> ::= So # ::std::basic_ostream<char,  std::char_traits<char> >
5585
// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
5586
// The St case is handled specially in parseNestedName.
5587
template <typename Derived, typename Alloc>
5588
0
Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() {
5589
0
  if (!consumeIf('S'))
5590
0
    return nullptr;
5591
5592
0
  if (look() >= 'a' && look() <= 'z') {
5593
0
    SpecialSubKind Kind;
5594
0
    switch (look()) {
5595
0
    case 'a':
5596
0
      Kind = SpecialSubKind::allocator;
5597
0
      break;
5598
0
    case 'b':
5599
0
      Kind = SpecialSubKind::basic_string;
5600
0
      break;
5601
0
    case 'd':
5602
0
      Kind = SpecialSubKind::iostream;
5603
0
      break;
5604
0
    case 'i':
5605
0
      Kind = SpecialSubKind::istream;
5606
0
      break;
5607
0
    case 'o':
5608
0
      Kind = SpecialSubKind::ostream;
5609
0
      break;
5610
0
    case 's':
5611
0
      Kind = SpecialSubKind::string;
5612
0
      break;
5613
0
    default:
5614
0
      return nullptr;
5615
0
    }
5616
0
    ++First;
5617
0
    auto *SpecialSub = make<SpecialSubstitution>(Kind);
5618
0
    if (!SpecialSub)
5619
0
      return nullptr;
5620
5621
    // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
5622
    // has ABI tags, the tags are appended to the substitution; the result is a
5623
    // substitutable component.
5624
0
    Node *WithTags = getDerived().parseAbiTags(SpecialSub);
5625
0
    if (WithTags != SpecialSub) {
5626
0
      Subs.push_back(WithTags);
5627
0
      SpecialSub = WithTags;
5628
0
    }
5629
0
    return SpecialSub;
5630
0
  }
5631
5632
  //                ::= S_
5633
0
  if (consumeIf('_')) {
5634
0
    if (Subs.empty())
5635
0
      return nullptr;
5636
0
    return Subs[0];
5637
0
  }
5638
5639
  //                ::= S <seq-id> _
5640
0
  size_t Index = 0;
5641
0
  if (parseSeqId(&Index))
5642
0
    return nullptr;
5643
0
  ++Index;
5644
0
  if (!consumeIf('_') || Index >= Subs.size())
5645
0
    return nullptr;
5646
0
  return Subs[Index];
5647
0
}
5648
5649
// <template-param> ::= T_    # first template parameter
5650
//                  ::= T <parameter-2 non-negative number> _
5651
//                  ::= TL <level-1> __
5652
//                  ::= TL <level-1> _ <parameter-2 non-negative number> _
5653
template <typename Derived, typename Alloc>
5654
0
Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
5655
0
  const char *Begin = First;
5656
0
  if (!consumeIf('T'))
5657
0
    return nullptr;
5658
5659
0
  size_t Level = 0;
5660
0
  if (consumeIf('L')) {
5661
0
    if (parsePositiveInteger(&Level))
5662
0
      return nullptr;
5663
0
    ++Level;
5664
0
    if (!consumeIf('_'))
5665
0
      return nullptr;
5666
0
  }
5667
5668
0
  size_t Index = 0;
5669
0
  if (!consumeIf('_')) {
5670
0
    if (parsePositiveInteger(&Index))
5671
0
      return nullptr;
5672
0
    ++Index;
5673
0
    if (!consumeIf('_'))
5674
0
      return nullptr;
5675
0
  }
5676
5677
  // We don't track enclosing template parameter levels well enough to reliably
5678
  // substitute them all within a <constraint-expression>, so print the
5679
  // parameter numbering instead for now.
5680
  // TODO: Track all enclosing template parameters and substitute them here.
5681
0
  if (InConstraintExpr) {
5682
0
    return make<NameType>(std::string_view(Begin, First - 1 - Begin));
5683
0
  }
5684
5685
  // If we're in a context where this <template-param> refers to a
5686
  // <template-arg> further ahead in the mangled name (currently just conversion
5687
  // operator types), then we should only look it up in the right context.
5688
  // This can only happen at the outermost level.
5689
0
  if (PermitForwardTemplateReferences && Level == 0) {
5690
0
    Node *ForwardRef = make<ForwardTemplateReference>(Index);
5691
0
    if (!ForwardRef)
5692
0
      return nullptr;
5693
0
    DEMANGLE_ASSERT(ForwardRef->getKind() == Node::KForwardTemplateReference,
5694
0
                    "");
5695
0
    ForwardTemplateRefs.push_back(
5696
0
        static_cast<ForwardTemplateReference *>(ForwardRef));
5697
0
    return ForwardRef;
5698
0
  }
5699
5700
0
  if (Level >= TemplateParams.size() || !TemplateParams[Level] ||
5701
0
      Index >= TemplateParams[Level]->size()) {
5702
    // Itanium ABI 5.1.8: In a generic lambda, uses of auto in the parameter
5703
    // list are mangled as the corresponding artificial template type parameter.
5704
0
    if (ParsingLambdaParamsAtLevel == Level && Level <= TemplateParams.size()) {
5705
      // This will be popped by the ScopedTemplateParamList in
5706
      // parseUnnamedTypeName.
5707
0
      if (Level == TemplateParams.size())
5708
0
        TemplateParams.push_back(nullptr);
5709
0
      return make<NameType>("auto");
5710
0
    }
5711
5712
0
    return nullptr;
5713
0
  }
5714
5715
0
  return (*TemplateParams[Level])[Index];
5716
0
}
5717
5718
// <template-param-decl> ::= Ty                          # type parameter
5719
//                       ::= Tn <type>                   # non-type parameter
5720
//                       ::= Tt <template-param-decl>* E # template parameter
5721
//                       ::= Tp <template-param-decl>    # parameter pack
5722
template <typename Derived, typename Alloc>
5723
Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
5724
0
    TemplateParamList *Params) {
5725
0
  auto InventTemplateParamName = [&](TemplateParamKind Kind) {
5726
0
    unsigned Index = NumSyntheticTemplateParameters[(int)Kind]++;
5727
0
    Node *N = make<SyntheticTemplateParamName>(Kind, Index);
5728
0
    if (N && Params)
5729
0
      Params->push_back(N);
5730
0
    return N;
5731
0
  };
5732
5733
0
  if (consumeIf("Ty")) {
5734
0
    Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5735
0
    if (!Name)
5736
0
      return nullptr;
5737
0
    return make<TypeTemplateParamDecl>(Name);
5738
0
  }
5739
5740
0
  if (consumeIf("Tk")) {
5741
0
    Node *Constraint = getDerived().parseName();
5742
0
    if (!Constraint)
5743
0
      return nullptr;
5744
0
    Node *Name = InventTemplateParamName(TemplateParamKind::Type);
5745
0
    if (!Name)
5746
0
      return nullptr;
5747
0
    return make<ConstrainedTypeTemplateParamDecl>(Constraint, Name);
5748
0
  }
5749
5750
0
  if (consumeIf("Tn")) {
5751
0
    Node *Name = InventTemplateParamName(TemplateParamKind::NonType);
5752
0
    if (!Name)
5753
0
      return nullptr;
5754
0
    Node *Type = parseType();
5755
0
    if (!Type)
5756
0
      return nullptr;
5757
0
    return make<NonTypeTemplateParamDecl>(Name, Type);
5758
0
  }
5759
5760
0
  if (consumeIf("Tt")) {
5761
0
    Node *Name = InventTemplateParamName(TemplateParamKind::Template);
5762
0
    if (!Name)
5763
0
      return nullptr;
5764
0
    size_t ParamsBegin = Names.size();
5765
0
    ScopedTemplateParamList TemplateTemplateParamParams(this);
5766
0
    Node *Requires = nullptr;
5767
0
    while (!consumeIf('E')) {
5768
0
      Node *P = parseTemplateParamDecl(TemplateTemplateParamParams.params());
5769
0
      if (!P)
5770
0
        return nullptr;
5771
0
      Names.push_back(P);
5772
0
      if (consumeIf('Q')) {
5773
0
        Requires = getDerived().parseConstraintExpr();
5774
0
        if (Requires == nullptr || !consumeIf('E'))
5775
0
          return nullptr;
5776
0
        break;
5777
0
      }
5778
0
    }
5779
0
    NodeArray InnerParams = popTrailingNodeArray(ParamsBegin);
5780
0
    return make<TemplateTemplateParamDecl>(Name, InnerParams, Requires);
5781
0
  }
5782
5783
0
  if (consumeIf("Tp")) {
5784
0
    Node *P = parseTemplateParamDecl(Params);
5785
0
    if (!P)
5786
0
      return nullptr;
5787
0
    return make<TemplateParamPackDecl>(P);
5788
0
  }
5789
5790
0
  return nullptr;
5791
0
}
5792
5793
// <template-arg> ::= <type>                    # type or template
5794
//                ::= X <expression> E          # expression
5795
//                ::= <expr-primary>            # simple expressions
5796
//                ::= J <template-arg>* E       # argument pack
5797
//                ::= LZ <encoding> E           # extension
5798
//                ::= <template-param-decl> <template-arg>
5799
template <typename Derived, typename Alloc>
5800
0
Node *AbstractManglingParser<Derived, Alloc>::parseTemplateArg() {
5801
0
  switch (look()) {
5802
0
  case 'X': {
5803
0
    ++First;
5804
0
    Node *Arg = getDerived().parseExpr();
5805
0
    if (Arg == nullptr || !consumeIf('E'))
5806
0
      return nullptr;
5807
0
    return Arg;
5808
0
  }
5809
0
  case 'J': {
5810
0
    ++First;
5811
0
    size_t ArgsBegin = Names.size();
5812
0
    while (!consumeIf('E')) {
5813
0
      Node *Arg = getDerived().parseTemplateArg();
5814
0
      if (Arg == nullptr)
5815
0
        return nullptr;
5816
0
      Names.push_back(Arg);
5817
0
    }
5818
0
    NodeArray Args = popTrailingNodeArray(ArgsBegin);
5819
0
    return make<TemplateArgumentPack>(Args);
5820
0
  }
5821
0
  case 'L': {
5822
    //                ::= LZ <encoding> E           # extension
5823
0
    if (look(1) == 'Z') {
5824
0
      First += 2;
5825
0
      Node *Arg = getDerived().parseEncoding();
5826
0
      if (Arg == nullptr || !consumeIf('E'))
5827
0
        return nullptr;
5828
0
      return Arg;
5829
0
    }
5830
    //                ::= <expr-primary>            # simple expressions
5831
0
    return getDerived().parseExprPrimary();
5832
0
  }
5833
0
  case 'T': {
5834
    // Either <template-param> or a <template-param-decl> <template-arg>.
5835
0
    if (!getDerived().isTemplateParamDecl())
5836
0
      return getDerived().parseType();
5837
0
    Node *Param = getDerived().parseTemplateParamDecl(nullptr);
5838
0
    if (!Param)
5839
0
      return nullptr;
5840
0
    Node *Arg = getDerived().parseTemplateArg();
5841
0
    if (!Arg)
5842
0
      return nullptr;
5843
0
    return make<TemplateParamQualifiedArg>(Param, Arg);
5844
0
  }
5845
0
  default:
5846
0
    return getDerived().parseType();
5847
0
  }
5848
0
}
5849
5850
// <template-args> ::= I <template-arg>* E
5851
//     extension, the abi says <template-arg>+
5852
template <typename Derived, typename Alloc>
5853
Node *
5854
0
AbstractManglingParser<Derived, Alloc>::parseTemplateArgs(bool TagTemplates) {
5855
0
  if (!consumeIf('I'))
5856
0
    return nullptr;
5857
5858
  // <template-params> refer to the innermost <template-args>. Clear out any
5859
  // outer args that we may have inserted into TemplateParams.
5860
0
  if (TagTemplates) {
5861
0
    TemplateParams.clear();
5862
0
    TemplateParams.push_back(&OuterTemplateParams);
5863
0
    OuterTemplateParams.clear();
5864
0
  }
5865
5866
0
  size_t ArgsBegin = Names.size();
5867
0
  Node *Requires = nullptr;
5868
0
  while (!consumeIf('E')) {
5869
0
    if (TagTemplates) {
5870
0
      Node *Arg = getDerived().parseTemplateArg();
5871
0
      if (Arg == nullptr)
5872
0
        return nullptr;
5873
0
      Names.push_back(Arg);
5874
0
      Node *TableEntry = Arg;
5875
0
      if (Arg->getKind() == Node::KTemplateParamQualifiedArg) {
5876
0
        TableEntry =
5877
0
            static_cast<TemplateParamQualifiedArg *>(TableEntry)->getArg();
5878
0
      }
5879
0
      if (Arg->getKind() == Node::KTemplateArgumentPack) {
5880
0
        TableEntry = make<ParameterPack>(
5881
0
            static_cast<TemplateArgumentPack*>(TableEntry)->getElements());
5882
0
        if (!TableEntry)
5883
0
          return nullptr;
5884
0
      }
5885
0
      OuterTemplateParams.push_back(TableEntry);
5886
0
    } else {
5887
0
      Node *Arg = getDerived().parseTemplateArg();
5888
0
      if (Arg == nullptr)
5889
0
        return nullptr;
5890
0
      Names.push_back(Arg);
5891
0
    }
5892
0
    if (consumeIf('Q')) {
5893
0
      Requires = getDerived().parseConstraintExpr();
5894
0
      if (!Requires || !consumeIf('E'))
5895
0
        return nullptr;
5896
0
      break;
5897
0
    }
5898
0
  }
5899
0
  return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin), Requires);
5900
0
}
5901
5902
// <mangled-name> ::= _Z <encoding>
5903
//                ::= <type>
5904
// extension      ::= ___Z <encoding> _block_invoke
5905
// extension      ::= ___Z <encoding> _block_invoke<decimal-digit>+
5906
// extension      ::= ___Z <encoding> _block_invoke_<decimal-digit>+
5907
template <typename Derived, typename Alloc>
5908
0
Node *AbstractManglingParser<Derived, Alloc>::parse(bool ParseParams) {
5909
0
  if (consumeIf("_Z") || consumeIf("__Z")) {
5910
0
    Node *Encoding = getDerived().parseEncoding(ParseParams);
5911
0
    if (Encoding == nullptr)
5912
0
      return nullptr;
5913
0
    if (look() == '.') {
5914
0
      Encoding =
5915
0
          make<DotSuffix>(Encoding, std::string_view(First, Last - First));
5916
0
      First = Last;
5917
0
    }
5918
0
    if (numLeft() != 0)
5919
0
      return nullptr;
5920
0
    return Encoding;
5921
0
  }
5922
5923
0
  if (consumeIf("___Z") || consumeIf("____Z")) {
5924
0
    Node *Encoding = getDerived().parseEncoding(ParseParams);
5925
0
    if (Encoding == nullptr || !consumeIf("_block_invoke"))
5926
0
      return nullptr;
5927
0
    bool RequireNumber = consumeIf('_');
5928
0
    if (parseNumber().empty() && RequireNumber)
5929
0
      return nullptr;
5930
0
    if (look() == '.')
5931
0
      First = Last;
5932
0
    if (numLeft() != 0)
5933
0
      return nullptr;
5934
0
    return make<SpecialName>("invocation function for block in ", Encoding);
5935
0
  }
5936
5937
0
  Node *Ty = getDerived().parseType();
5938
0
  if (numLeft() != 0)
5939
0
    return nullptr;
5940
0
  return Ty;
5941
0
}
5942
5943
template <typename Alloc>
5944
struct ManglingParser : AbstractManglingParser<ManglingParser<Alloc>, Alloc> {
5945
  using AbstractManglingParser<ManglingParser<Alloc>,
5946
                               Alloc>::AbstractManglingParser;
5947
};
5948
5949
DEMANGLE_NAMESPACE_END
5950
5951
#ifdef _LIBCXXABI_COMPILER_CLANG
5952
#pragma clang diagnostic pop
5953
#endif
5954
5955
#endif // DEMANGLE_ITANIUMDEMANGLE_H