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