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