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)
K(K_)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
hasRHSComponent(OutputStream & S)151 bool hasRHSComponent(OutputStream &S) const {
152 if (RHSComponentCache != Cache::Unknown)
153 return RHSComponentCache == Cache::Yes;
154 return hasRHSComponentSlow(S);
155 }
156
hasArray(OutputStream & S)157 bool hasArray(OutputStream &S) const {
158 if (ArrayCache != Cache::Unknown)
159 return ArrayCache == Cache::Yes;
160 return hasArraySlow(S);
161 }
162
hasFunction(OutputStream & S)163 bool hasFunction(OutputStream &S) const {
164 if (FunctionCache != Cache::Unknown)
165 return FunctionCache == Cache::Yes;
166 return hasFunctionSlow(S);
167 }
168
getKind()169 Kind getKind() const { return K; }
170
hasRHSComponentSlow(OutputStream &)171 virtual bool hasRHSComponentSlow(OutputStream &) const { return false; }
hasArraySlow(OutputStream &)172 virtual bool hasArraySlow(OutputStream &) const { return false; }
hasFunctionSlow(OutputStream &)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.
getSyntaxNode(OutputStream &)177 virtual const Node *getSyntaxNode(OutputStream &) const {
178 return this;
179 }
180
print(OutputStream & S)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.
printRight(OutputStream &)194 virtual void printRight(OutputStream &) const {}
195
getBaseName()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:
NodeArray()211 NodeArray() : Elements(nullptr), NumElements(0) {}
NodeArray(Node ** Elements_,size_t NumElements_)212 NodeArray(Node **Elements_, size_t NumElements_)
213 : Elements(Elements_), NumElements(NumElements_) {}
214
empty()215 bool empty() const { return NumElements == 0; }
size()216 size_t size() const { return NumElements; }
217
begin()218 Node **begin() const { return Elements; }
end()219 Node **end() const { return Elements + NumElements; }
220
221 Node *operator[](size_t Idx) const { return Elements[Idx]; }
222
printWithComma(OutputStream & S)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;
NodeArrayNodeNodeArrayNode246 NodeArrayNode(NodeArray Array_) : Node(KNodeArrayNode), Array(Array_) {}
247
matchNodeArrayNode248 template<typename Fn> void match(Fn F) const { F(Array); }
249
printLeftNodeArrayNode250 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:
DotSuffix(const Node * Prefix_,StringView Suffix_)260 DotSuffix(const Node *Prefix_, StringView Suffix_)
261 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
262
match(Fn F)263 template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
264
printLeft(OutputStream & s)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:
VendorExtQualType(const Node * Ty_,StringView Ext_)278 VendorExtQualType(const Node *Ty_, StringView Ext_)
279 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_) {}
280
match(Fn F)281 template<typename Fn> void match(Fn F) const { F(Ty, Ext); }
282
printLeft(OutputStream & S)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
printQuals(OutputStream & S)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:
QualType(const Node * Child_,Qualifiers Quals_)322 QualType(const Node *Child_, Qualifiers Quals_)
323 : Node(KQualType, Child_->RHSComponentCache,
324 Child_->ArrayCache, Child_->FunctionCache),
325 Quals(Quals_), Child(Child_) {}
326
match(Fn F)327 template<typename Fn> void match(Fn F) const { F(Child, Quals); }
328
hasRHSComponentSlow(OutputStream & S)329 bool hasRHSComponentSlow(OutputStream &S) const override {
330 return Child->hasRHSComponent(S);
331 }
hasArraySlow(OutputStream & S)332 bool hasArraySlow(OutputStream &S) const override {
333 return Child->hasArray(S);
334 }
hasFunctionSlow(OutputStream & S)335 bool hasFunctionSlow(OutputStream &S) const override {
336 return Child->hasFunction(S);
337 }
338
printLeft(OutputStream & S)339 void printLeft(OutputStream &S) const override {
340 Child->printLeft(S);
341 printQuals(S);
342 }
343
printRight(OutputStream & S)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:
ConversionOperatorType(const Node * Ty_)351 ConversionOperatorType(const Node *Ty_)
352 : Node(KConversionOperatorType), Ty(Ty_) {}
353
match(Fn F)354 template<typename Fn> void match(Fn F) const { F(Ty); }
355
printLeft(OutputStream & S)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:
PostfixQualifiedType(Node * Ty_,StringView Postfix_)367 PostfixQualifiedType(Node *Ty_, StringView Postfix_)
368 : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
369
match(Fn F)370 template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
371
printLeft(OutputStream & s)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:
NameType(StringView Name_)382 NameType(StringView Name_) : Node(KNameType), Name(Name_) {}
383
match(Fn F)384 template<typename Fn> void match(Fn F) const { F(Name); }
385
getName()386 StringView getName() const { return Name; }
getBaseName()387 StringView getBaseName() const override { return Name; }
388
printLeft(OutputStream & s)389 void printLeft(OutputStream &s) const override { s += Name; }
390 };
391
392 class ElaboratedTypeSpefType : public Node {
393 StringView Kind;
394 Node *Child;
395 public:
ElaboratedTypeSpefType(StringView Kind_,Node * Child_)396 ElaboratedTypeSpefType(StringView Kind_, Node *Child_)
397 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
398
match(Fn F)399 template<typename Fn> void match(Fn F) const { F(Kind, Child); }
400
printLeft(OutputStream & S)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
AbiTagAttrAbiTagAttr412 AbiTagAttr(Node* Base_, StringView Tag_)
413 : Node(KAbiTagAttr, Base_->RHSComponentCache,
414 Base_->ArrayCache, Base_->FunctionCache),
415 Base(Base_), Tag(Tag_) {}
416
matchAbiTagAttr417 template<typename Fn> void match(Fn F) const { F(Base, Tag); }
418
printLeftAbiTagAttr419 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:
EnableIfAttr(NodeArray Conditions_)430 EnableIfAttr(NodeArray Conditions_)
431 : Node(KEnableIfAttr), Conditions(Conditions_) {}
432
match(Fn F)433 template<typename Fn> void match(Fn F) const { F(Conditions); }
434
printLeft(OutputStream & S)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:
ObjCProtoName(const Node * Ty_,StringView Protocol_)449 ObjCProtoName(const Node *Ty_, StringView Protocol_)
450 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
451
match(Fn F)452 template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
453
isObjCObject()454 bool isObjCObject() const {
455 return Ty->getKind() == KNameType &&
456 static_cast<const NameType *>(Ty)->getName() == "objc_object";
457 }
458
printLeft(OutputStream & S)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:
PointerType(const Node * Pointee_)471 PointerType(const Node *Pointee_)
472 : Node(KPointerType, Pointee_->RHSComponentCache),
473 Pointee(Pointee_) {}
474
match(Fn F)475 template<typename Fn> void match(Fn F) const { F(Pointee); }
476
hasRHSComponentSlow(OutputStream & S)477 bool hasRHSComponentSlow(OutputStream &S) const override {
478 return Pointee->hasRHSComponent(S);
479 }
480
printLeft(OutputStream & s)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
printRight(OutputStream & s)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.
collapse(OutputStream & S)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:
ReferenceType(const Node * Pointee_,ReferenceKind RK_)538 ReferenceType(const Node *Pointee_, ReferenceKind RK_)
539 : Node(KReferenceType, Pointee_->RHSComponentCache),
540 Pointee(Pointee_), RK(RK_) {}
541
match(Fn F)542 template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
543
hasRHSComponentSlow(OutputStream & S)544 bool hasRHSComponentSlow(OutputStream &S) const override {
545 return Pointee->hasRHSComponent(S);
546 }
547
printLeft(OutputStream & s)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 }
printRight(OutputStream & s)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:
PointerToMemberType(const Node * ClassType_,const Node * MemberType_)577 PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
578 : Node(KPointerToMemberType, MemberType_->RHSComponentCache),
579 ClassType(ClassType_), MemberType(MemberType_) {}
580
match(Fn F)581 template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
582
hasRHSComponentSlow(OutputStream & S)583 bool hasRHSComponentSlow(OutputStream &S) const override {
584 return MemberType->hasRHSComponent(S);
585 }
586
printLeft(OutputStream & s)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
printRight(OutputStream & s)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:
NodeOrString(StringView Str)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
NodeOrString(Node * N)620 /* implicit */ NodeOrString(Node *N)
621 : First(static_cast<const void *>(N)), Second(nullptr) {}
NodeOrString()622 NodeOrString() : First(nullptr), Second(nullptr) {}
623
isString()624 bool isString() const { return Second && First; }
isNode()625 bool isNode() const { return First && !Second; }
isEmpty()626 bool isEmpty() const { return !First && !Second; }
627
asString()628 StringView asString() const {
629 assert(isString());
630 return StringView(static_cast<const char *>(First),
631 static_cast<const char *>(Second));
632 }
633
asNode()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:
ArrayType(const Node * Base_,NodeOrString Dimension_)645 ArrayType(const Node *Base_, NodeOrString Dimension_)
646 : Node(KArrayType,
647 /*RHSComponentCache=*/Cache::Yes,
648 /*ArrayCache=*/Cache::Yes),
649 Base(Base_), Dimension(Dimension_) {}
650
match(Fn F)651 template<typename Fn> void match(Fn F) const { F(Base, Dimension); }
652
hasRHSComponentSlow(OutputStream &)653 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
hasArraySlow(OutputStream &)654 bool hasArraySlow(OutputStream &) const override { return true; }
655
printLeft(OutputStream & S)656 void printLeft(OutputStream &S) const override { Base->printLeft(S); }
657
printRight(OutputStream & S)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:
FunctionType(const Node * Ret_,NodeArray Params_,Qualifiers CVQuals_,FunctionRefQual RefQual_,const Node * ExceptionSpec_)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
match(Fn F)687 template<typename Fn> void match(Fn F) const {
688 F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
689 }
690
hasRHSComponentSlow(OutputStream &)691 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
hasFunctionSlow(OutputStream &)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.
printLeft(OutputStream & S)701 void printLeft(OutputStream &S) const override {
702 Ret->printLeft(S);
703 S += " ";
704 }
705
printRight(OutputStream & S)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:
NoexceptSpec(const Node * E_)734 NoexceptSpec(const Node *E_) : Node(KNoexceptSpec), E(E_) {}
735
match(Fn F)736 template<typename Fn> void match(Fn F) const { F(E); }
737
printLeft(OutputStream & S)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:
DynamicExceptionSpec(NodeArray Types_)748 DynamicExceptionSpec(NodeArray Types_)
749 : Node(KDynamicExceptionSpec), Types(Types_) {}
750
match(Fn F)751 template<typename Fn> void match(Fn F) const { F(Types); }
752
printLeft(OutputStream & S)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:
FunctionEncoding(const Node * Ret_,const Node * Name_,NodeArray Params_,const Node * Attrs_,Qualifiers CVQuals_,FunctionRefQual RefQual_)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
match(Fn F)778 template<typename Fn> void match(Fn F) const {
779 F(Ret, Name, Params, Attrs, CVQuals, RefQual);
780 }
781
getCVQuals()782 Qualifiers getCVQuals() const { return CVQuals; }
getRefQual()783 FunctionRefQual getRefQual() const { return RefQual; }
getParams()784 NodeArray getParams() const { return Params; }
getReturnType()785 const Node *getReturnType() const { return Ret; }
786
hasRHSComponentSlow(OutputStream &)787 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
hasFunctionSlow(OutputStream &)788 bool hasFunctionSlow(OutputStream &) const override { return true; }
789
getName()790 const Node *getName() const { return Name; }
791
printLeft(OutputStream & S)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
printRight(OutputStream & S)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:
LiteralOperator(const Node * OpName_)829 LiteralOperator(const Node *OpName_)
830 : Node(KLiteralOperator), OpName(OpName_) {}
831
match(Fn F)832 template<typename Fn> void match(Fn F) const { F(OpName); }
833
printLeft(OutputStream & S)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:
SpecialName(StringView Special_,const Node * Child_)845 SpecialName(StringView Special_, const Node *Child_)
846 : Node(KSpecialName), Special(Special_), Child(Child_) {}
847
match(Fn F)848 template<typename Fn> void match(Fn F) const { F(Special, Child); }
849
printLeft(OutputStream & S)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:
CtorVtableSpecialName(const Node * FirstType_,const Node * SecondType_)861 CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_)
862 : Node(KCtorVtableSpecialName),
863 FirstType(FirstType_), SecondType(SecondType_) {}
864
match(Fn F)865 template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); }
866
printLeft(OutputStream & S)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
NestedNameNestedName879 NestedName(Node *Qual_, Node *Name_)
880 : Node(KNestedName), Qual(Qual_), Name(Name_) {}
881
matchNestedName882 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
883
getBaseNameNestedName884 StringView getBaseName() const override { return Name->getBaseName(); }
885
printLeftNestedName886 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
LocalNameLocalName897 LocalName(Node *Encoding_, Node *Entity_)
898 : Node(KLocalName), Encoding(Encoding_), Entity(Entity_) {}
899
matchLocalName900 template<typename Fn> void match(Fn F) const { F(Encoding, Entity); }
901
printLeftLocalName902 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:
QualifiedName(const Node * Qualifier_,const Node * Name_)915 QualifiedName(const Node *Qualifier_, const Node *Name_)
916 : Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
917
match(Fn F)918 template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
919
getBaseName()920 StringView getBaseName() const override { return Name->getBaseName(); }
921
printLeft(OutputStream & S)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:
VectorType(const Node * BaseType_,NodeOrString Dimension_)934 VectorType(const Node *BaseType_, NodeOrString Dimension_)
935 : Node(KVectorType), BaseType(BaseType_),
936 Dimension(Dimension_) {}
937
match(Fn F)938 template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); }
939
printLeft(OutputStream & S)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:
PixelVectorType(NodeOrString Dimension_)955 PixelVectorType(NodeOrString Dimension_)
956 : Node(KPixelVectorType), Dimension(Dimension_) {}
957
match(Fn F)958 template<typename Fn> void match(Fn F) const { F(Dimension); }
959
printLeft(OutputStream & S)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.
initializePackExpansion(OutputStream & S)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:
ParameterPack(NodeArray Data_)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
match(Fn F)1004 template<typename Fn> void match(Fn F) const { F(Data); }
1005
hasRHSComponentSlow(OutputStream & S)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 }
hasArraySlow(OutputStream & S)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 }
hasFunctionSlow(OutputStream & S)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 }
getSyntaxNode(OutputStream & S)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
printLeft(OutputStream & S)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 }
printRight(OutputStream & S)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:
TemplateArgumentPack(NodeArray Elements_)1049 TemplateArgumentPack(NodeArray Elements_)
1050 : Node(KTemplateArgumentPack), Elements(Elements_) {}
1051
match(Fn F)1052 template<typename Fn> void match(Fn F) const { F(Elements); }
1053
getElements()1054 NodeArray getElements() const { return Elements; }
1055
printLeft(OutputStream & S)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:
ParameterPackExpansion(const Node * Child_)1067 ParameterPackExpansion(const Node *Child_)
1068 : Node(KParameterPackExpansion), Child(Child_) {}
1069
match(Fn F)1070 template<typename Fn> void match(Fn F) const { F(Child); }
1071
getChild()1072 const Node *getChild() const { return Child; }
1073
printLeft(OutputStream & S)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:
TemplateArgs(NodeArray Params_)1111 TemplateArgs(NodeArray Params_) : Node(KTemplateArgs), Params(Params_) {}
1112
match(Fn F)1113 template<typename Fn> void match(Fn F) const { F(Params); }
1114
getParams()1115 NodeArray getParams() { return Params; }
1116
printLeft(OutputStream & S)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
ForwardTemplateReferenceForwardTemplateReference1154 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
hasRHSComponentSlowForwardTemplateReference1164 bool hasRHSComponentSlow(OutputStream &S) const override {
1165 if (Printing)
1166 return false;
1167 SwapAndRestore<bool> SavePrinting(Printing, true);
1168 return Ref->hasRHSComponent(S);
1169 }
hasArraySlowForwardTemplateReference1170 bool hasArraySlow(OutputStream &S) const override {
1171 if (Printing)
1172 return false;
1173 SwapAndRestore<bool> SavePrinting(Printing, true);
1174 return Ref->hasArray(S);
1175 }
hasFunctionSlowForwardTemplateReference1176 bool hasFunctionSlow(OutputStream &S) const override {
1177 if (Printing)
1178 return false;
1179 SwapAndRestore<bool> SavePrinting(Printing, true);
1180 return Ref->hasFunction(S);
1181 }
getSyntaxNodeForwardTemplateReference1182 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
printLeftForwardTemplateReference1189 void printLeft(OutputStream &S) const override {
1190 if (Printing)
1191 return;
1192 SwapAndRestore<bool> SavePrinting(Printing, true);
1193 Ref->printLeft(S);
1194 }
printRightForwardTemplateReference1195 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
NameWithTemplateArgsNameWithTemplateArgs1208 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
1209 : Node(KNameWithTemplateArgs), Name(Name_), TemplateArgs(TemplateArgs_) {}
1210
matchNameWithTemplateArgs1211 template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1212
getBaseNameNameWithTemplateArgs1213 StringView getBaseName() const override { return Name->getBaseName(); }
1214
printLeftNameWithTemplateArgs1215 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:
GlobalQualifiedName(Node * Child_)1225 GlobalQualifiedName(Node* Child_)
1226 : Node(KGlobalQualifiedName), Child(Child_) {}
1227
match(Fn F)1228 template<typename Fn> void match(Fn F) const { F(Child); }
1229
getBaseName()1230 StringView getBaseName() const override { return Child->getBaseName(); }
1231
printLeft(OutputStream & S)1232 void printLeft(OutputStream &S) const override {
1233 S += "::";
1234 Child->print(S);
1235 }
1236 };
1237
1238 struct StdQualifiedName : Node {
1239 Node *Child;
1240
StdQualifiedNameStdQualifiedName1241 StdQualifiedName(Node *Child_) : Node(KStdQualifiedName), Child(Child_) {}
1242
matchStdQualifiedName1243 template<typename Fn> void match(Fn F) const { F(Child); }
1244
getBaseNameStdQualifiedName1245 StringView getBaseName() const override { return Child->getBaseName(); }
1246
printLeftStdQualifiedName1247 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:
ExpandedSpecialSubstitution(SpecialSubKind SSK_)1266 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1267 : Node(KExpandedSpecialSubstitution), SSK(SSK_) {}
1268
match(Fn F)1269 template<typename Fn> void match(Fn F) const { F(SSK); }
1270
getBaseName()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
printLeft(OutputStream & S)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
SpecialSubstitution(SpecialSubKind SSK_)1318 SpecialSubstitution(SpecialSubKind SSK_)
1319 : Node(KSpecialSubstitution), SSK(SSK_) {}
1320
match(Fn F)1321 template<typename Fn> void match(Fn F) const { F(SSK); }
1322
getBaseName()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
printLeft(OutputStream & S)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:
CtorDtorName(const Node * Basename_,bool IsDtor_,int Variant_)1371 CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
1372 : Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1373 Variant(Variant_) {}
1374
match(Fn F)1375 template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1376
printLeft(OutputStream & S)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:
DtorName(const Node * Base_)1388 DtorName(const Node *Base_) : Node(KDtorName), Base(Base_) {}
1389
match(Fn F)1390 template<typename Fn> void match(Fn F) const { F(Base); }
1391
printLeft(OutputStream & S)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:
UnnamedTypeName(StringView Count_)1402 UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {}
1403
match(Fn F)1404 template<typename Fn> void match(Fn F) const { F(Count); }
1405
printLeft(OutputStream & S)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:
ClosureTypeName(NodeArray Params_,StringView Count_)1418 ClosureTypeName(NodeArray Params_, StringView Count_)
1419 : Node(KClosureTypeName), Params(Params_), Count(Count_) {}
1420
match(Fn F)1421 template<typename Fn> void match(Fn F) const { F(Params, Count); }
1422
printLeft(OutputStream & S)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:
StructuredBindingName(NodeArray Bindings_)1435 StructuredBindingName(NodeArray Bindings_)
1436 : Node(KStructuredBindingName), Bindings(Bindings_) {}
1437
match(Fn F)1438 template<typename Fn> void match(Fn F) const { F(Bindings); }
1439
printLeft(OutputStream & S)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:
BinaryExpr(const Node * LHS_,StringView InfixOperator_,const Node * RHS_)1455 BinaryExpr(const Node *LHS_, StringView InfixOperator_, const Node *RHS_)
1456 : Node(KBinaryExpr), LHS(LHS_), InfixOperator(InfixOperator_), RHS(RHS_) {
1457 }
1458
match(Fn F)1459 template<typename Fn> void match(Fn F) const { F(LHS, InfixOperator, RHS); }
1460
printLeft(OutputStream & S)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:
ArraySubscriptExpr(const Node * Op1_,const Node * Op2_)1485 ArraySubscriptExpr(const Node *Op1_, const Node *Op2_)
1486 : Node(KArraySubscriptExpr), Op1(Op1_), Op2(Op2_) {}
1487
match(Fn F)1488 template<typename Fn> void match(Fn F) const { F(Op1, Op2); }
1489
printLeft(OutputStream & S)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:
PostfixExpr(const Node * Child_,StringView Operator_)1504 PostfixExpr(const Node *Child_, StringView Operator_)
1505 : Node(KPostfixExpr), Child(Child_), Operator(Operator_) {}
1506
match(Fn F)1507 template<typename Fn> void match(Fn F) const { F(Child, Operator); }
1508
printLeft(OutputStream & S)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:
ConditionalExpr(const Node * Cond_,const Node * Then_,const Node * Else_)1523 ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_)
1524 : Node(KConditionalExpr), Cond(Cond_), Then(Then_), Else(Else_) {}
1525
match(Fn F)1526 template<typename Fn> void match(Fn F) const { F(Cond, Then, Else); }
1527
printLeft(OutputStream & S)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:
MemberExpr(const Node * LHS_,StringView Kind_,const Node * RHS_)1545 MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_)
1546 : Node(KMemberExpr), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
1547
match(Fn F)1548 template<typename Fn> void match(Fn F) const { F(LHS, Kind, RHS); }
1549
printLeft(OutputStream & S)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:
EnclosingExpr(StringView Prefix_,Node * Infix_,StringView Postfix_)1563 EnclosingExpr(StringView Prefix_, Node *Infix_, StringView Postfix_)
1564 : Node(KEnclosingExpr), Prefix(Prefix_), Infix(Infix_),
1565 Postfix(Postfix_) {}
1566
match(Fn F)1567 template<typename Fn> void match(Fn F) const { F(Prefix, Infix, Postfix); }
1568
printLeft(OutputStream & S)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:
CastExpr(StringView CastKind_,const Node * To_,const Node * From_)1583 CastExpr(StringView CastKind_, const Node *To_, const Node *From_)
1584 : Node(KCastExpr), CastKind(CastKind_), To(To_), From(From_) {}
1585
match(Fn F)1586 template<typename Fn> void match(Fn F) const { F(CastKind, To, From); }
1587
printLeft(OutputStream & S)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:
SizeofParamPackExpr(const Node * Pack_)1602 SizeofParamPackExpr(const Node *Pack_)
1603 : Node(KSizeofParamPackExpr), Pack(Pack_) {}
1604
match(Fn F)1605 template<typename Fn> void match(Fn F) const { F(Pack); }
1606
printLeft(OutputStream & S)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:
CallExpr(const Node * Callee_,NodeArray Args_)1620 CallExpr(const Node *Callee_, NodeArray Args_)
1621 : Node(KCallExpr), Callee(Callee_), Args(Args_) {}
1622
match(Fn F)1623 template<typename Fn> void match(Fn F) const { F(Callee, Args); }
1624
printLeft(OutputStream & S)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:
NewExpr(NodeArray ExprList_,Node * Type_,NodeArray InitList_,bool IsGlobal_,bool IsArray_)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
match(Fn F)1646 template<typename Fn> void match(Fn F) const {
1647 F(ExprList, Type, InitList, IsGlobal, IsArray);
1648 }
1649
printLeft(OutputStream & S)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:
DeleteExpr(Node * Op_,bool IsGlobal_,bool IsArray_)1678 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_)
1679 : Node(KDeleteExpr), Op(Op_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
1680
match(Fn F)1681 template<typename Fn> void match(Fn F) const { F(Op, IsGlobal, IsArray); }
1682
printLeft(OutputStream & S)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:
PrefixExpr(StringView Prefix_,Node * Child_)1698 PrefixExpr(StringView Prefix_, Node *Child_)
1699 : Node(KPrefixExpr), Prefix(Prefix_), Child(Child_) {}
1700
match(Fn F)1701 template<typename Fn> void match(Fn F) const { F(Prefix, Child); }
1702
printLeft(OutputStream & S)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:
FunctionParam(StringView Number_)1715 FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {}
1716
match(Fn F)1717 template<typename Fn> void match(Fn F) const { F(Number); }
1718
printLeft(OutputStream & S)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:
ConversionExpr(const Node * Type_,NodeArray Expressions_)1730 ConversionExpr(const Node *Type_, NodeArray Expressions_)
1731 : Node(KConversionExpr), Type(Type_), Expressions(Expressions_) {}
1732
match(Fn F)1733 template<typename Fn> void match(Fn F) const { F(Type, Expressions); }
1734
printLeft(OutputStream & S)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:
InitListExpr(const Node * Ty_,NodeArray Inits_)1748 InitListExpr(const Node *Ty_, NodeArray Inits_)
1749 : Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
1750
match(Fn F)1751 template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
1752
printLeft(OutputStream & S)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:
BracedExpr(const Node * Elem_,const Node * Init_,bool IsArray_)1767 BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
1768 : Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
1769
match(Fn F)1770 template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
1771
printLeft(OutputStream & S)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:
BracedRangeExpr(const Node * First_,const Node * Last_,const Node * Init_)1792 BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
1793 : Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
1794
match(Fn F)1795 template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
1796
printLeft(OutputStream & S)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:
FoldExpr(bool IsLeftFold_,StringView OperatorName_,const Node * Pack_,const Node * Init_)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
match(Fn F)1820 template<typename Fn> void match(Fn F) const {
1821 F(IsLeftFold, OperatorName, Pack, Init);
1822 }
1823
printLeft(OutputStream & S)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:
ThrowExpr(const Node * Op_)1868 ThrowExpr(const Node *Op_) : Node(KThrowExpr), Op(Op_) {}
1869
match(Fn F)1870 template<typename Fn> void match(Fn F) const { F(Op); }
1871
printLeft(OutputStream & S)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:
BoolExpr(bool Value_)1882 BoolExpr(bool Value_) : Node(KBoolExpr), Value(Value_) {}
1883
match(Fn F)1884 template<typename Fn> void match(Fn F) const { F(Value); }
1885
printLeft(OutputStream & S)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:
IntegerCastExpr(const Node * Ty_,StringView Integer_)1897 IntegerCastExpr(const Node *Ty_, StringView Integer_)
1898 : Node(KIntegerCastExpr), Ty(Ty_), Integer(Integer_) {}
1899
match(Fn F)1900 template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
1901
printLeft(OutputStream & S)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:
IntegerLiteral(StringView Type_,StringView Value_)1915 IntegerLiteral(StringView Type_, StringView Value_)
1916 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
1917
match(Fn F)1918 template<typename Fn> void match(Fn F) const { F(Type, Value); }
1919
printLeft(OutputStream & S)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 {
getFloatLiteralKind(float *)1941 constexpr Node::Kind getFloatLiteralKind(float *) {
1942 return Node::KFloatLiteral;
1943 }
getFloatLiteralKind(double *)1944 constexpr Node::Kind getFloatLiteralKind(double *) {
1945 return Node::KDoubleLiteral;
1946 }
getFloatLiteralKind(long double *)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:
FloatLiteralImpl(StringView Contents_)1959 FloatLiteralImpl(StringView Contents_)
1960 : Node(KindForClass), Contents(Contents_) {}
1961
match(Fn F)1962 template<typename Fn> void match(Fn F) const { F(Contents); }
1963
printLeft(OutputStream & s)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>
visit(Fn F)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 };
FOR_EACH_NODE_KIND(SPECIALIZATION)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
AbstractManglingParserAbstractManglingParser2171 AbstractManglingParser(const char *First_, const char *Last_)
2172 : First(First_), Last(Last_) {}
2173
getDerivedAbstractManglingParser2174 Derived &getDerived() { return static_cast<Derived &>(*this); }
2175
resetAbstractManglingParser2176 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
makeAbstractManglingParser2188 template <class T, class... Args> Node *make(Args &&... args) {
2189 return ASTAllocator.template makeNode<T>(std::forward<Args>(args)...);
2190 }
2191
makeNodeArrayAbstractManglingParser2192 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
popTrailingNodeArrayAbstractManglingParser2200 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
consumeIfAbstractManglingParser2208 bool consumeIf(StringView S) {
2209 if (StringView(First, Last).startsWith(S)) {
2210 First += S.size();
2211 return true;
2212 }
2213 return false;
2214 }
2215
consumeIfAbstractManglingParser2216 bool consumeIf(char C) {
2217 if (First != Last && *First == C) {
2218 ++First;
2219 return true;
2220 }
2221 return false;
2222 }
2223
consumeAbstractManglingParser2224 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
numLeftAbstractManglingParser2232 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
NameStateAbstractManglingParser::NameState2281 NameState(AbstractManglingParser *Enclosing)
2282 : ForwardTemplateRefsBegin(Enclosing->ForwardTemplateRefs.size()) {}
2283 };
2284
resolveForwardTemplateRefsAbstractManglingParser2285 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>
parseName(NameState * State)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>
parseLocalName(NameState * State)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 *
parseUnscopedName(NameState * State)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 *
parseUnqualifiedName(NameState * State)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 *
parseUnnamedTypeName(NameState *)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>
parseSourceName(NameState *)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 *
parseOperatorName(NameState * State)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 *
parseCtorDtorName(Node * & SoFar,NameState * State)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 *
parseNestedName(NameState * State)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>
parseSimpleId()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>
parseDestructorName()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>
parseUnresolvedType()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>
parseBaseUnresolvedName()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>
parseUnresolvedName()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>
parseAbiTags(Node * N)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
parseNumber(bool AllowNegative)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>
parsePositiveInteger(size_t * Out)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>
parseBareSourceName()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>
parseFunctionType()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>
parseVectorType()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>
parseDecltype()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>
parseArrayType()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>
parsePointerToMemberType()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>
parseClassEnumType()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>
parseQualifiedType()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>
parseType()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>
parsePrefixExpr(StringView Kind)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>
parseBinaryExpr(StringView Kind)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 *
parseIntegerLiteral(StringView Lit)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>
parseCVQualifiers()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>
parseFunctionParam()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>
parseNewExpr()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>
parseConversionExpr()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>
parseExprPrimary()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>
parseBracedExpr()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>
parseFoldExpr()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>
parseExpr()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>
parseCallOffset()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>
parseSpecialName()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>
parseEncoding()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 = 41;
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