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