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