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