blob: e13358b7ef99bb17f958f5ec982c8b4d10da68c1 [file] [log] [blame]
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001//===-------------------------- cxa_demangle.cpp --------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Howard Hinnant6c33e762013-06-17 18:10:34 +000010#define _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd213ffd2011-05-05 15:27:28 +000011
Saleem Abdulrasoolb4ec5792015-12-04 02:14:58 +000012#include "__cxxabi_config.h"
13
Howard Hinnant6c33e762013-06-17 18:10:34 +000014#include <vector>
Howard Hinnantd213ffd2011-05-05 15:27:28 +000015#include <algorithm>
Howard Hinnant6c33e762013-06-17 18:10:34 +000016#include <numeric>
Erik Pilkington77101542017-07-28 00:53:30 +000017#include <cstdio>
Howard Hinnant6c33e762013-06-17 18:10:34 +000018#include <cstdlib>
19#include <cstring>
20#include <cctype>
Howard Hinnantd213ffd2011-05-05 15:27:28 +000021
Nico Weberb4c998b2015-09-20 18:10:46 +000022#ifdef _MSC_VER
23// snprintf is implemented in VS 2015
24#if _MSC_VER < 1900
25#define snprintf _snprintf_s
26#endif
27#endif
28
Howard Hinnantd213ffd2011-05-05 15:27:28 +000029namespace __cxxabiv1
30{
31
Howard Hinnant6c33e762013-06-17 18:10:34 +000032namespace
Howard Hinnantd213ffd2011-05-05 15:27:28 +000033{
34
Howard Hinnant6c33e762013-06-17 18:10:34 +000035enum
Howard Hinnantd213ffd2011-05-05 15:27:28 +000036{
Howard Hinnant6c33e762013-06-17 18:10:34 +000037 unknown_error = -4,
38 invalid_args = -3,
39 invalid_mangled_name,
40 memory_alloc_failure,
41 success
Howard Hinnantd213ffd2011-05-05 15:27:28 +000042};
43
Erik Pilkington0024acd2017-07-28 00:43:49 +000044class StringView {
45 const char *First;
46 const char *Last;
47
48public:
49 template <size_t N>
50 StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
51 StringView(const char *First, const char *Last) : First(First), Last(Last) {}
52 StringView() : First(nullptr), Last(nullptr) {}
53
54 StringView substr(size_t From, size_t To) {
55 if (To >= size())
56 To = size() - 1;
57 if (From >= size())
58 From = size() - 1;
59 return StringView(First + From, First + To);
60 }
61
62 StringView dropFront(size_t N) const {
63 if (N >= size())
64 N = size() - 1;
65 return StringView(First + N, Last);
66 }
67
68 bool startsWith(StringView Str) const {
69 if (Str.size() > size())
70 return false;
71 return std::equal(Str.begin(), Str.end(), begin());
72 }
73
74 const char &operator[](size_t Idx) const { return *(begin() + Idx); }
75
76 const char *begin() const { return First; }
77 const char *end() const { return Last; }
78 size_t size() const { return static_cast<size_t>(Last - First); }
79};
80
81bool operator==(const StringView &LHS, const StringView &RHS) {
82 return LHS.size() == RHS.size() &&
83 std::equal(LHS.begin(), LHS.end(), RHS.begin());
84}
85
86// Stream that AST nodes write their string representation into after the AST
87// has been parsed.
88class OutputStream {
89 char *Buffer;
90 size_t CurrentPosition;
91 size_t BufferCapacity;
92
93 // Ensure there is at least n more positions in buffer.
94 void grow(size_t N) {
95 if (N + CurrentPosition >= BufferCapacity) {
96 BufferCapacity *= 2;
97 if (BufferCapacity < N + CurrentPosition)
98 BufferCapacity = N + CurrentPosition;
99 Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
100 }
101 }
102
103public:
104 OutputStream(char *StartBuf, size_t Size)
105 : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
106
107 OutputStream &operator+=(StringView R) {
108 size_t Size = R.size();
109 if (Size == 0)
110 return *this;
111 grow(Size);
112 memmove(Buffer + CurrentPosition, R.begin(), Size);
113 CurrentPosition += Size;
114 return *this;
115 }
116
117 OutputStream &operator+=(char C) {
118 grow(1);
119 Buffer[CurrentPosition++] = C;
120 return *this;
121 }
122
123 // Offset of position in buffer, used for building stream_string_view.
124 typedef unsigned StreamPosition;
125
126 // StringView into a stream, used for caching the ast nodes.
127 class StreamStringView {
128 StreamPosition First, Last;
129
130 friend class OutputStream;
131
132 public:
133 StreamStringView() : First(0), Last(0) {}
134
135 StreamStringView(StreamPosition First, StreamPosition Last)
136 : First(First), Last(Last) {}
137
138 bool empty() const { return First == Last; }
139 };
140
141 OutputStream &operator+=(StreamStringView &s) {
142 size_t Sz = static_cast<size_t>(s.Last - s.First);
143 if (Sz == 0)
144 return *this;
145 grow(Sz);
146 memmove(Buffer + CurrentPosition, Buffer + s.First, Sz);
147 CurrentPosition += Sz;
148 return *this;
149 }
150
151 StreamPosition getCurrentPosition() const {
152 return static_cast<StreamPosition>(CurrentPosition);
153 }
154
155 StreamStringView makeStringViewFromPastPosition(StreamPosition Pos) {
156 return StreamStringView(Pos, getCurrentPosition());
157 }
158
159 char back() const {
160 return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
161 }
162
163 bool empty() const { return CurrentPosition == 0; }
164
165 char *getBuffer() { return Buffer; }
166 char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
167 size_t getBufferCapacity() { return BufferCapacity; }
168};
169
170// Base class of all AST nodes. The AST is built by the parser, then is
171// traversed by the printLeft/Right functions to produce a demangled string.
172class Node {
173public:
174 enum Kind : unsigned char {
175 KDotSuffix,
176 KVendorExtQualType,
177 KQualType,
178 KConversionOperatorType,
179 KPostfixQualifiedType,
180 KNameType,
181 KObjCProtoName,
182 KPointerType,
183 KLValueReferenceType,
184 KRValueReferenceType,
185 KPointerToMemberType,
186 KArrayType,
187 KFunctionType,
188 KTopLevelFunctionDecl,
189 KFunctionQualType,
190 KFunctionRefQualType,
191 KLiteralOperator,
192 KSpecialName,
193 KCtorVtableSpecialName,
194 KQualifiedName,
195 KEmptyName,
196 KVectorType,
197 KTemplateParams,
198 KNameWithTemplateArgs,
199 KGlobalQualifiedName,
200 KStdQualifiedName,
201 KExpandedSpecialSubstitution,
202 KSpecialSubstitution,
203 KCtorDtorName,
204 KDtorName,
205 KUnnamedTypeName,
206 KLambdaTypeName,
207 KExpr,
208 };
209
210 const Kind K;
211
212private:
213 // If this Node has any RHS part, potentally many Nodes further down.
214 const unsigned HasRHSComponent : 1;
215 const unsigned HasFunction : 1;
216 const unsigned HasArray : 1;
217
218public:
219 Node(Kind K, bool HasRHS = false, bool HasFunction = false,
220 bool HasArray = false)
221 : K(K), HasRHSComponent(HasRHS), HasFunction(HasFunction),
222 HasArray(HasArray) {}
223
224 bool hasRHSComponent() const { return HasRHSComponent; }
225 bool hasArray() const { return HasArray; }
226 bool hasFunction() const { return HasFunction; }
227
228 void print(OutputStream &s) const {
229 printLeft(s);
230 if (hasRHSComponent())
231 printRight(s);
232 }
233
234 // Print the "left" side of this Node into OutputStream.
235 virtual void printLeft(OutputStream &) const = 0;
236
237 // Print the "right". This distinction is necessary to represent C++ types
238 // that appear on the RHS of their subtype, such as arrays or functions.
239 // Since most types don't have such a component, provide a default
240 // implemenation.
241 virtual void printRight(OutputStream &) const {}
242
243 virtual StringView getBaseName() const { return StringView(); }
244
245 // Silence compiler warnings, this dtor will never be called.
246 virtual ~Node() = default;
247};
248
249class NodeArray {
250 Node **Elements;
251 size_t NumElements;
252
253public:
254 NodeArray() : NumElements(0) {}
255 NodeArray(Node **Elements, size_t NumElements)
256 : Elements(Elements), NumElements(NumElements) {}
257
258 bool empty() const { return NumElements == 0; }
259 size_t size() const { return NumElements; }
260
261 void printWithSeperator(OutputStream &S, StringView Seperator) const {
262 for (size_t Idx = 0; Idx != NumElements; ++Idx) {
263 if (Idx)
264 S += Seperator;
265 Elements[Idx]->print(S);
266 }
267 }
268};
269
270class DotSuffix final : public Node {
271 const Node *Prefix;
272 const StringView Suffix;
273
274public:
275 DotSuffix(Node *Prefix, StringView Suffix)
276 : Node(KDotSuffix), Prefix(Prefix), Suffix(Suffix) {}
277
278 void printLeft(OutputStream &s) const override {
279 Prefix->print(s);
280 s += " (";
281 s += Suffix;
282 s += ")";
283 }
284};
285
286class VendorExtQualType final : public Node {
287 const Node *Ext;
288 const Node *Ty;
289
290public:
291 VendorExtQualType(Node *Ext, Node *Ty)
292 : Node(KVendorExtQualType), Ext(Ext), Ty(Ty) {}
293
294 void printLeft(OutputStream &S) const override {
295 Ext->print(S);
296 S += " ";
297 Ty->printLeft(S);
298 }
299
300 void printRight(OutputStream &S) const override { Ty->printRight(S); }
301};
302
303enum Qualifiers {
304 QualNone = 0,
305 QualConst = 0x1,
306 QualVolatile = 0x2,
307 QualRestrict = 0x4,
308};
309
310void addQualifiers(Qualifiers &Q1, Qualifiers Q2) {
311 Q1 = static_cast<Qualifiers>(Q1 | Q2);
312}
313
314class QualType : public Node {
315protected:
316 const Qualifiers Quals;
317 const Node *Child;
318
319 void printQuals(OutputStream &S) const {
320 if (Quals & QualConst)
321 S += " const";
322 if (Quals & QualVolatile)
323 S += " volatile";
324 if (Quals & QualRestrict)
325 S += " restrict";
326 }
327
328public:
329 QualType(Node *Child, Qualifiers Quals)
330 : Node(KQualType, Child->hasRHSComponent(), Child->hasFunction(),
331 Child->hasArray()),
332 Quals(Quals), Child(Child) {}
333
334 QualType(Node::Kind ChildKind, Node *Child, Qualifiers Quals)
335 : Node(ChildKind, Child->hasRHSComponent(), Child->hasFunction(),
336 Child->hasArray()),
337 Quals(Quals), Child(Child) {}
338
339 void printLeft(OutputStream &S) const override {
340 Child->printLeft(S);
341 printQuals(S);
342 }
343
344 void printRight(OutputStream &S) const override { Child->printRight(S); }
345};
346
347class ConversionOperatorType final : public Node {
348 const Node *Ty;
349
350public:
351 ConversionOperatorType(Node *Ty) : Node(KConversionOperatorType), Ty(Ty) {}
352
353 void printLeft(OutputStream &S) const override {
354 S += "operator ";
355 Ty->print(S);
356 }
357};
358
359class PostfixQualifiedType final : public Node {
360 const Node *Ty;
361 const StringView Postfix;
362
363public:
364 PostfixQualifiedType(Node *Ty, StringView Postfix)
365 : Node(KPostfixQualifiedType), Ty(Ty), Postfix(Postfix) {}
366
367 void printLeft(OutputStream &s) const override {
368 Ty->printLeft(s);
369 s += Postfix;
370 }
371
372 void printRight(OutputStream &S) const override { Ty->printRight(S); }
373};
374
375class NameType final : public Node {
376 const StringView Name;
377
378public:
379 NameType(StringView Name) : Node(KNameType), Name(Name) {}
380
381 StringView getName() const { return Name; }
382 StringView getBaseName() const override { return Name; }
383
384 void printLeft(OutputStream &s) const override { s += Name; }
385};
386
387class ObjCProtoName : public Node {
388 Node *Ty;
389 Node *Protocol;
390
391 friend class PointerType;
392
393public:
394 ObjCProtoName(Node *Ty, Node *Protocol)
395 : Node(KObjCProtoName), Ty(Ty), Protocol(Protocol) {}
396
397 bool isObjCObject() const {
398 return Ty->K == KNameType &&
399 static_cast<NameType *>(Ty)->getName() == "objc_object";
400 }
401
402 void printLeft(OutputStream &S) const override {
403 Ty->printLeft(S);
404 S += "<";
405 Protocol->printLeft(S);
406 S += ">";
407 }
408};
409
410class PointerType final : public Node {
411 const Node *Pointee;
412
413public:
414 PointerType(Node *Pointee)
415 : Node(KPointerType, Pointee->hasRHSComponent()), Pointee(Pointee) {}
416
417 void printLeft(OutputStream &s) const override {
418 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
419 if (Pointee->K != KObjCProtoName ||
420 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
421 Pointee->printLeft(s);
422 if (Pointee->hasArray())
423 s += " ";
424 if (Pointee->hasArray() || Pointee->hasFunction())
425 s += "(";
426 s += "*";
427 } else {
428 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
429 s += "id<";
430 objcProto->Protocol->print(s);
431 s += ">";
432 }
433 }
434
435 void printRight(OutputStream &s) const override {
436 if (Pointee->K != KObjCProtoName ||
437 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
438 if (Pointee->hasArray() || Pointee->hasFunction())
439 s += ")";
440 Pointee->printRight(s);
441 }
442 }
443};
444
445class LValueReferenceType final : public Node {
446 const Node *Pointee;
447
448public:
449 LValueReferenceType(Node *Pointee)
450 : Node(KLValueReferenceType, Pointee->hasRHSComponent()),
451 Pointee(Pointee) {}
452
453 void printLeft(OutputStream &s) const override {
454 Pointee->printLeft(s);
455 if (Pointee->hasArray())
456 s += " ";
457 if (Pointee->hasArray() || Pointee->hasFunction())
458 s += "(&";
459 else
460 s += "&";
461 }
462 void printRight(OutputStream &s) const override {
463 if (Pointee->hasArray() || Pointee->hasFunction())
464 s += ")";
465 Pointee->printRight(s);
466 }
467};
468
469class RValueReferenceType final : public Node {
470 const Node *Pointee;
471
472public:
473 RValueReferenceType(Node *Pointee)
474 : Node(KRValueReferenceType, Pointee->hasRHSComponent()),
475 Pointee(Pointee) {}
476
477 void printLeft(OutputStream &s) const override {
478 Pointee->printLeft(s);
479 if (Pointee->hasArray())
480 s += " ";
481 if (Pointee->hasArray() || Pointee->hasFunction())
482 s += "(&&";
483 else
484 s += "&&";
485 }
486
487 void printRight(OutputStream &s) const override {
488 if (Pointee->hasArray() || Pointee->hasFunction())
489 s += ")";
490 Pointee->printRight(s);
491 }
492};
493
494class PointerToMemberType final : public Node {
495 const Node *ClassType;
496 const Node *MemberType;
497
498public:
499 PointerToMemberType(Node *ClassType, Node *MemberType)
500 : Node(KPointerToMemberType, MemberType->hasRHSComponent()),
501 ClassType(ClassType), MemberType(MemberType) {}
502
503 void printLeft(OutputStream &s) const override {
504 MemberType->printLeft(s);
505 if (MemberType->hasArray() || MemberType->hasFunction())
506 s += "(";
507 else
508 s += " ";
509 ClassType->print(s);
510 s += "::*";
511 }
512
513 void printRight(OutputStream &s) const override {
514 if (MemberType->hasArray() || MemberType->hasFunction())
515 s += ")";
516 MemberType->printRight(s);
517 }
518};
519
520class NodeOrString {
521 const void *First;
522 const void *Second;
523
524public:
525 /* implicit */ NodeOrString(StringView Str) {
526 const char *FirstChar = Str.begin();
527 const char *SecondChar = Str.end();
528 if (SecondChar == nullptr) {
529 assert(FirstChar == SecondChar);
530 ++FirstChar, ++SecondChar;
531 }
532 First = static_cast<const void *>(FirstChar);
533 Second = static_cast<const void *>(SecondChar);
534 }
535
536 /* implicit */ NodeOrString(Node *N)
537 : First(static_cast<const void *>(N)), Second(nullptr) {}
538 NodeOrString() : First(nullptr), Second(nullptr) {}
539
540 bool isString() const { return Second && First; }
541 bool isNode() const { return First && !Second; }
542 bool isEmpty() const { return !First && !Second; }
543
544 StringView asString() const {
545 assert(isString());
546 return StringView(static_cast<const char *>(First),
547 static_cast<const char *>(Second));
548 }
549
550 const Node *asNode() const {
551 assert(isNode());
552 return static_cast<const Node *>(First);
553 }
554};
555
556class ArrayType final : public Node {
557 Node *Base;
558 NodeOrString Dimension;
559
560public:
561 ArrayType(Node *Base, NodeOrString Dimension)
562 : Node(KArrayType, true, false, true), Base(Base), Dimension(Dimension) {}
563
564 // Incomplete array type.
565 ArrayType(Node *Base) : Node(KArrayType, true, false, true), Base(Base) {}
566
567 void printLeft(OutputStream &S) const override { Base->printLeft(S); }
568
569 void printRight(OutputStream &S) const override {
570 if (S.back() != ']')
571 S += " ";
572 S += "[";
573 if (Dimension.isString())
574 S += Dimension.asString();
575 else if (Dimension.isNode())
576 Dimension.asNode()->print(S);
577 S += "]";
578 Base->printRight(S);
579 }
580};
581
582class FunctionType final : public Node {
583 Node *Ret;
584 NodeArray Params;
585
586public:
587 FunctionType(Node *Ret, NodeArray Params)
588 : Node(KFunctionType, true, true), Ret(Ret), Params(Params) {}
589
590 // Handle C++'s ... quirky decl grammer by using the left & right
591 // distinction. Consider:
592 // int (*f(float))(char) {}
593 // f is a function that takes a float and returns a pointer to a function
594 // that takes a char and returns an int. If we're trying to print f, start
595 // by printing out the return types's left, then print our parameters, then
596 // finally print right of the return type.
597 void printLeft(OutputStream &S) const override {
598 Ret->printLeft(S);
599 S += " ";
600 }
601
602 void printRight(OutputStream &S) const override {
603 S += "(";
604 Params.printWithSeperator(S, ", ");
605 S += ")";
606 Ret->printRight(S);
607 }
608};
609
610class TopLevelFunctionDecl final : public Node {
611 const Node *Ret;
612 const Node *Name;
613 NodeArray Params;
614
615public:
616 TopLevelFunctionDecl(Node *Ret, Node *Name, NodeArray Params)
617 : Node(KTopLevelFunctionDecl, true, true), Ret(Ret), Name(Name),
618 Params(Params) {}
619
620 void printLeft(OutputStream &S) const override {
621 if (Ret) {
622 Ret->printLeft(S);
623 if (!Ret->hasRHSComponent())
624 S += " ";
625 }
626 Name->print(S);
627 }
628
629 void printRight(OutputStream &S) const override {
630 S += "(";
631 Params.printWithSeperator(S, ", ");
632 S += ")";
633 if (Ret)
634 Ret->printRight(S);
635 }
636};
637
638enum FunctionRefQual : unsigned char {
639 FrefQualNone,
640 FrefQualLValue,
641 FrefQualRValue,
642};
643
644class FunctionRefQualType : public Node {
645 Node *Fn;
646 FunctionRefQual Quals;
647
648 friend class FunctionQualType;
649
650public:
651 FunctionRefQualType(Node *Fn, FunctionRefQual Quals)
652 : Node(KFunctionRefQualType, true, true), Fn(Fn), Quals(Quals) {}
653
654 void printQuals(OutputStream &S) const {
655 if (Quals == FrefQualLValue)
656 S += " &";
657 else
658 S += " &&";
659 }
660
661 void printLeft(OutputStream &S) const override { Fn->printLeft(S); }
662
663 void printRight(OutputStream &S) const override {
664 Fn->printRight(S);
665 printQuals(S);
666 }
667};
668
669class FunctionQualType final : public QualType {
670public:
671 FunctionQualType(Node *Child, Qualifiers Quals)
672 : QualType(KFunctionQualType, Child, Quals) {}
673
674 void printLeft(OutputStream &S) const override { Child->printLeft(S); }
675
676 void printRight(OutputStream &S) const override {
677 if (Child->K == KFunctionRefQualType) {
678 auto *RefQuals = static_cast<const FunctionRefQualType *>(Child);
679 RefQuals->Fn->printRight(S);
680 printQuals(S);
681 RefQuals->printQuals(S);
682 } else {
683 Child->printRight(S);
684 printQuals(S);
685 }
686 }
687};
688
689class LiteralOperator : public Node {
690 const Node *OpName;
691
692public:
693 LiteralOperator(Node *OpName) : Node(KLiteralOperator), OpName(OpName) {}
694
695 void printLeft(OutputStream &S) const override {
696 S += "operator\"\" ";
697 OpName->print(S);
698 }
699};
700
701class SpecialName final : public Node {
702 const StringView Special;
703 const Node *Child;
704
705public:
706 SpecialName(StringView Special, Node *Child)
707 : Node(KSpecialName), Special(Special), Child(Child) {}
708
709 void printLeft(OutputStream &S) const override {
710 S += Special;
711 Child->print(S);
712 }
713};
714
715class CtorVtableSpecialName final : public Node {
716 const Node *FirstType;
717 const Node *SecondType;
718
719public:
720 CtorVtableSpecialName(Node *FirstType, Node *SecondType)
721 : Node(KCtorVtableSpecialName), FirstType(FirstType),
722 SecondType(SecondType) {}
723
724 void printLeft(OutputStream &S) const override {
725 S += "construction vtable for ";
726 FirstType->print(S);
727 S += "-in-";
728 SecondType->print(S);
729 }
730};
731
732class QualifiedName final : public Node {
733 // qualifier::name
734 const Node *Qualifier;
735 const Node *Name;
736
737 mutable OutputStream::StreamStringView Cache;
738
739public:
740 QualifiedName(Node *Qualifier, Node *Name)
741 : Node(KQualifiedName), Qualifier(Qualifier), Name(Name) {}
742
743 StringView getBaseName() const override { return Name->getBaseName(); }
744
745 void printLeft(OutputStream &S) const override {
746 if (!Cache.empty()) {
747 S += Cache;
748 return;
749 }
750
751 OutputStream::StreamPosition Start = S.getCurrentPosition();
752 if (Qualifier->K != KEmptyName) {
753 Qualifier->print(S);
754 S += "::";
755 }
756 Name->print(S);
757 Cache = S.makeStringViewFromPastPosition(Start);
758 }
759};
760
761class EmptyName : public Node {
762public:
763 EmptyName() : Node(KEmptyName) {}
764 void printLeft(OutputStream &) const override {}
765};
766
767class VectorType final : public Node {
768 const Node *BaseType;
769 const NodeOrString Dimension;
770 const bool IsPixel;
771
772public:
773 VectorType(NodeOrString Dimension)
774 : Node(KVectorType), BaseType(nullptr), Dimension(Dimension),
775 IsPixel(true) {}
776 VectorType(Node *BaseType, NodeOrString Dimension)
777 : Node(KVectorType), BaseType(BaseType), Dimension(Dimension),
778 IsPixel(false) {}
779
780 void printLeft(OutputStream &S) const override {
781 if (IsPixel) {
782 S += "pixel vector[";
783 S += Dimension.asString();
784 S += "]";
785 } else {
786 BaseType->print(S);
787 S += " vector[";
788 if (Dimension.isNode())
789 Dimension.asNode()->print(S);
790 else if (Dimension.isString())
791 S += Dimension.asString();
792 S += "]";
793 }
794 }
795};
796
797class TemplateParams final : public Node {
798 NodeArray Params;
799
800 mutable OutputStream::StreamStringView Cache;
801
802public:
803 TemplateParams(NodeArray Params) : Node(KTemplateParams), Params(Params) {}
804
805 void printLeft(OutputStream &S) const override {
806 if (!Cache.empty()) {
807 S += Cache;
808 return;
809 }
810
811 OutputStream::StreamPosition Start = S.getCurrentPosition();
812
813 S += "<";
814 Params.printWithSeperator(S, ", ");
815 if (S.back() == '>')
816 S += " ";
817 S += ">";
818
819 Cache = S.makeStringViewFromPastPosition(Start);
820 }
821};
822
823class NameWithTemplateArgs final : public Node {
824 // name<template_args>
825 Node *Name;
826 Node *TemplateArgs;
827
828public:
829 NameWithTemplateArgs(Node *Name, Node *TemplateArgs)
830 : Node(KNameWithTemplateArgs), Name(Name), TemplateArgs(TemplateArgs) {}
831
832 StringView getBaseName() const override { return Name->getBaseName(); }
833
834 void printLeft(OutputStream &S) const override {
835 Name->print(S);
836 TemplateArgs->print(S);
837 }
838};
839
840class GlobalQualifiedName final : public Node {
841 Node *Child;
842
843public:
844 GlobalQualifiedName(Node *Child) : Node(KGlobalQualifiedName), Child(Child) {}
845
846 StringView getBaseName() const override { return Child->getBaseName(); }
847
848 void printLeft(OutputStream &S) const override {
849 S += "::";
850 Child->print(S);
851 }
852};
853
854class StdQualifiedName final : public Node {
855 Node *Child;
856
857public:
858 StdQualifiedName(Node *Child) : Node(KStdQualifiedName), Child(Child) {}
859
860 StringView getBaseName() const override { return Child->getBaseName(); }
861
862 void printLeft(OutputStream &S) const override {
863 S += "std::";
864 Child->print(S);
865 }
866};
867
868enum class SpecialSubKind {
869 allocator,
870 basic_string,
871 string,
872 istream,
873 ostream,
874 iostream,
875};
876
877class ExpandedSpecialSubstitution final : public Node {
878 SpecialSubKind SSK;
879
880public:
881 ExpandedSpecialSubstitution(SpecialSubKind SSK)
882 : Node(KExpandedSpecialSubstitution), SSK(SSK) {}
883
884 StringView getBaseName() const override {
885 switch (SSK) {
886 case SpecialSubKind::allocator:
887 return StringView("allocator");
888 case SpecialSubKind::basic_string:
889 return StringView("basic_string");
890 case SpecialSubKind::string:
891 return StringView("basic_string");
892 case SpecialSubKind::istream:
893 return StringView("basic_istream");
894 case SpecialSubKind::ostream:
895 return StringView("basic_ostream");
896 case SpecialSubKind::iostream:
897 return StringView("basic_iostream");
898 }
Erik Pilkingtond25d9012017-08-01 02:38:40 +0000899 _LIBCPP_UNREACHABLE();
Erik Pilkington0024acd2017-07-28 00:43:49 +0000900 }
901
902 void printLeft(OutputStream &S) const override {
903 switch (SSK) {
904 case SpecialSubKind::allocator:
905 S += "std::basic_string<char, std::char_traits<char>, "
906 "std::allocator<char> >";
907 break;
908 case SpecialSubKind::basic_string:
909 case SpecialSubKind::string:
910 S += "std::basic_string<char, std::char_traits<char>, "
911 "std::allocator<char> >";
912 break;
913 case SpecialSubKind::istream:
914 S += "std::basic_istream<char, std::char_traits<char> >";
915 break;
916 case SpecialSubKind::ostream:
917 S += "std::basic_ostream<char, std::char_traits<char> >";
918 break;
919 case SpecialSubKind::iostream:
920 S += "std::basic_iostream<char, std::char_traits<char> >";
921 break;
922 }
923 }
924};
925
926class SpecialSubstitution final : public Node {
927public:
928 SpecialSubKind SSK;
929
930 SpecialSubstitution(SpecialSubKind SSK)
931 : Node(KSpecialSubstitution), SSK(SSK) {}
932
933 StringView getBaseName() const override {
934 switch (SSK) {
935 case SpecialSubKind::allocator:
936 return StringView("allocator");
937 case SpecialSubKind::basic_string:
938 return StringView("basic_string");
939 case SpecialSubKind::string:
940 return StringView("string");
941 case SpecialSubKind::istream:
942 return StringView("istream");
943 case SpecialSubKind::ostream:
944 return StringView("ostream");
945 case SpecialSubKind::iostream:
946 return StringView("iostream");
947 }
Erik Pilkingtond25d9012017-08-01 02:38:40 +0000948 _LIBCPP_UNREACHABLE();
Erik Pilkington0024acd2017-07-28 00:43:49 +0000949 }
950
951 void printLeft(OutputStream &S) const override {
952 switch (SSK) {
953 case SpecialSubKind::allocator:
954 S += "std::allocator";
955 break;
956 case SpecialSubKind::basic_string:
957 S += "std::basic_string";
958 break;
959 case SpecialSubKind::string:
960 S += "std::string";
961 break;
962 case SpecialSubKind::istream:
963 S += "std::istream";
964 break;
965 case SpecialSubKind::ostream:
966 S += "std::ostream";
967 break;
968 case SpecialSubKind::iostream:
969 S += "std::iostream";
970 break;
971 }
972 }
973};
974
975class CtorDtorName final : public Node {
976 const Node *Basename;
977 const bool IsDtor;
978
979public:
980 CtorDtorName(Node *Basename, bool IsDtor)
981 : Node(KCtorDtorName), Basename(Basename), IsDtor(IsDtor) {}
982
983 void printLeft(OutputStream &S) const override {
984 if (IsDtor)
985 S += "~";
986 S += Basename->getBaseName();
987 }
988};
989
990class DtorName : public Node {
991 const Node *Base;
992
993public:
994 DtorName(Node *Base) : Node(KDtorName), Base(Base) {}
995
996 void printLeft(OutputStream &S) const override {
997 S += "~";
998 Base->printLeft(S);
999 }
1000};
1001
1002class UnnamedTypeName : public Node {
1003 const StringView Count;
1004
1005public:
1006 UnnamedTypeName(StringView Count) : Node(KUnnamedTypeName), Count(Count) {}
1007
1008 void printLeft(OutputStream &S) const override {
1009 S += "'unnamed";
1010 S += Count;
1011 S += "\'";
1012 }
1013};
1014
1015class LambdaTypeName : public Node {
1016 NodeArray Params;
1017 StringView Count;
1018
1019public:
1020 LambdaTypeName(NodeArray Params, StringView Count)
1021 : Node(KLambdaTypeName), Params(Params), Count(Count) {}
1022
1023 void printLeft(OutputStream &S) const override {
1024 S += "\'lambda";
1025 S += Count;
1026 S += "\'(";
1027 Params.printWithSeperator(S, ", ");
1028 S += ")";
1029 }
1030};
1031
1032// -- Expression Nodes --
1033
1034struct Expr : public Node {
1035 Expr() : Node(KExpr) {}
1036};
1037
1038class BinaryExpr : public Expr {
1039 const Node *LHS;
1040 const StringView InfixOperator;
1041 const Node *RHS;
1042
1043public:
1044 BinaryExpr(Node *LHS, StringView InfixOperator, Node *RHS)
1045 : LHS(LHS), InfixOperator(InfixOperator), RHS(RHS) {}
1046
1047 void printLeft(OutputStream &S) const override {
1048 // might be a template argument expression, then we need to disambiguate
1049 // with parens.
1050 if (InfixOperator == ">")
1051 S += "(";
1052
1053 S += "(";
1054 LHS->print(S);
1055 S += ") ";
1056 S += InfixOperator;
1057 S += " (";
1058 RHS->print(S);
1059 S += ")";
1060
1061 if (InfixOperator == ">")
1062 S += ")";
1063 }
1064};
1065
1066class ArraySubscriptExpr : public Expr {
1067 const Node *Op1;
1068 const Node *Op2;
1069
1070public:
1071 ArraySubscriptExpr(Node *Op1, Node *Op2) : Op1(Op1), Op2(Op2) {}
1072
1073 void printLeft(OutputStream &S) const override {
1074 S += "(";
1075 Op1->print(S);
1076 S += ")[";
1077 Op2->print(S);
1078 S += "]";
1079 }
1080};
1081
1082class PostfixExpr : public Expr {
1083 const Node *Child;
1084 const StringView Operand;
1085
1086public:
1087 PostfixExpr(Node *Child, StringView Operand)
1088 : Child(Child), Operand(Operand) {}
1089
1090 void printLeft(OutputStream &S) const override {
1091 S += "(";
1092 Child->print(S);
1093 S += ")";
1094 S += Operand;
1095 }
1096};
1097
1098class ConditionalExpr : public Expr {
1099 const Node *Cond;
1100 const Node *Then;
1101 const Node *Else;
1102
1103public:
1104 ConditionalExpr(Node *Cond, Node *Then, Node *Else)
1105 : Cond(Cond), Then(Then), Else(Else) {}
1106
1107 void printLeft(OutputStream &S) const override {
1108 S += "(";
1109 Cond->print(S);
1110 S += ") ? (";
1111 Then->print(S);
1112 S += ") : (";
1113 Else->print(S);
1114 S += ")";
1115 }
1116};
1117
1118class MemberExpr : public Expr {
1119 const Node *LHS;
1120 const StringView Kind;
1121 const Node *RHS;
1122
1123public:
1124 MemberExpr(Node *LHS, StringView Kind, Node *RHS)
1125 : LHS(LHS), Kind(Kind), RHS(RHS) {}
1126
1127 void printLeft(OutputStream &S) const override {
1128 LHS->print(S);
1129 S += Kind;
1130 RHS->print(S);
1131 }
1132};
1133
1134class EnclosingExpr : public Expr {
1135 const StringView Prefix;
1136 const Node *Infix;
1137 const StringView Postfix;
1138
1139public:
1140 EnclosingExpr(StringView Prefix, Node *Infix, StringView Postfix)
1141 : Prefix(Prefix), Infix(Infix), Postfix(Postfix) {}
1142
1143 void printLeft(OutputStream &S) const override {
1144 S += Prefix;
1145 Infix->print(S);
1146 S += Postfix;
1147 }
1148};
1149
1150class CastExpr : public Expr {
1151 // cast_kind<to>(from)
1152 const StringView CastKind;
1153 const Node *To;
1154 const Node *From;
1155
1156public:
1157 CastExpr(StringView CastKind, Node *To, Node *From)
1158 : CastKind(CastKind), To(To), From(From) {}
1159
1160 void printLeft(OutputStream &S) const override {
1161 S += CastKind;
1162 S += "<";
1163 To->printLeft(S);
1164 S += ">(";
1165 From->printLeft(S);
1166 S += ")";
1167 }
1168};
1169
1170class SizeofParamPackExpr : public Expr {
1171 NodeArray Args;
1172
1173public:
1174 SizeofParamPackExpr(NodeArray Args) : Args(Args) {}
1175
1176 void printLeft(OutputStream &S) const override {
1177 S += "sizeof...(";
1178 Args.printWithSeperator(S, ", ");
1179 S += ")";
1180 }
1181};
1182
1183class CallExpr : public Expr {
1184 const Node *Callee;
1185 NodeArray Args;
1186
1187public:
1188 CallExpr(Node *Callee, NodeArray Args) : Callee(Callee), Args(Args) {}
1189
1190 void printLeft(OutputStream &S) const override {
1191 Callee->print(S);
1192 S += "(";
1193 Args.printWithSeperator(S, ", ");
1194 S += ")";
1195 }
1196};
1197
1198class NewExpr : public Expr {
1199 // new (expr_list) type(init_list)
1200 NodeArray ExprList;
1201 Node *Type;
1202 NodeArray InitList;
1203 bool IsGlobal; // ::operator new ?
1204 bool IsArray; // new[] ?
1205public:
1206 NewExpr(NodeArray ExprList, Node *Type, NodeArray InitList, bool IsGlobal,
1207 bool IsArray)
1208 : ExprList(ExprList), Type(Type), InitList(InitList), IsGlobal(IsGlobal),
1209 IsArray(IsArray) {}
1210
1211 void printLeft(OutputStream &S) const override {
1212 if (IsGlobal)
1213 S += "::operator ";
1214 S += "new";
1215 if (IsArray)
1216 S += "[]";
1217 if (!ExprList.empty()) {
1218 S += "(";
1219 ExprList.printWithSeperator(S, ", ");
1220 S += ")";
1221 }
1222 Type->print(S);
1223 if (!InitList.empty()) {
1224 S += "(";
1225 InitList.printWithSeperator(S, ", ");
1226 S += ")";
1227 }
1228 }
1229};
1230
1231class DeleteExpr : public Expr {
1232 Node *Op;
1233 bool IsGlobal;
1234 bool IsArray;
1235
1236public:
1237 DeleteExpr(Node *Op, bool IsGlobal, bool IsArray)
1238 : Op(Op), IsGlobal(IsGlobal), IsArray(IsArray) {}
1239
1240 void printLeft(OutputStream &S) const override {
1241 if (IsGlobal)
1242 S += "::";
1243 S += "delete";
1244 if (IsArray)
1245 S += "[] ";
1246 Op->print(S);
1247 }
1248};
1249
1250class PrefixExpr : public Expr {
1251 StringView Prefix;
1252 Node *Child;
1253
1254public:
1255 PrefixExpr(StringView Prefix, Node *Child) : Prefix(Prefix), Child(Child) {}
1256
1257 void printLeft(OutputStream &S) const override {
1258 S += Prefix;
1259 S += "(";
1260 Child->print(S);
1261 S += ")";
1262 }
1263};
1264
1265class FunctionParam : public Expr {
1266 StringView Number;
1267
1268public:
1269 FunctionParam(StringView Number) : Number(Number) {}
1270
1271 void printLeft(OutputStream &S) const override {
1272 S += "fp";
1273 S += Number;
1274 }
1275};
1276
1277class ExprList : public Expr {
1278 NodeArray SubExprs;
1279
1280public:
1281 ExprList(NodeArray SubExprs) : SubExprs(SubExprs) {}
1282
1283 void printLeft(OutputStream &S) const override {
1284 S += "(";
1285 SubExprs.printWithSeperator(S, ", ");
1286 S += ")";
1287 }
1288};
1289
1290class ConversionExpr : public Expr {
1291 NodeArray Expressions;
1292 NodeArray Types;
1293
1294public:
1295 ConversionExpr(NodeArray Expressions, NodeArray Types)
1296 : Expressions(Expressions), Types(Types) {}
1297
1298 void printLeft(OutputStream &S) const override {
1299 S += "(";
1300 Expressions.printWithSeperator(S, ", ");
1301 S += ")(";
1302 Types.printWithSeperator(S, ", ");
1303 S += ")";
1304 }
1305};
1306
1307class ThrowExpr : public Expr {
1308 const Node *Op;
1309
1310public:
1311 ThrowExpr(Node *Op) : Op(Op) {}
1312
1313 void printLeft(OutputStream &S) const override {
1314 S += "throw ";
1315 Op->print(S);
1316 }
1317};
1318
1319class BoolExpr : public Expr {
1320 bool Value;
1321
1322public:
1323 BoolExpr(bool Value) : Value(Value) {}
1324
1325 void printLeft(OutputStream &S) const override {
1326 S += Value ? StringView("true") : StringView("false");
1327 }
1328};
1329
1330class IntegerCastExpr : public Expr {
1331 // ty(integer)
1332 Node *Ty;
1333 StringView Integer;
1334
1335public:
1336 IntegerCastExpr(Node *Ty, StringView Integer) : Ty(Ty), Integer(Integer) {}
1337
1338 void printLeft(OutputStream &S) const override {
1339 S += "(";
1340 Ty->print(S);
1341 S += ")";
1342 S += Integer;
1343 }
1344};
1345
1346class IntegerExpr : public Expr {
1347 StringView Type;
1348 StringView Value;
1349
1350public:
1351 IntegerExpr(StringView Type, StringView Value) : Type(Type), Value(Value) {}
1352
1353 void printLeft(OutputStream &S) const override {
1354 if (Type.size() > 3) {
1355 S += "(";
1356 S += Type;
1357 S += ")";
1358 }
1359
1360 if (Value[0] == 'n') {
1361 S += "-";
1362 S += Value.dropFront(1);
1363 } else
1364 S += Value;
1365
1366 if (Type.size() <= 3)
1367 S += Type;
1368 }
1369};
1370
1371template <class Float> struct FloatData;
1372
1373template <class Float> class FloatExpr : public Expr {
1374 const StringView Contents;
1375
1376public:
1377 FloatExpr(StringView Contents) : Contents(Contents) {}
1378
1379 void printLeft(OutputStream &s) const override {
1380 const char *first = Contents.begin();
1381 const char *last = Contents.end() + 1;
1382
1383 const size_t N = FloatData<Float>::mangled_size;
1384 if (static_cast<std::size_t>(last - first) > N) {
1385 last = first + N;
1386 union {
1387 Float value;
1388 char buf[sizeof(Float)];
1389 };
1390 const char *t = first;
1391 char *e = buf;
1392 for (; t != last; ++t, ++e) {
1393 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1394 : static_cast<unsigned>(*t - 'a' + 10);
1395 ++t;
1396 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1397 : static_cast<unsigned>(*t - 'a' + 10);
1398 *e = static_cast<char>((d1 << 4) + d0);
1399 }
1400#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1401 std::reverse(buf, e);
1402#endif
1403 char num[FloatData<Float>::max_demangled_size] = {0};
1404 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
1405 s += StringView(num, num + n);
1406 }
1407 }
1408};
1409
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001410template <std::size_t N>
1411class arena
1412{
1413 static const std::size_t alignment = 16;
1414 alignas(alignment) char buf_[N];
1415 char* ptr_;
1416
1417 std::size_t
1418 align_up(std::size_t n) noexcept
1419 {return (n + (alignment-1)) & ~(alignment-1);}
1420
1421 bool
1422 pointer_in_buffer(char* p) noexcept
1423 {return buf_ <= p && p <= buf_ + N;}
1424
1425public:
1426 arena() noexcept : ptr_(buf_) {}
1427 ~arena() {ptr_ = nullptr;}
1428 arena(const arena&) = delete;
1429 arena& operator=(const arena&) = delete;
1430
1431 char* allocate(std::size_t n);
1432 void deallocate(char* p, std::size_t n) noexcept;
1433
1434 static constexpr std::size_t size() {return N;}
1435 std::size_t used() const {return static_cast<std::size_t>(ptr_ - buf_);}
1436 void reset() {ptr_ = buf_;}
1437};
1438
1439template <std::size_t N>
1440char*
1441arena<N>::allocate(std::size_t n)
1442{
1443 n = align_up(n);
1444 if (static_cast<std::size_t>(buf_ + N - ptr_) >= n)
1445 {
1446 char* r = ptr_;
1447 ptr_ += n;
1448 return r;
1449 }
1450 return static_cast<char*>(std::malloc(n));
1451}
1452
1453template <std::size_t N>
1454void
1455arena<N>::deallocate(char* p, std::size_t n) noexcept
1456{
1457 if (pointer_in_buffer(p))
1458 {
1459 n = align_up(n);
1460 if (p + n == ptr_)
1461 ptr_ = p;
1462 }
1463 else
1464 std::free(p);
1465}
1466
1467template <class T, std::size_t N>
1468class short_alloc
1469{
1470 arena<N>& a_;
1471public:
1472 typedef T value_type;
1473
1474public:
1475 template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;};
1476
1477 short_alloc(arena<N>& a) noexcept : a_(a) {}
1478 template <class U>
1479 short_alloc(const short_alloc<U, N>& a) noexcept
1480 : a_(a.a_) {}
1481 short_alloc(const short_alloc&) = default;
1482 short_alloc& operator=(const short_alloc&) = delete;
1483
1484 T* allocate(std::size_t n)
1485 {
1486 return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
1487 }
1488 void deallocate(T* p, std::size_t n) noexcept
1489 {
1490 a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
1491 }
1492
1493 template <class T1, std::size_t N1, class U, std::size_t M>
1494 friend
1495 bool
1496 operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) noexcept;
1497
1498 template <class U, std::size_t M> friend class short_alloc;
1499};
1500
1501template <class T, std::size_t N, class U, std::size_t M>
1502inline
1503bool
1504operator==(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
1505{
1506 return N == M && &x.a_ == &y.a_;
1507}
1508
1509template <class T, std::size_t N, class U, std::size_t M>
1510inline
1511bool
1512operator!=(const short_alloc<T, N>& x, const short_alloc<U, M>& y) noexcept
1513{
1514 return !(x == y);
1515}
1516
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001517const size_t bs = 4 * 1024;
1518template <class T> using Alloc = short_alloc<T, bs>;
1519template <class T> using Vector = std::vector<T, Alloc<T>>;
1520
Erik Pilkington0024acd2017-07-28 00:43:49 +00001521class BumpPointerAllocator {
1522 struct BlockMeta {
1523 BlockMeta* Next;
1524 size_t Current;
1525 };
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001526
Erik Pilkington0024acd2017-07-28 00:43:49 +00001527 static constexpr size_t AllocSize = 4096;
1528 static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001529
Erik Pilkington0024acd2017-07-28 00:43:49 +00001530 alignas(16) char InitialBuffer[AllocSize];
1531 BlockMeta* BlockList = nullptr;
1532
1533 void grow() {
1534 char* NewMeta = new char[AllocSize];
1535 BlockList = new (NewMeta) BlockMeta{BlockList, 0};
1536 }
1537
1538 void* allocateMassive(size_t NBytes) {
1539 NBytes += sizeof(BlockMeta);
1540 BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(new char[NBytes]);
1541 BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
1542 return static_cast<void*>(NewMeta + 1);
1543 }
1544
1545public:
1546 BumpPointerAllocator()
1547 : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
1548
1549 void* allocate(size_t N) {
1550 N = (N + 15u) & ~15u;
1551 if (N + BlockList->Current >= UsableAllocSize) {
1552 if (N > UsableAllocSize)
1553 return allocateMassive(N);
1554 grow();
1555 }
1556 BlockList->Current += N;
1557 return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
1558 BlockList->Current - N);
1559 }
1560
1561 ~BumpPointerAllocator() {
1562 while (BlockList) {
1563 BlockMeta* Tmp = BlockList;
1564 BlockList = BlockList->Next;
1565 if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
1566 delete[] reinterpret_cast<char*>(Tmp);
1567 }
1568 }
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001569};
1570
1571struct Db
1572{
Erik Pilkington0024acd2017-07-28 00:43:49 +00001573 typedef Vector<Node*> sub_type;
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001574 typedef Vector<sub_type> template_param_type;
1575 sub_type names;
1576 template_param_type subs;
1577 Vector<template_param_type> template_param;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001578 Qualifiers cv = QualNone;
1579 FunctionRefQual ref = FrefQualNone;
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001580 unsigned encoding_depth = 0;
1581 bool parsed_ctor_dtor_cv = false;
1582 bool tag_templates = true;
1583 bool fix_forward_references = false;
1584 bool try_to_parse_template_args = true;
1585
Erik Pilkington0024acd2017-07-28 00:43:49 +00001586 BumpPointerAllocator ASTAllocator;
1587
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001588 template <size_t N>
1589 Db(arena<N>& ar) :
1590 names(ar),
1591 subs(0, names, ar),
1592 template_param(0, subs, ar)
1593 {}
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001594
Erik Pilkington0024acd2017-07-28 00:43:49 +00001595 template <class T, class... Args> T* make(Args&& ...args)
1596 {
1597 return new (ASTAllocator.allocate(sizeof(T)))
1598 T(std::forward<Args>(args)...);
1599 }
1600
1601 template <class It> NodeArray makeNodeArray(It begin, It end)
1602 {
1603 size_t sz = static_cast<size_t>(end - begin);
1604 void* mem = ASTAllocator.allocate(sizeof(Node*) * sz);
1605 Node** data = new (mem) Node*[sz];
1606 std::copy(begin, end, data);
1607 return NodeArray(data, sz);
1608 }
1609
1610 NodeArray popTrailingNodeArray(size_t FromPosition)
1611 {
1612 assert(FromPosition <= names.size());
1613 NodeArray res = makeNodeArray(
1614 names.begin() + (long)FromPosition, names.end());
1615 names.erase(names.begin() + (long)FromPosition, names.end());
1616 return res;
1617 }
1618};
Erik Pilkingtonc3926622017-07-08 18:54:08 +00001619
1620const char* parse_type(const char* first, const char* last, Db& db);
1621const char* parse_encoding(const char* first, const char* last, Db& db);
1622const char* parse_name(const char* first, const char* last, Db& db,
1623 bool* ends_with_template_args = 0);
1624const char* parse_expression(const char* first, const char* last, Db& db);
1625const char* parse_template_args(const char* first, const char* last, Db& db);
1626const char* parse_operator_name(const char* first, const char* last, Db& db);
1627const char* parse_unqualified_name(const char* first, const char* last, Db& db);
1628const char* parse_decltype(const char* first, const char* last, Db& db);
1629
Howard Hinnant6c33e762013-06-17 18:10:34 +00001630// <number> ::= [n] <non-negative decimal integer>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001631
1632const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00001633parse_number(const char* first, const char* last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001634{
Howard Hinnant6c33e762013-06-17 18:10:34 +00001635 if (first != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001636 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001637 const char* t = first;
1638 if (*t == 'n')
1639 ++t;
1640 if (t != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001641 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001642 if (*t == '0')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001643 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001644 first = t+1;
1645 }
1646 else if ('1' <= *t && *t <= '9')
1647 {
1648 first = t+1;
1649 while (first != last && std::isdigit(*first))
1650 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001651 }
1652 }
1653 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00001654 return first;
1655}
1656
1657template <class Float>
Erik Pilkington0024acd2017-07-28 00:43:49 +00001658struct FloatData;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001659
1660template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00001661struct FloatData<float>
Howard Hinnant6c33e762013-06-17 18:10:34 +00001662{
1663 static const size_t mangled_size = 8;
1664 static const size_t max_demangled_size = 24;
Howard Hinnantc62cbea2013-06-17 20:25:21 +00001665 static constexpr const char* spec = "%af";
Howard Hinnant6c33e762013-06-17 18:10:34 +00001666};
1667
Erik Pilkington0024acd2017-07-28 00:43:49 +00001668constexpr const char* FloatData<float>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001669
1670template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00001671struct FloatData<double>
Howard Hinnant6c33e762013-06-17 18:10:34 +00001672{
1673 static const size_t mangled_size = 16;
1674 static const size_t max_demangled_size = 32;
1675 static constexpr const char* spec = "%a";
Howard Hinnant6c33e762013-06-17 18:10:34 +00001676};
1677
Erik Pilkington0024acd2017-07-28 00:43:49 +00001678constexpr const char* FloatData<double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001679
1680template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00001681struct FloatData<long double>
Howard Hinnant6c33e762013-06-17 18:10:34 +00001682{
Dan Gohmand04ecd02016-01-13 16:39:30 +00001683#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
1684 defined(__wasm__)
Daniel Sanders52cf98b2015-07-30 16:11:04 +00001685 static const size_t mangled_size = 32;
Ben Craig9ef2c6e2016-01-20 14:10:23 +00001686#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
Logan Chien05d51bc2014-05-10 00:42:10 +00001687 static const size_t mangled_size = 16;
1688#else
Howard Hinnant6c33e762013-06-17 18:10:34 +00001689 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
Logan Chien05d51bc2014-05-10 00:42:10 +00001690#endif
Howard Hinnant6c33e762013-06-17 18:10:34 +00001691 static const size_t max_demangled_size = 40;
Howard Hinnantc62cbea2013-06-17 20:25:21 +00001692 static constexpr const char* spec = "%LaL";
Howard Hinnant6c33e762013-06-17 18:10:34 +00001693};
1694
Erik Pilkington0024acd2017-07-28 00:43:49 +00001695constexpr const char* FloatData<long double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001696
Erik Pilkingtonc3926622017-07-08 18:54:08 +00001697template <class Float>
Howard Hinnant6c33e762013-06-17 18:10:34 +00001698const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00001699parse_floating_number(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00001700{
Erik Pilkington0024acd2017-07-28 00:43:49 +00001701 const size_t N = FloatData<Float>::mangled_size;
1702 if (static_cast<std::size_t>(last - first) <= N)
1703 return first;
1704 last = first + N;
1705 const char* t = first;
1706 for (; t != last; ++t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001707 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00001708 if (!isxdigit(*t))
1709 return first;
1710 }
1711 if (*t == 'E')
1712 {
1713 db.names.push_back(
1714 db.make<FloatExpr<Float>>(StringView(first, t)));
1715 first = t + 1;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001716 }
1717 return first;
1718}
1719
1720// <source-name> ::= <positive length number> <identifier>
1721
Howard Hinnant6c33e762013-06-17 18:10:34 +00001722const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00001723parse_source_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00001724{
1725 if (first != last)
1726 {
1727 char c = *first;
1728 if (isdigit(c) && first+1 != last)
1729 {
1730 const char* t = first+1;
1731 size_t n = static_cast<size_t>(c - '0');
1732 for (c = *t; isdigit(c); c = *t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001733 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00001734 n = n * 10 + static_cast<size_t>(c - '0');
1735 if (++t == last)
1736 return first;
1737 }
1738 if (static_cast<size_t>(last - t) >= n)
1739 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00001740 StringView r(t, t + n);
Howard Hinnant6c33e762013-06-17 18:10:34 +00001741 if (r.substr(0, 10) == "_GLOBAL__N")
Erik Pilkington0024acd2017-07-28 00:43:49 +00001742 db.names.push_back(db.make<NameType>("(anonymous namespace)"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001743 else
Erik Pilkington0024acd2017-07-28 00:43:49 +00001744 db.names.push_back(db.make<NameType>(r));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001745 first = t + n;
1746 }
1747 }
1748 }
1749 return first;
1750}
1751
1752// <substitution> ::= S <seq-id> _
1753// ::= S_
1754// <substitution> ::= Sa # ::std::allocator
1755// <substitution> ::= Sb # ::std::basic_string
1756// <substitution> ::= Ss # ::std::basic_string < char,
1757// ::std::char_traits<char>,
1758// ::std::allocator<char> >
1759// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
1760// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
1761// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
1762
Howard Hinnant6c33e762013-06-17 18:10:34 +00001763const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00001764parse_substitution(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00001765{
1766 if (last - first >= 2)
1767 {
1768 if (*first == 'S')
1769 {
1770 switch (first[1])
1771 {
1772 case 'a':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001773 db.names.push_back(
1774 db.make<SpecialSubstitution>(
1775 SpecialSubKind::allocator));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001776 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001777 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001778 case 'b':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001779 db.names.push_back(
1780 db.make<SpecialSubstitution>(SpecialSubKind::basic_string));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001781 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001782 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00001783 case 's':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001784 db.names.push_back(
1785 db.make<SpecialSubstitution>(
1786 SpecialSubKind::string));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001787 first += 2;
1788 break;
1789 case 'i':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001790 db.names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::istream));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001791 first += 2;
1792 break;
1793 case 'o':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001794 db.names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::ostream));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001795 first += 2;
1796 break;
1797 case 'd':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001798 db.names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::iostream));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001799 first += 2;
1800 break;
1801 case '_':
1802 if (!db.subs.empty())
1803 {
1804 for (const auto& n : db.subs.front())
1805 db.names.push_back(n);
1806 first += 2;
1807 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001808 break;
1809 default:
Howard Hinnant6c33e762013-06-17 18:10:34 +00001810 if (std::isdigit(first[1]) || std::isupper(first[1]))
1811 {
1812 size_t sub = 0;
1813 const char* t = first+1;
1814 if (std::isdigit(*t))
1815 sub = static_cast<size_t>(*t - '0');
1816 else
1817 sub = static_cast<size_t>(*t - 'A') + 10;
1818 for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t)
1819 {
1820 sub *= 36;
1821 if (std::isdigit(*t))
1822 sub += static_cast<size_t>(*t - '0');
1823 else
1824 sub += static_cast<size_t>(*t - 'A') + 10;
1825 }
1826 if (t == last || *t != '_')
1827 return first;
1828 ++sub;
1829 if (sub < db.subs.size())
1830 {
1831 for (const auto& n : db.subs[sub])
1832 db.names.push_back(n);
1833 first = t+1;
1834 }
1835 }
1836 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001837 }
1838 }
1839 }
1840 return first;
1841}
1842
1843// <builtin-type> ::= v # void
1844// ::= w # wchar_t
1845// ::= b # bool
1846// ::= c # char
1847// ::= a # signed char
1848// ::= h # unsigned char
1849// ::= s # short
1850// ::= t # unsigned short
1851// ::= i # int
1852// ::= j # unsigned int
1853// ::= l # long
1854// ::= m # unsigned long
1855// ::= x # long long, __int64
1856// ::= y # unsigned long long, __int64
1857// ::= n # __int128
1858// ::= o # unsigned __int128
1859// ::= f # float
1860// ::= d # double
1861// ::= e # long double, __float80
1862// ::= g # __float128
1863// ::= z # ellipsis
1864// ::= Dd # IEEE 754r decimal floating point (64 bits)
1865// ::= De # IEEE 754r decimal floating point (128 bits)
1866// ::= Df # IEEE 754r decimal floating point (32 bits)
1867// ::= Dh # IEEE 754r half-precision floating point (16 bits)
1868// ::= Di # char32_t
1869// ::= Ds # char16_t
1870// ::= Da # auto (in dependent new-expressions)
Anders Carlsson2950e562014-02-17 21:56:01 +00001871// ::= Dc # decltype(auto)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001872// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
1873// ::= u <source-name> # vendor extended type
1874
1875const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00001876parse_builtin_type(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001877{
1878 if (first != last)
1879 {
1880 switch (*first)
1881 {
1882 case 'v':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001883 db.names.push_back(db.make<NameType>("void"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001884 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001885 break;
1886 case 'w':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001887 db.names.push_back(db.make<NameType>("wchar_t"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001888 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001889 break;
1890 case 'b':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001891 db.names.push_back(db.make<NameType>("bool"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001892 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001893 break;
1894 case 'c':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001895 db.names.push_back(db.make<NameType>("char"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001896 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001897 break;
1898 case 'a':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001899 db.names.push_back(db.make<NameType>("signed char"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001900 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001901 break;
1902 case 'h':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001903 db.names.push_back(db.make<NameType>("unsigned char"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001904 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001905 break;
1906 case 's':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001907 db.names.push_back(db.make<NameType>("short"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001908 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001909 break;
1910 case 't':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001911 db.names.push_back(db.make<NameType>("unsigned short"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001912 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001913 break;
1914 case 'i':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001915 db.names.push_back(db.make<NameType>("int"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001916 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001917 break;
1918 case 'j':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001919 db.names.push_back(db.make<NameType>("unsigned int"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001920 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001921 break;
1922 case 'l':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001923 db.names.push_back(db.make<NameType>("long"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001924 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001925 break;
1926 case 'm':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001927 db.names.push_back(db.make<NameType>("unsigned long"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001928 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001929 break;
1930 case 'x':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001931 db.names.push_back(db.make<NameType>("long long"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001932 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001933 break;
1934 case 'y':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001935 db.names.push_back(db.make<NameType>("unsigned long long"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001936 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001937 break;
1938 case 'n':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001939 db.names.push_back(db.make<NameType>("__int128"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001940 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001941 break;
1942 case 'o':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001943 db.names.push_back(db.make<NameType>("unsigned __int128"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001944 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001945 break;
1946 case 'f':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001947 db.names.push_back(db.make<NameType>("float"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001948 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001949 break;
1950 case 'd':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001951 db.names.push_back(db.make<NameType>("double"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001952 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001953 break;
1954 case 'e':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001955 db.names.push_back(db.make<NameType>("long double"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001956 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001957 break;
1958 case 'g':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001959 db.names.push_back(db.make<NameType>("__float128"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001960 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001961 break;
1962 case 'z':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001963 db.names.push_back(db.make<NameType>("..."));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001964 ++first;
1965 break;
1966 case 'u':
1967 {
1968 const char*t = parse_source_name(first+1, last, db);
1969 if (t != first+1)
1970 first = t;
1971 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001972 break;
1973 case 'D':
1974 if (first+1 != last)
1975 {
1976 switch (first[1])
1977 {
1978 case 'd':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001979 db.names.push_back(db.make<NameType>("decimal64"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001980 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001981 break;
1982 case 'e':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001983 db.names.push_back(db.make<NameType>("decimal128"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001984 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001985 break;
1986 case 'f':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001987 db.names.push_back(db.make<NameType>("decimal32"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001988 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001989 break;
1990 case 'h':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001991 db.names.push_back(db.make<NameType>("decimal16"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001992 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001993 break;
1994 case 'i':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001995 db.names.push_back(db.make<NameType>("char32_t"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00001996 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00001997 break;
1998 case 's':
Erik Pilkington0024acd2017-07-28 00:43:49 +00001999 db.names.push_back(db.make<NameType>("char16_t"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002000 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002001 break;
2002 case 'a':
Erik Pilkington0024acd2017-07-28 00:43:49 +00002003 db.names.push_back(db.make<NameType>("auto"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002004 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002005 break;
Anders Carlsson2950e562014-02-17 21:56:01 +00002006 case 'c':
Erik Pilkington0024acd2017-07-28 00:43:49 +00002007 db.names.push_back(db.make<NameType>("decltype(auto)"));
Anders Carlsson2950e562014-02-17 21:56:01 +00002008 first += 2;
2009 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002010 case 'n':
Erik Pilkington0024acd2017-07-28 00:43:49 +00002011 db.names.push_back(db.make<NameType>("std::nullptr_t"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002012 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002013 break;
2014 }
2015 }
2016 break;
2017 }
2018 }
2019 return first;
2020}
2021
Erik Pilkington0024acd2017-07-28 00:43:49 +00002022// <CV-Qualifiers> ::= [r] [V] [K]
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002023
2024const char*
Erik Pilkington0024acd2017-07-28 00:43:49 +00002025parse_cv_qualifiers(const char* first, const char* last, Qualifiers& cv)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002026{
Erik Pilkington0024acd2017-07-28 00:43:49 +00002027 cv = QualNone;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002028 if (first != last)
2029 {
2030 if (*first == 'r')
2031 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002032 addQualifiers(cv, QualRestrict);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002033 ++first;
2034 }
2035 if (*first == 'V')
2036 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002037 addQualifiers(cv, QualVolatile);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002038 ++first;
2039 }
2040 if (*first == 'K')
2041 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002042 addQualifiers(cv, QualConst);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002043 ++first;
2044 }
2045 }
2046 return first;
2047}
2048
2049// <template-param> ::= T_ # first template parameter
2050// ::= T <parameter-2 non-negative number> _
2051
Howard Hinnant6c33e762013-06-17 18:10:34 +00002052const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002053parse_template_param(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002054{
2055 if (last - first >= 2)
2056 {
2057 if (*first == 'T')
2058 {
2059 if (first[1] == '_')
2060 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002061 if (db.template_param.empty())
2062 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002063 if (!db.template_param.back().empty())
2064 {
2065 for (auto& t : db.template_param.back().front())
2066 db.names.push_back(t);
2067 first += 2;
2068 }
2069 else
2070 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002071 db.names.push_back(db.make<NameType>("T_"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002072 first += 2;
2073 db.fix_forward_references = true;
2074 }
2075 }
2076 else if (isdigit(first[1]))
2077 {
2078 const char* t = first+1;
2079 size_t sub = static_cast<size_t>(*t - '0');
2080 for (++t; t != last && isdigit(*t); ++t)
2081 {
2082 sub *= 10;
2083 sub += static_cast<size_t>(*t - '0');
2084 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00002085 if (t == last || *t != '_' || db.template_param.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00002086 return first;
2087 ++sub;
2088 if (sub < db.template_param.back().size())
2089 {
2090 for (auto& temp : db.template_param.back()[sub])
2091 db.names.push_back(temp);
2092 first = t+1;
2093 }
2094 else
2095 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002096 db.names.push_back(
2097 db.make<NameType>(StringView(first, t + 1)));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002098 first = t+1;
2099 db.fix_forward_references = true;
2100 }
2101 }
2102 }
2103 }
2104 return first;
2105}
2106
2107// cc <type> <expression> # const_cast<type> (expression)
2108
Howard Hinnant6c33e762013-06-17 18:10:34 +00002109const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002110parse_const_cast_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002111{
2112 if (last - first >= 3 && first[0] == 'c' && first[1] == 'c')
2113 {
2114 const char* t = parse_type(first+2, last, db);
2115 if (t != first+2)
2116 {
2117 const char* t1 = parse_expression(t, last, db);
2118 if (t1 != t)
2119 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002120 if (db.names.size() < 2)
2121 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002122 auto from_expr = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002123 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00002124 if (db.names.empty())
2125 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002126 db.names.back() = db.make<CastExpr>(
2127 "const_cast", db.names.back(), from_expr);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002128 first = t1;
2129 }
2130 }
2131 }
2132 return first;
2133}
2134
2135// dc <type> <expression> # dynamic_cast<type> (expression)
2136
Howard Hinnant6c33e762013-06-17 18:10:34 +00002137const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002138parse_dynamic_cast_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002139{
2140 if (last - first >= 3 && first[0] == 'd' && first[1] == 'c')
2141 {
2142 const char* t = parse_type(first+2, last, db);
2143 if (t != first+2)
2144 {
2145 const char* t1 = parse_expression(t, last, db);
2146 if (t1 != t)
2147 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002148 if (db.names.size() < 2)
2149 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002150 auto from_expr = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002151 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00002152 if (db.names.empty())
2153 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002154 db.names.back() = db.make<CastExpr>(
2155 "dynamic_cast", db.names.back(), from_expr);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002156 first = t1;
2157 }
2158 }
2159 }
2160 return first;
2161}
2162
2163// rc <type> <expression> # reinterpret_cast<type> (expression)
2164
Howard Hinnant6c33e762013-06-17 18:10:34 +00002165const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002166parse_reinterpret_cast_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002167{
2168 if (last - first >= 3 && first[0] == 'r' && first[1] == 'c')
2169 {
2170 const char* t = parse_type(first+2, last, db);
2171 if (t != first+2)
2172 {
2173 const char* t1 = parse_expression(t, last, db);
2174 if (t1 != t)
2175 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002176 if (db.names.size() < 2)
2177 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002178 auto from_expr = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002179 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00002180 if (db.names.empty())
2181 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002182 db.names.back() = db.make<CastExpr>(
2183 "reinterpret_cast", db.names.back(), from_expr);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002184 first = t1;
2185 }
2186 }
2187 }
2188 return first;
2189}
2190
2191// sc <type> <expression> # static_cast<type> (expression)
2192
Howard Hinnant6c33e762013-06-17 18:10:34 +00002193const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002194parse_static_cast_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002195{
2196 if (last - first >= 3 && first[0] == 's' && first[1] == 'c')
2197 {
2198 const char* t = parse_type(first+2, last, db);
2199 if (t != first+2)
2200 {
2201 const char* t1 = parse_expression(t, last, db);
2202 if (t1 != t)
2203 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002204 if (db.names.size() < 2)
2205 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002206 auto from_expr = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002207 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002208 db.names.back() = db.make<CastExpr>(
2209 "static_cast", db.names.back(), from_expr);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002210 first = t1;
2211 }
2212 }
2213 }
2214 return first;
2215}
2216
2217// sp <expression> # pack expansion
2218
Howard Hinnant6c33e762013-06-17 18:10:34 +00002219const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002220parse_pack_expansion(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002221{
2222 if (last - first >= 3 && first[0] == 's' && first[1] == 'p')
2223 {
2224 const char* t = parse_expression(first+2, last, db);
2225 if (t != first+2)
2226 first = t;
2227 }
2228 return first;
2229}
2230
2231// st <type> # sizeof (a type)
2232
Howard Hinnant6c33e762013-06-17 18:10:34 +00002233const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002234parse_sizeof_type_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002235{
2236 if (last - first >= 3 && first[0] == 's' && first[1] == 't')
2237 {
2238 const char* t = parse_type(first+2, last, db);
2239 if (t != first+2)
2240 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002241 if (db.names.empty())
2242 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002243 db.names.back() = db.make<EnclosingExpr>(
2244 "sizeof (", db.names.back(), ")");
Howard Hinnant6c33e762013-06-17 18:10:34 +00002245 first = t;
2246 }
2247 }
2248 return first;
2249}
2250
2251// sz <expr> # sizeof (a expression)
2252
Howard Hinnant6c33e762013-06-17 18:10:34 +00002253const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002254parse_sizeof_expr_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002255{
2256 if (last - first >= 3 && first[0] == 's' && first[1] == 'z')
2257 {
2258 const char* t = parse_expression(first+2, last, db);
2259 if (t != first+2)
2260 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002261 if (db.names.empty())
2262 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002263 db.names.back() = db.make<EnclosingExpr>(
2264 "sizeof (", db.names.back(), ")");
Howard Hinnant6c33e762013-06-17 18:10:34 +00002265 first = t;
2266 }
2267 }
2268 return first;
2269}
2270
2271// sZ <template-param> # size of a parameter pack
2272
Howard Hinnant6c33e762013-06-17 18:10:34 +00002273const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002274parse_sizeof_param_pack_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002275{
2276 if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'T')
2277 {
2278 size_t k0 = db.names.size();
2279 const char* t = parse_template_param(first+2, last, db);
2280 size_t k1 = db.names.size();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002281 if (t != first+2 && k0 <= k1)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002282 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002283 Node* sizeof_expr = db.make<SizeofParamPackExpr>(
2284 db.popTrailingNodeArray(k0));
2285 db.names.push_back(sizeof_expr);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002286 first = t;
2287 }
2288 }
2289 return first;
2290}
2291
Erik Pilkington0024acd2017-07-28 00:43:49 +00002292// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
2293// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
2294// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
2295// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
Howard Hinnant6c33e762013-06-17 18:10:34 +00002296
Howard Hinnant6c33e762013-06-17 18:10:34 +00002297const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002298parse_function_param(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002299{
2300 if (last - first >= 3 && *first == 'f')
2301 {
2302 if (first[1] == 'p')
2303 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002304 Qualifiers cv;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002305 const char* t = parse_cv_qualifiers(first+2, last, cv);
2306 const char* t1 = parse_number(t, last);
2307 if (t1 != last && *t1 == '_')
2308 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002309 db.names.push_back(
2310 db.make<FunctionParam>(StringView(t, t1)));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002311 first = t1+1;
2312 }
2313 }
2314 else if (first[1] == 'L')
2315 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002316 Qualifiers cv;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002317 const char* t0 = parse_number(first+2, last);
2318 if (t0 != last && *t0 == 'p')
2319 {
2320 ++t0;
2321 const char* t = parse_cv_qualifiers(t0, last, cv);
2322 const char* t1 = parse_number(t, last);
2323 if (t1 != last && *t1 == '_')
2324 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002325 db.names.push_back(
2326 db.make<FunctionParam>(StringView(t, t1)));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002327 first = t1+1;
2328 }
2329 }
2330 }
2331 }
2332 return first;
2333}
2334
2335// sZ <function-param> # size of a function parameter pack
2336
Howard Hinnant6c33e762013-06-17 18:10:34 +00002337const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002338parse_sizeof_function_param_pack_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002339{
2340 if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'f')
2341 {
2342 const char* t = parse_function_param(first+2, last, db);
2343 if (t != first+2)
2344 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002345 if (db.names.empty())
2346 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002347 db.names.back() = db.make<EnclosingExpr>(
2348 "sizeof...(", db.names.back(), ")");
Howard Hinnant6c33e762013-06-17 18:10:34 +00002349 first = t;
2350 }
2351 }
2352 return first;
2353}
2354
2355// te <expression> # typeid (expression)
2356// ti <type> # typeid (type)
2357
Howard Hinnant6c33e762013-06-17 18:10:34 +00002358const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002359parse_typeid_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002360{
2361 if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i'))
2362 {
2363 const char* t;
2364 if (first[1] == 'e')
2365 t = parse_expression(first+2, last, db);
2366 else
2367 t = parse_type(first+2, last, db);
2368 if (t != first+2)
2369 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002370 if (db.names.empty())
2371 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002372 db.names.back() = db.make<EnclosingExpr>(
2373 "typeid(", db.names.back(), ")");
Howard Hinnant6c33e762013-06-17 18:10:34 +00002374 first = t;
2375 }
2376 }
2377 return first;
2378}
2379
2380// tw <expression> # throw expression
2381
Howard Hinnant6c33e762013-06-17 18:10:34 +00002382const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002383parse_throw_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002384{
2385 if (last - first >= 3 && first[0] == 't' && first[1] == 'w')
2386 {
2387 const char* t = parse_expression(first+2, last, db);
2388 if (t != first+2)
2389 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002390 if (db.names.empty())
2391 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002392 db.names.back() = db.make<ThrowExpr>(db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00002393 first = t;
2394 }
2395 }
2396 return first;
2397}
2398
2399// ds <expression> <expression> # expr.*expr
2400
Howard Hinnant6c33e762013-06-17 18:10:34 +00002401const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002402parse_dot_star_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002403{
2404 if (last - first >= 3 && first[0] == 'd' && first[1] == 's')
2405 {
2406 const char* t = parse_expression(first+2, last, db);
2407 if (t != first+2)
2408 {
2409 const char* t1 = parse_expression(t, last, db);
2410 if (t1 != t)
2411 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002412 if (db.names.size() < 2)
2413 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002414 auto rhs_expr = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002415 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002416 db.names.back() = db.make<MemberExpr>(
2417 db.names.back(), ".*", rhs_expr);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002418 first = t1;
2419 }
2420 }
2421 }
2422 return first;
2423}
2424
2425// <simple-id> ::= <source-name> [ <template-args> ]
2426
Howard Hinnant6c33e762013-06-17 18:10:34 +00002427const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002428parse_simple_id(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002429{
2430 if (first != last)
2431 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002432 const char* t = parse_source_name(first, last, db);
2433 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002434 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002435 const char* t1 = parse_template_args(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002436 if (t1 != t)
2437 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002438 if (db.names.size() < 2)
2439 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002440 auto args = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002441 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002442 db.names.back() =
2443 db.make<NameWithTemplateArgs>(db.names.back(), args);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002444 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002445 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002446 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002447 else
Howard Hinnant6c33e762013-06-17 18:10:34 +00002448 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002449 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002450 return first;
2451}
2452
Howard Hinnant6c33e762013-06-17 18:10:34 +00002453// <unresolved-type> ::= <template-param>
2454// ::= <decltype>
2455// ::= <substitution>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002456
2457const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002458parse_unresolved_type(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002459{
Howard Hinnant6c33e762013-06-17 18:10:34 +00002460 if (first != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002461 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002462 const char* t = first;
2463 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002464 {
Howard Hinnant86ccacd2012-09-13 23:49:59 +00002465 case 'T':
Howard Hinnant6c33e762013-06-17 18:10:34 +00002466 {
2467 size_t k0 = db.names.size();
2468 t = parse_template_param(first, last, db);
2469 size_t k1 = db.names.size();
2470 if (t != first && k1 == k0 + 1)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002471 {
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002472 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002473 first = t;
Howard Hinnantab039992012-08-01 18:56:46 +00002474 }
2475 else
Howard Hinnant342f2f92012-11-30 18:43:50 +00002476 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002477 for (; k1 != k0; --k1)
2478 db.names.pop_back();
Howard Hinnant342f2f92012-11-30 18:43:50 +00002479 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +00002480 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002481 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002482 case 'D':
Howard Hinnant6c33e762013-06-17 18:10:34 +00002483 t = parse_decltype(first, last, db);
2484 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002485 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002486 if (db.names.empty())
2487 return first;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002488 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002489 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002490 }
2491 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002492 case 'S':
2493 t = parse_substitution(first, last, db);
2494 if (t != first)
2495 first = t;
2496 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002497 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002498 if (last - first > 2 && first[1] == 't')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002499 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002500 t = parse_unqualified_name(first+2, last, db);
2501 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002502 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002503 if (db.names.empty())
2504 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002505 db.names.back() =
2506 db.make<StdQualifiedName>(db.names.back());
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002507 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002508 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002509 }
2510 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002511 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002512 break;
2513 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002514 }
2515 return first;
2516}
2517
2518// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
2519// ::= <simple-id> # e.g., ~A<2*N>
2520
2521const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002522parse_destructor_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002523{
2524 if (first != last)
2525 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002526 const char* t = parse_unresolved_type(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002527 if (t == first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002528 t = parse_simple_id(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002529 if (t != first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002530 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002531 if (db.names.empty())
2532 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002533 db.names.back() = db.make<DtorName>(db.names.back());
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002534 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002535 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002536 }
2537 return first;
2538}
2539
2540// <base-unresolved-name> ::= <simple-id> # unresolved name
2541// extension ::= <operator-name> # unresolved operator-function-id
2542// extension ::= <operator-name> <template-args> # unresolved operator template-id
2543// ::= on <operator-name> # unresolved operator-function-id
2544// ::= on <operator-name> <template-args> # unresolved operator template-id
2545// ::= dn <destructor-name> # destructor or pseudo-destructor;
2546// # e.g. ~X or ~X<N-1>
2547
2548const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002549parse_base_unresolved_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002550{
2551 if (last - first >= 2)
2552 {
2553 if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n')
2554 {
2555 if (first[0] == 'o')
2556 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002557 const char* t = parse_operator_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002558 if (t != first+2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002559 {
2560 first = parse_template_args(t, last, db);
2561 if (first != t)
2562 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002563 if (db.names.size() < 2)
2564 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002565 auto args = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002566 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002567 db.names.back() =
2568 db.make<NameWithTemplateArgs>(
2569 db.names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002570 }
2571 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002572 }
2573 else
2574 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002575 const char* t = parse_destructor_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002576 if (t != first+2)
2577 first = t;
2578 }
2579 }
2580 else
2581 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002582 const char* t = parse_simple_id(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002583 if (t == first)
2584 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002585 t = parse_operator_name(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002586 if (t != first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002587 {
2588 first = parse_template_args(t, last, db);
2589 if (first != t)
2590 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002591 if (db.names.size() < 2)
2592 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002593 auto args = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002594 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002595 db.names.back() =
2596 db.make<NameWithTemplateArgs>(
2597 db.names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002598 }
2599 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002600 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002601 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002602 first = t;
2603 }
2604 }
2605 return first;
2606}
2607
Howard Hinnant6c33e762013-06-17 18:10:34 +00002608// <unresolved-qualifier-level> ::= <simple-id>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002609
2610const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002611parse_unresolved_qualifier_level(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002612{
Howard Hinnant6c33e762013-06-17 18:10:34 +00002613 return parse_simple_id(first, last, db);
Howard Hinnant889b02d2011-06-22 19:27:39 +00002614}
2615
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002616// <unresolved-name>
Howard Hinnant889b02d2011-06-22 19:27:39 +00002617// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002618// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
2619// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
2620// # A::x, N::y, A<T>::z; "gs" means leading "::"
Howard Hinnant889b02d2011-06-22 19:27:39 +00002621// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
Howard Hinnant6c33e762013-06-17 18:10:34 +00002622// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
Howard Hinnant889b02d2011-06-22 19:27:39 +00002623// # T::N::x /decltype(p)::N::x
2624// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002625
2626const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002627parse_unresolved_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002628{
2629 if (last - first > 2)
2630 {
Howard Hinnant889b02d2011-06-22 19:27:39 +00002631 const char* t = first;
2632 bool global = false;
2633 if (t[0] == 'g' && t[1] == 's')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002634 {
Howard Hinnant889b02d2011-06-22 19:27:39 +00002635 global = true;
2636 t += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002637 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002638 const char* t2 = parse_base_unresolved_name(t, last, db);
Howard Hinnant889b02d2011-06-22 19:27:39 +00002639 if (t2 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002640 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002641 if (global)
Howard Hinnant753a30d2013-12-11 19:44:25 +00002642 {
2643 if (db.names.empty())
2644 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002645 db.names.back() =
2646 db.make<GlobalQualifiedName>(db.names.back());
Howard Hinnant753a30d2013-12-11 19:44:25 +00002647 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002648 first = t2;
Howard Hinnant889b02d2011-06-22 19:27:39 +00002649 }
2650 else if (last - t > 2 && t[0] == 's' && t[1] == 'r')
2651 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002652 if (t[2] == 'N')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002653 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002654 t += 3;
2655 const char* t1 = parse_unresolved_type(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002656 if (t1 == t || t1 == last)
2657 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002658 t = t1;
2659 t1 = parse_template_args(t, last, db);
2660 if (t1 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002661 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002662 if (db.names.size() < 2)
2663 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002664 auto args = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002665 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002666 db.names.back() = db.make<NameWithTemplateArgs>(
2667 db.names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002668 t = t1;
2669 if (t == last)
2670 {
2671 db.names.pop_back();
2672 return first;
2673 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002674 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002675 while (*t != 'E')
2676 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002677 t1 = parse_unresolved_qualifier_level(t, last, db);
Howard Hinnant753a30d2013-12-11 19:44:25 +00002678 if (t1 == t || t1 == last || db.names.size() < 2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002679 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002680 auto s = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002681 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002682 db.names.back() =
2683 db.make<QualifiedName>(db.names.back(), s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002684 t = t1;
2685 }
2686 ++t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002687 t1 = parse_base_unresolved_name(t, last, db);
2688 if (t1 == t)
2689 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002690 if (!db.names.empty())
2691 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002692 return first;
2693 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00002694 if (db.names.size() < 2)
2695 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002696 auto s = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002697 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002698 db.names.back() =
2699 db.make<QualifiedName>(db.names.back(), s);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002700 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002701 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002702 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002703 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002704 t += 2;
2705 const char* t1 = parse_unresolved_type(t, last, db);
2706 if (t1 != t)
2707 {
2708 t = t1;
2709 t1 = parse_template_args(t, last, db);
2710 if (t1 != t)
2711 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002712 if (db.names.size() < 2)
2713 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002714 auto args = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002715 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002716 db.names.back() =
2717 db.make<NameWithTemplateArgs>(
2718 db.names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002719 t = t1;
2720 }
2721 t1 = parse_base_unresolved_name(t, last, db);
2722 if (t1 == t)
2723 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002724 if (!db.names.empty())
2725 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002726 return first;
2727 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00002728 if (db.names.size() < 2)
2729 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002730 auto s = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002731 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002732 db.names.back() =
2733 db.make<QualifiedName>(db.names.back(), s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002734 first = t1;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002735 }
2736 else
2737 {
2738 t1 = parse_unresolved_qualifier_level(t, last, db);
2739 if (t1 == t || t1 == last)
2740 return first;
2741 t = t1;
2742 if (global)
Howard Hinnant753a30d2013-12-11 19:44:25 +00002743 {
2744 if (db.names.empty())
2745 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002746 db.names.back() =
2747 db.make<GlobalQualifiedName>(
2748 db.names.back());
Howard Hinnant753a30d2013-12-11 19:44:25 +00002749 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00002750 while (*t != 'E')
2751 {
2752 t1 = parse_unresolved_qualifier_level(t, last, db);
Howard Hinnant753a30d2013-12-11 19:44:25 +00002753 if (t1 == t || t1 == last || db.names.size() < 2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002754 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002755 auto s = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002756 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002757 db.names.back() = db.make<QualifiedName>(
2758 db.names.back(), s);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002759 t = t1;
2760 }
2761 ++t;
2762 t1 = parse_base_unresolved_name(t, last, db);
2763 if (t1 == t)
2764 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002765 if (!db.names.empty())
2766 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002767 return first;
2768 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00002769 if (db.names.size() < 2)
2770 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002771 auto s = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002772 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002773 db.names.back() =
2774 db.make<QualifiedName>(db.names.back(), s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002775 first = t1;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002776 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002777 }
2778 }
2779 }
2780 return first;
2781}
2782
2783// dt <expression> <unresolved-name> # expr.name
2784
2785const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002786parse_dot_expr(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002787{
2788 if (last - first >= 3 && first[0] == 'd' && first[1] == 't')
2789 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002790 const char* t = parse_expression(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002791 if (t != first+2)
2792 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002793 const char* t1 = parse_unresolved_name(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002794 if (t1 != t)
2795 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002796 if (db.names.size() < 2)
2797 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002798 auto name = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002799 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00002800 if (db.names.empty())
2801 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002802 db.names.back() = db.make<MemberExpr>(db.names.back(), ".", name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002803 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002804 }
2805 }
2806 }
2807 return first;
2808}
2809
Howard Hinnant6c33e762013-06-17 18:10:34 +00002810// cl <expression>+ E # call
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002811
2812const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002813parse_call_expr(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002814{
Howard Hinnant6c33e762013-06-17 18:10:34 +00002815 if (last - first >= 4 && first[0] == 'c' && first[1] == 'l')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002816 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002817 const char* t = parse_expression(first+2, last, db);
Erik Pilkington0024acd2017-07-28 00:43:49 +00002818 if (t == last || t == first + 2 || db.names.empty())
2819 return first;
2820 Node* callee = db.names.back();
2821 db.names.pop_back();
2822 size_t args_begin = db.names.size();
2823 while (*t != 'E')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002824 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00002825 const char* t1 = parse_expression(t, last, db);
2826 if (t1 == last || t1 == t)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002827 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002828 t = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002829 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00002830 if (db.names.size() < args_begin)
2831 return first;
2832 ++t;
2833 CallExpr* the_call = db.make<CallExpr>(
2834 callee, db.popTrailingNodeArray(args_begin));
2835 db.names.push_back(the_call);
2836 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002837 }
2838 return first;
2839}
2840
2841// [gs] nw <expression>* _ <type> E # new (expr-list) type
2842// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
2843// [gs] na <expression>* _ <type> E # new[] (expr-list) type
2844// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
2845// <initializer> ::= pi <expression>* E # parenthesized initialization
2846
2847const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002848parse_new_expr(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002849{
2850 if (last - first >= 4)
2851 {
2852 const char* t = first;
2853 bool parsed_gs = false;
2854 if (t[0] == 'g' && t[1] == 's')
2855 {
2856 t += 2;
2857 parsed_gs = true;
2858 }
2859 if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a'))
2860 {
2861 bool is_array = t[1] == 'a';
2862 t += 2;
2863 if (t == last)
2864 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002865 size_t first_expr_in_list = db.names.size();
2866 NodeArray ExprList, init_list;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002867 while (*t != '_')
2868 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002869 const char* t1 = parse_expression(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002870 if (t1 == t || t1 == last)
2871 return first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002872 t = t1;
2873 }
Erik Pilkingtonffdace52017-07-30 20:09:55 +00002874 if (first_expr_in_list > db.names.size())
Erik Pilkington0024acd2017-07-28 00:43:49 +00002875 return first;
2876 ExprList = db.popTrailingNodeArray(first_expr_in_list);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002877 ++t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002878 const char* t1 = parse_type(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002879 if (t1 == t || t1 == last)
2880 return first;
2881 t = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002882 bool has_init = false;
2883 if (last - t >= 3 && t[0] == 'p' && t[1] == 'i')
2884 {
2885 t += 2;
2886 has_init = true;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002887 size_t init_list_begin = db.names.size();
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002888 while (*t != 'E')
2889 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002890 t1 = parse_expression(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002891 if (t1 == t || t1 == last)
2892 return first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002893 t = t1;
2894 }
Erik Pilkingtonffdace52017-07-30 20:09:55 +00002895 if (init_list_begin > db.names.size())
Erik Pilkington0024acd2017-07-28 00:43:49 +00002896 return first;
2897 init_list = db.popTrailingNodeArray(init_list_begin);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002898 }
2899 if (*t != 'E')
2900 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002901 auto type = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002902 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002903 db.names.push_back(
2904 db.make<NewExpr>(ExprList, type, init_list,
2905 parsed_gs, is_array));
Howard Hinnant6c33e762013-06-17 18:10:34 +00002906 first = t+1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002907 }
2908 }
2909 return first;
2910}
2911
Howard Hinnant6c33e762013-06-17 18:10:34 +00002912// cv <type> <expression> # conversion with one argument
2913// cv <type> _ <expression>* E # conversion with a different number of arguments
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002914
2915const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002916parse_conversion_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00002917{
2918 if (last - first >= 3 && first[0] == 'c' && first[1] == 'v')
2919 {
2920 bool try_to_parse_template_args = db.try_to_parse_template_args;
2921 db.try_to_parse_template_args = false;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002922 size_t type_begin = db.names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002923 const char* t = parse_type(first+2, last, db);
2924 db.try_to_parse_template_args = try_to_parse_template_args;
2925 if (t != first+2 && t != last)
2926 {
Erik Pilkingtonffdace52017-07-30 20:09:55 +00002927 size_t expr_list_begin = db.names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002928 if (*t != '_')
2929 {
2930 const char* t1 = parse_expression(t, last, db);
2931 if (t1 == t)
2932 return first;
2933 t = t1;
2934 }
2935 else
2936 {
2937 ++t;
2938 if (t == last)
2939 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002940 if (*t != 'E')
Howard Hinnant6c33e762013-06-17 18:10:34 +00002941 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002942 while (*t != 'E')
2943 {
2944 const char* t1 = parse_expression(t, last, db);
2945 if (t1 == t || t1 == last)
2946 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00002947 t = t1;
2948 }
2949 }
2950 ++t;
2951 }
Erik Pilkingtonffdace52017-07-30 20:09:55 +00002952 if (db.names.size() < expr_list_begin ||
2953 type_begin > expr_list_begin)
Howard Hinnant753a30d2013-12-11 19:44:25 +00002954 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002955 NodeArray expressions = db.makeNodeArray(
Erik Pilkingtonffdace52017-07-30 20:09:55 +00002956 db.names.begin() + (long)expr_list_begin, db.names.end());
Erik Pilkington0024acd2017-07-28 00:43:49 +00002957 NodeArray types = db.makeNodeArray(
2958 db.names.begin() + (long)type_begin,
Erik Pilkingtonffdace52017-07-30 20:09:55 +00002959 db.names.begin() + (long)expr_list_begin);
Erik Pilkington0024acd2017-07-28 00:43:49 +00002960 auto* conv_expr = db.make<ConversionExpr>(
2961 types, expressions);
2962 db.names.erase(
2963 db.names.begin() + (long)type_begin, db.names.end());
2964 db.names.push_back(conv_expr);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002965 first = t;
2966 }
2967 }
2968 return first;
2969}
2970
2971// pt <expression> <expression> # expr->name
2972
Howard Hinnant6c33e762013-06-17 18:10:34 +00002973const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002974parse_arrow_expr(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002975{
2976 if (last - first >= 3 && first[0] == 'p' && first[1] == 't')
2977 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002978 const char* t = parse_expression(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002979 if (t != first+2)
2980 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00002981 const char* t1 = parse_expression(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002982 if (t1 != t)
2983 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00002984 if (db.names.size() < 2)
2985 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00002986 auto tmp = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00002987 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00002988 db.names.back() = db.make<MemberExpr>(
2989 db.names.back(), "->", tmp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00002990 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002991 }
2992 }
2993 }
2994 return first;
2995}
2996
Howard Hinnant6c33e762013-06-17 18:10:34 +00002997// <ref-qualifier> ::= R # & ref-qualifier
2998// <ref-qualifier> ::= O # && ref-qualifier
Howard Hinnantd213ffd2011-05-05 15:27:28 +00002999
Howard Hinnant6c33e762013-06-17 18:10:34 +00003000// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
3001
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003002const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003003parse_function_type(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003004{
Howard Hinnant6c33e762013-06-17 18:10:34 +00003005 if (first != last && *first == 'F')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003006 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003007 const char* t = first+1;
3008 if (t != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003009 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003010 if (*t == 'Y')
3011 {
Saleem Abdulrasoolb2cceca2015-04-27 02:21:57 +00003012 /* extern "C" */
Howard Hinnant6c33e762013-06-17 18:10:34 +00003013 if (++t == last)
3014 return first;
3015 }
3016 const char* t1 = parse_type(t, last, db);
Erik Pilkington0024acd2017-07-28 00:43:49 +00003017 if (t1 != t && !db.names.empty())
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003018 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003019 Node* ret_type = db.names.back();
3020 db.names.pop_back();
3021 size_t params_begin = db.names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003022 t = t1;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003023 FunctionRefQual RefQuals = FrefQualNone;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003024 while (true)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003025 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003026 if (t == last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003027 {
Mehdi Aminieb7bd382017-01-27 20:32:16 +00003028 if (!db.names.empty())
3029 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003030 return first;
3031 }
3032 if (*t == 'E')
3033 {
3034 ++t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003035 break;
3036 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003037 if (*t == 'v')
3038 {
3039 ++t;
3040 continue;
3041 }
3042 if (*t == 'R' && t+1 != last && t[1] == 'E')
3043 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003044 RefQuals = FrefQualLValue;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003045 ++t;
3046 continue;
3047 }
3048 if (*t == 'O' && t+1 != last && t[1] == 'E')
3049 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003050 RefQuals = FrefQualRValue;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003051 ++t;
3052 continue;
3053 }
3054 size_t k0 = db.names.size();
3055 t1 = parse_type(t, last, db);
3056 size_t k1 = db.names.size();
Erik Pilkington0024acd2017-07-28 00:43:49 +00003057 if (t1 == t || t1 == last || k1 < k0)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003058 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003059 t = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003060 }
Erik Pilkingtonffdace52017-07-30 20:09:55 +00003061 if (db.names.empty() || params_begin > db.names.size())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003062 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003063 Node* fty = db.make<FunctionType>(
3064 ret_type, db.popTrailingNodeArray(params_begin));
3065 if (RefQuals)
3066 fty = db.make<FunctionRefQualType>(fty, RefQuals);
3067 db.names.push_back(fty);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003068 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003069 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003070 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003071 }
3072 return first;
3073}
3074
3075// <pointer-to-member-type> ::= M <class type> <member type>
3076
Howard Hinnant6c33e762013-06-17 18:10:34 +00003077const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003078parse_pointer_to_member_type(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003079{
3080 if (first != last && *first == 'M')
3081 {
3082 const char* t = parse_type(first+1, last, db);
3083 if (t != first+1)
3084 {
3085 const char* t2 = parse_type(t, last, db);
3086 if (t2 != t)
3087 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003088 if (db.names.size() < 2)
3089 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003090 auto func = std::move(db.names.back());
3091 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00003092 auto ClassType = std::move(db.names.back());
3093 db.names.back() =
3094 db.make<PointerToMemberType>(ClassType, func);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003095 first = t2;
3096 }
3097 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003098 }
3099 return first;
3100}
3101
3102// <array-type> ::= A <positive dimension number> _ <element type>
3103// ::= A [<dimension expression>] _ <element type>
3104
3105const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003106parse_array_type(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003107{
3108 if (first != last && *first == 'A' && first+1 != last)
3109 {
3110 if (first[1] == '_')
3111 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003112 const char* t = parse_type(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003113 if (t != first+2)
3114 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003115 if (db.names.empty())
3116 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003117 db.names.back() = db.make<ArrayType>(db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003118 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003119 }
3120 }
3121 else if ('1' <= first[1] && first[1] <= '9')
3122 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003123 const char* t = parse_number(first+1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003124 if (t != last && *t == '_')
3125 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003126 const char* t2 = parse_type(t+1, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003127 if (t2 != t+1)
3128 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003129 if (db.names.empty())
3130 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003131 db.names.back() =
3132 db.make<ArrayType>(db.names.back(),
3133 StringView(first + 1, t));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003134 first = t2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003135 }
3136 }
3137 }
3138 else
3139 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003140 const char* t = parse_expression(first+1, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003141 if (t != first+1 && t != last && *t == '_')
3142 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003143 const char* t2 = parse_type(++t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003144 if (t2 != t)
3145 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003146 if (db.names.size() < 2)
3147 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003148 auto base_type = std::move(db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003149 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00003150 auto dimension_expr = std::move(db.names.back());
3151 db.names.back() =
3152 db.make<ArrayType>(base_type, dimension_expr);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003153 first = t2;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003154 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003155 }
3156 }
3157 }
3158 return first;
3159}
3160
3161// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
3162// ::= DT <expression> E # decltype of an expression (C++0x)
3163
3164const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003165parse_decltype(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003166{
3167 if (last - first >= 4 && first[0] == 'D')
3168 {
3169 switch (first[1])
3170 {
3171 case 't':
3172 case 'T':
3173 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003174 const char* t = parse_expression(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003175 if (t != first+2 && t != last && *t == 'E')
3176 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003177 if (db.names.empty())
3178 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003179 db.names.back() = db.make<EnclosingExpr>(
3180 "decltype(", db.names.back(), ")");
Howard Hinnant6c33e762013-06-17 18:10:34 +00003181 first = t+1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003182 }
3183 }
3184 break;
3185 }
3186 }
3187 return first;
3188}
3189
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003190// extension:
3191// <vector-type> ::= Dv <positive dimension number> _
3192// <extended element type>
3193// ::= Dv [<dimension expression>] _ <element type>
3194// <extended element type> ::= <element type>
3195// ::= p # AltiVec vector pixel
3196
3197const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003198parse_vector_type(const char* first, const char* last, Db& db)
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003199{
3200 if (last - first > 3 && first[0] == 'D' && first[1] == 'v')
3201 {
3202 if ('1' <= first[2] && first[2] <= '9')
3203 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003204 const char* t = parse_number(first+2, last);
3205 if (t == last || *t != '_')
3206 return first;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003207 const char* num = first + 2;
Howard Hinnant3e5c7d02012-03-08 18:45:24 +00003208 size_t sz = static_cast<size_t>(t - num);
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003209 if (++t != last)
3210 {
3211 if (*t != 'p')
3212 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003213 const char* t1 = parse_type(t, last, db);
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003214 if (t1 != t)
3215 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003216 if (db.names.empty())
3217 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003218 db.names.back() =
3219 db.make<VectorType>(db.names.back(),
3220 StringView(num, num + sz));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003221 first = t1;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003222 }
3223 }
3224 else
3225 {
3226 ++t;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003227 db.names.push_back(
3228 db.make<VectorType>(StringView(num, num + sz)));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003229 first = t;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003230 }
3231 }
3232 }
3233 else
3234 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003235 Node* num = nullptr;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003236 const char* t1 = first+2;
3237 if (*t1 != '_')
3238 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003239 const char* t = parse_expression(t1, last, db);
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003240 if (t != t1)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003241 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003242 if (db.names.empty())
3243 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003244 num = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003245 db.names.pop_back();
3246 t1 = t;
3247 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003248 }
3249 if (t1 != last && *t1 == '_' && ++t1 != last)
3250 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003251 const char* t = parse_type(t1, last, db);
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003252 if (t != t1)
3253 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003254 if (db.names.empty())
3255 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003256 if (num)
3257 db.names.back() =
3258 db.make<VectorType>(db.names.back(), num);
3259 else
3260 db.names.back() =
3261 db.make<VectorType>(db.names.back(), StringView());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003262 first = t;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003263 } else if (num)
3264 db.names.push_back(num);
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003265 }
3266 }
3267 }
3268 return first;
3269}
3270
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003271// <type> ::= <builtin-type>
3272// ::= <function-type>
3273// ::= <class-enum-type>
3274// ::= <array-type>
3275// ::= <pointer-to-member-type>
3276// ::= <template-param>
3277// ::= <template-template-param> <template-args>
3278// ::= <decltype>
3279// ::= <substitution>
Erik Pilkington0024acd2017-07-28 00:43:49 +00003280// ::= <CV-Qualifiers> <type>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003281// ::= P <type> # pointer-to
3282// ::= R <type> # reference-to
3283// ::= O <type> # rvalue reference-to (C++0x)
3284// ::= C <type> # complex pair (C 2000)
3285// ::= G <type> # imaginary (C 2000)
3286// ::= Dp <type> # pack expansion (C++0x)
3287// ::= U <source-name> <type> # vendor extended type qualifier
Howard Hinnant19e36dd2013-06-19 13:43:18 +00003288// extension := U <objc-name> <objc-type> # objc-type<identifier>
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003289// extension := <vector-type> # <vector-type> starts with Dv
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003290
Howard Hinnant19e36dd2013-06-19 13:43:18 +00003291// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
3292// <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
3293
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003294const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003295parse_type(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003296{
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003297 if (first != last)
3298 {
3299 switch (*first)
3300 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003301 case 'r':
3302 case 'V':
3303 case 'K':
3304 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003305 Qualifiers cv = QualNone;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003306 const char* t = parse_cv_qualifiers(first, last, cv);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003307 if (t != first)
3308 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003309 bool is_function = *t == 'F';
3310 size_t k0 = db.names.size();
3311 const char* t1 = parse_type(t, last, db);
3312 size_t k1 = db.names.size();
3313 if (t1 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003314 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003315 if (is_function)
3316 db.subs.pop_back();
3317 db.subs.emplace_back(db.names.get_allocator());
3318 for (size_t k = k0; k < k1; ++k)
3319 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003320 if (cv) {
3321 if (is_function)
3322 db.names[k] = db.make<FunctionQualType>(
3323 db.names[k], cv);
3324 else
3325 db.names[k] =
3326 db.make<QualType>(db.names[k], cv);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003327 }
3328 db.subs.back().push_back(db.names[k]);
3329 }
3330 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003331 }
3332 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003333 }
3334 break;
3335 default:
3336 {
3337 const char* t = parse_builtin_type(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003338 if (t != first)
3339 {
3340 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003341 }
3342 else
3343 {
3344 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003345 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003346 case 'A':
3347 t = parse_array_type(first, last, db);
3348 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003349 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003350 if (db.names.empty())
3351 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003352 first = t;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003353 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003354 }
3355 break;
3356 case 'C':
3357 t = parse_type(first+1, last, db);
3358 if (t != first+1)
3359 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003360 if (db.names.empty())
3361 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003362 db.names.back() = db.make<PostfixQualifiedType>(
3363 db.names.back(), " complex");
Howard Hinnant6c33e762013-06-17 18:10:34 +00003364 first = t;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003365 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003366 }
3367 break;
3368 case 'F':
3369 t = parse_function_type(first, last, db);
3370 if (t != first)
3371 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003372 if (db.names.empty())
3373 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003374 first = t;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003375 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003376 }
3377 break;
3378 case 'G':
3379 t = parse_type(first+1, last, db);
3380 if (t != first+1)
3381 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003382 if (db.names.empty())
3383 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003384 db.names.back() = db.make<PostfixQualifiedType>(
3385 db.names.back(), " imaginary");
Howard Hinnant6c33e762013-06-17 18:10:34 +00003386 first = t;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003387 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003388 }
3389 break;
3390 case 'M':
3391 t = parse_pointer_to_member_type(first, last, db);
3392 if (t != first)
3393 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003394 if (db.names.empty())
3395 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003396 first = t;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003397 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003398 }
3399 break;
3400 case 'O':
3401 {
3402 size_t k0 = db.names.size();
3403 t = parse_type(first+1, last, db);
3404 size_t k1 = db.names.size();
3405 if (t != first+1)
3406 {
3407 db.subs.emplace_back(db.names.get_allocator());
3408 for (size_t k = k0; k < k1; ++k)
3409 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003410 db.names[k] =
3411 db.make<RValueReferenceType>(db.names[k]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003412 db.subs.back().push_back(db.names[k]);
3413 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003414 first = t;
3415 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003416 break;
3417 }
3418 case 'P':
3419 {
3420 size_t k0 = db.names.size();
3421 t = parse_type(first+1, last, db);
3422 size_t k1 = db.names.size();
3423 if (t != first+1)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003424 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003425 db.subs.emplace_back(db.names.get_allocator());
3426 for (size_t k = k0; k < k1; ++k)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003427 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003428 db.names[k] = db.make<PointerType>(db.names[k]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003429 db.subs.back().push_back(db.names[k]);
3430 }
3431 first = t;
3432 }
3433 break;
3434 }
3435 case 'R':
3436 {
3437 size_t k0 = db.names.size();
3438 t = parse_type(first+1, last, db);
3439 size_t k1 = db.names.size();
3440 if (t != first+1)
3441 {
3442 db.subs.emplace_back(db.names.get_allocator());
3443 for (size_t k = k0; k < k1; ++k)
3444 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003445 db.names[k] =
3446 db.make<LValueReferenceType>(db.names[k]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003447 db.subs.back().push_back(db.names[k]);
3448 }
3449 first = t;
3450 }
3451 break;
3452 }
3453 case 'T':
3454 {
3455 size_t k0 = db.names.size();
3456 t = parse_template_param(first, last, db);
3457 size_t k1 = db.names.size();
3458 if (t != first)
3459 {
3460 db.subs.emplace_back(db.names.get_allocator());
3461 for (size_t k = k0; k < k1; ++k)
3462 db.subs.back().push_back(db.names[k]);
3463 if (db.try_to_parse_template_args && k1 == k0+1)
3464 {
3465 const char* t1 = parse_template_args(t, last, db);
3466 if (t1 != t)
3467 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003468 auto args = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003469 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00003470 db.names.back() = db.make<
3471 NameWithTemplateArgs>(
3472 db.names.back(), args);
3473 db.subs.push_back(Db::sub_type(
3474 1, db.names.back(),
3475 db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003476 t = t1;
3477 }
3478 }
3479 first = t;
3480 }
3481 break;
3482 }
3483 case 'U':
3484 if (first+1 != last)
3485 {
3486 t = parse_source_name(first+1, last, db);
3487 if (t != first+1)
3488 {
3489 const char* t2 = parse_type(t, last, db);
3490 if (t2 != t)
3491 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003492 if (db.names.size() < 2)
3493 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003494 auto type = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003495 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00003496 if (db.names.back()->K != Node::KNameType ||
3497 !static_cast<NameType*>(db.names.back())->getName().startsWith("objcproto"))
Howard Hinnant19e36dd2013-06-19 13:43:18 +00003498 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003499 db.names.back() = db.make<VendorExtQualType>(type, db.names.back());
Howard Hinnant19e36dd2013-06-19 13:43:18 +00003500 }
3501 else
3502 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003503 auto* proto = static_cast<NameType*>(db.names.back());
Howard Hinnant19e36dd2013-06-19 13:43:18 +00003504 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00003505 t = parse_source_name(proto->getName().begin() + 9, proto->getName().end(), db);
3506 if (t != proto->getName().begin() + 9)
Howard Hinnant19e36dd2013-06-19 13:43:18 +00003507 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003508 db.names.back() = db.make<ObjCProtoName>(type, db.names.back());
Howard Hinnant19e36dd2013-06-19 13:43:18 +00003509 }
3510 else
3511 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003512 db.names.push_back(db.make<VendorExtQualType>(type, proto));
Howard Hinnant19e36dd2013-06-19 13:43:18 +00003513 }
3514 }
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003515 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003516 first = t2;
3517 }
3518 }
3519 }
3520 break;
3521 case 'S':
3522 if (first+1 != last && first[1] == 't')
3523 {
3524 t = parse_name(first, last, db);
3525 if (t != first)
3526 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003527 if (db.names.empty())
3528 return first;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003529 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003530 first = t;
3531 }
3532 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003533 else
3534 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003535 t = parse_substitution(first, last, db);
3536 if (t != first)
3537 {
3538 first = t;
3539 // Parsed a substitution. If the substitution is a
3540 // <template-param> it might be followed by <template-args>.
Erik Pilkingtonb74d9d82017-07-13 19:37:37 +00003541 if (db.try_to_parse_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003542 {
Erik Pilkingtonb74d9d82017-07-13 19:37:37 +00003543 t = parse_template_args(first, last, db);
3544 if (t != first)
3545 {
3546 if (db.names.size() < 2)
3547 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003548 auto template_args = db.names.back();
Erik Pilkingtonb74d9d82017-07-13 19:37:37 +00003549 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00003550 db.names.back() = db.make<
3551 NameWithTemplateArgs>(
3552 db.names.back(), template_args);
Erik Pilkingtonb74d9d82017-07-13 19:37:37 +00003553 // Need to create substitution for <template-template-param> <template-args>
3554 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
3555 first = t;
3556 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003557 }
3558 }
3559 }
3560 break;
3561 case 'D':
3562 if (first+1 != last)
3563 {
3564 switch (first[1])
3565 {
3566 case 'p':
3567 {
3568 size_t k0 = db.names.size();
3569 t = parse_type(first+2, last, db);
3570 size_t k1 = db.names.size();
Howard Hinnantf6725172013-06-21 17:04:24 +00003571 if (t != first+2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003572 {
3573 db.subs.emplace_back(db.names.get_allocator());
3574 for (size_t k = k0; k < k1; ++k)
3575 db.subs.back().push_back(db.names[k]);
3576 first = t;
3577 return first;
3578 }
3579 break;
3580 }
3581 case 't':
3582 case 'T':
3583 t = parse_decltype(first, last, db);
3584 if (t != first)
3585 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003586 if (db.names.empty())
3587 return first;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003588 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003589 first = t;
3590 return first;
3591 }
3592 break;
3593 case 'v':
3594 t = parse_vector_type(first, last, db);
3595 if (t != first)
3596 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003597 if (db.names.empty())
3598 return first;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003599 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003600 first = t;
3601 return first;
3602 }
3603 break;
3604 }
3605 }
Eric Fiselier96504b12017-06-15 20:18:10 +00003606 _LIBCPP_FALLTHROUGH();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003607 default:
3608 // must check for builtin-types before class-enum-types to avoid
3609 // ambiguities with operator-names
3610 t = parse_builtin_type(first, last, db);
3611 if (t != first)
3612 {
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003613 first = t;
3614 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003615 else
3616 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003617 t = parse_name(first, last, db);
3618 if (t != first)
3619 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003620 if (db.names.empty())
3621 return first;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003622 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003623 first = t;
3624 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003625 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003626 break;
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003627 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003628 }
3629 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003630 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003631 }
3632 }
3633 return first;
3634}
3635
3636// <operator-name>
3637// ::= aa # &&
3638// ::= ad # & (unary)
3639// ::= an # &
3640// ::= aN # &=
3641// ::= aS # =
3642// ::= cl # ()
3643// ::= cm # ,
3644// ::= co # ~
3645// ::= cv <type> # (cast)
3646// ::= da # delete[]
3647// ::= de # * (unary)
3648// ::= dl # delete
3649// ::= dv # /
3650// ::= dV # /=
3651// ::= eo # ^
3652// ::= eO # ^=
3653// ::= eq # ==
3654// ::= ge # >=
3655// ::= gt # >
3656// ::= ix # []
3657// ::= le # <=
Howard Hinnantf29757a2014-01-06 23:05:04 +00003658// ::= li <source-name> # operator ""
Howard Hinnant6c33e762013-06-17 18:10:34 +00003659// ::= ls # <<
3660// ::= lS # <<=
3661// ::= lt # <
3662// ::= mi # -
3663// ::= mI # -=
3664// ::= ml # *
3665// ::= mL # *=
3666// ::= mm # -- (postfix in <expression> context)
3667// ::= na # new[]
3668// ::= ne # !=
3669// ::= ng # - (unary)
3670// ::= nt # !
3671// ::= nw # new
3672// ::= oo # ||
3673// ::= or # |
3674// ::= oR # |=
3675// ::= pm # ->*
3676// ::= pl # +
3677// ::= pL # +=
3678// ::= pp # ++ (postfix in <expression> context)
3679// ::= ps # + (unary)
3680// ::= pt # ->
3681// ::= qu # ?
3682// ::= rm # %
3683// ::= rM # %=
3684// ::= rs # >>
3685// ::= rS # >>=
3686// ::= v <digit> <source-name> # vendor extended operator
3687
Howard Hinnant6c33e762013-06-17 18:10:34 +00003688const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003689parse_operator_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003690{
3691 if (last - first >= 2)
3692 {
3693 switch (first[0])
3694 {
3695 case 'a':
3696 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003697 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003698 case 'a':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003699 db.names.push_back(db.make<NameType>("operator&&"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003700 first += 2;
3701 break;
3702 case 'd':
3703 case 'n':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003704 db.names.push_back(db.make<NameType>("operator&"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003705 first += 2;
3706 break;
3707 case 'N':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003708 db.names.push_back(db.make<NameType>("operator&="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003709 first += 2;
3710 break;
3711 case 'S':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003712 db.names.push_back(db.make<NameType>("operator="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003713 first += 2;
3714 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003715 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003716 break;
3717 case 'c':
3718 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003719 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003720 case 'l':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003721 db.names.push_back(db.make<NameType>("operator()"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003722 first += 2;
3723 break;
3724 case 'm':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003725 db.names.push_back(db.make<NameType>("operator,"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003726 first += 2;
3727 break;
3728 case 'o':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003729 db.names.push_back(db.make<NameType>("operator~"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003730 first += 2;
3731 break;
3732 case 'v':
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003733 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003734 bool try_to_parse_template_args = db.try_to_parse_template_args;
3735 db.try_to_parse_template_args = false;
3736 const char* t = parse_type(first+2, last, db);
3737 db.try_to_parse_template_args = try_to_parse_template_args;
3738 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003739 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003740 if (db.names.empty())
3741 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003742 db.names.back() =
3743 db.make<ConversionOperatorType>(db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003744 db.parsed_ctor_dtor_cv = true;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003745 first = t;
3746 }
3747 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003748 break;
3749 }
3750 break;
3751 case 'd':
3752 switch (first[1])
3753 {
3754 case 'a':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003755 db.names.push_back(db.make<NameType>("operator delete[]"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003756 first += 2;
3757 break;
3758 case 'e':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003759 db.names.push_back(db.make<NameType>("operator*"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003760 first += 2;
3761 break;
3762 case 'l':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003763 db.names.push_back(db.make<NameType>("operator delete"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003764 first += 2;
3765 break;
3766 case 'v':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003767 db.names.push_back(db.make<NameType>("operator/"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003768 first += 2;
3769 break;
3770 case 'V':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003771 db.names.push_back(db.make<NameType>("operator/="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003772 first += 2;
3773 break;
3774 }
3775 break;
3776 case 'e':
3777 switch (first[1])
3778 {
3779 case 'o':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003780 db.names.push_back(db.make<NameType>("operator^"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003781 first += 2;
3782 break;
3783 case 'O':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003784 db.names.push_back(db.make<NameType>("operator^="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003785 first += 2;
3786 break;
3787 case 'q':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003788 db.names.push_back(db.make<NameType>("operator=="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003789 first += 2;
3790 break;
3791 }
3792 break;
3793 case 'g':
3794 switch (first[1])
3795 {
3796 case 'e':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003797 db.names.push_back(db.make<NameType>("operator>="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003798 first += 2;
3799 break;
3800 case 't':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003801 db.names.push_back(db.make<NameType>("operator>"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003802 first += 2;
3803 break;
3804 }
3805 break;
3806 case 'i':
3807 if (first[1] == 'x')
3808 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003809 db.names.push_back(db.make<NameType>("operator[]"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003810 first += 2;
3811 }
3812 break;
3813 case 'l':
3814 switch (first[1])
3815 {
3816 case 'e':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003817 db.names.push_back(db.make<NameType>("operator<="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003818 first += 2;
3819 break;
Howard Hinnantf29757a2014-01-06 23:05:04 +00003820 case 'i':
3821 {
3822 const char* t = parse_source_name(first+2, last, db);
3823 if (t != first+2)
3824 {
3825 if (db.names.empty())
3826 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003827 db.names.back() =
3828 db.make<LiteralOperator>(db.names.back());
Howard Hinnantf29757a2014-01-06 23:05:04 +00003829 first = t;
3830 }
3831 }
3832 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003833 case 's':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003834 db.names.push_back(db.make<NameType>("operator<<"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003835 first += 2;
3836 break;
3837 case 'S':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003838 db.names.push_back(db.make<NameType>("operator<<="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003839 first += 2;
3840 break;
3841 case 't':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003842 db.names.push_back(db.make<NameType>("operator<"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003843 first += 2;
3844 break;
3845 }
3846 break;
3847 case 'm':
3848 switch (first[1])
3849 {
3850 case 'i':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003851 db.names.push_back(db.make<NameType>("operator-"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003852 first += 2;
3853 break;
3854 case 'I':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003855 db.names.push_back(db.make<NameType>("operator-="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003856 first += 2;
3857 break;
3858 case 'l':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003859 db.names.push_back(db.make<NameType>("operator*"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003860 first += 2;
3861 break;
3862 case 'L':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003863 db.names.push_back(db.make<NameType>("operator*="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003864 first += 2;
3865 break;
3866 case 'm':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003867 db.names.push_back(db.make<NameType>("operator--"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003868 first += 2;
3869 break;
3870 }
3871 break;
3872 case 'n':
3873 switch (first[1])
3874 {
3875 case 'a':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003876 db.names.push_back(db.make<NameType>("operator new[]"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003877 first += 2;
3878 break;
3879 case 'e':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003880 db.names.push_back(db.make<NameType>("operator!="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003881 first += 2;
3882 break;
3883 case 'g':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003884 db.names.push_back(db.make<NameType>("operator-"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003885 first += 2;
3886 break;
3887 case 't':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003888 db.names.push_back(db.make<NameType>("operator!"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003889 first += 2;
3890 break;
3891 case 'w':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003892 db.names.push_back(db.make<NameType>("operator new"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003893 first += 2;
3894 break;
3895 }
3896 break;
3897 case 'o':
3898 switch (first[1])
3899 {
3900 case 'o':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003901 db.names.push_back(db.make<NameType>("operator||"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003902 first += 2;
3903 break;
3904 case 'r':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003905 db.names.push_back(db.make<NameType>("operator|"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003906 first += 2;
3907 break;
3908 case 'R':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003909 db.names.push_back(db.make<NameType>("operator|="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003910 first += 2;
3911 break;
3912 }
3913 break;
3914 case 'p':
3915 switch (first[1])
3916 {
3917 case 'm':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003918 db.names.push_back(db.make<NameType>("operator->*"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003919 first += 2;
3920 break;
3921 case 'l':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003922 db.names.push_back(db.make<NameType>("operator+"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003923 first += 2;
3924 break;
3925 case 'L':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003926 db.names.push_back(db.make<NameType>("operator+="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003927 first += 2;
3928 break;
3929 case 'p':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003930 db.names.push_back(db.make<NameType>("operator++"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003931 first += 2;
3932 break;
3933 case 's':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003934 db.names.push_back(db.make<NameType>("operator+"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003935 first += 2;
3936 break;
3937 case 't':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003938 db.names.push_back(db.make<NameType>("operator->"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003939 first += 2;
3940 break;
3941 }
3942 break;
3943 case 'q':
3944 if (first[1] == 'u')
3945 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003946 db.names.push_back(db.make<NameType>("operator?"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003947 first += 2;
3948 }
3949 break;
3950 case 'r':
3951 switch (first[1])
3952 {
3953 case 'm':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003954 db.names.push_back(db.make<NameType>("operator%"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003955 first += 2;
3956 break;
3957 case 'M':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003958 db.names.push_back(db.make<NameType>("operator%="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003959 first += 2;
3960 break;
3961 case 's':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003962 db.names.push_back(db.make<NameType>("operator>>"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003963 first += 2;
3964 break;
3965 case 'S':
Erik Pilkington0024acd2017-07-28 00:43:49 +00003966 db.names.push_back(db.make<NameType>("operator>>="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003967 first += 2;
3968 break;
3969 }
3970 break;
3971 case 'v':
3972 if (std::isdigit(first[1]))
3973 {
3974 const char* t = parse_source_name(first+2, last, db);
3975 if (t != first+2)
3976 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00003977 if (db.names.empty())
3978 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00003979 db.names.back() =
3980 db.make<ConversionOperatorType>(db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003981 first = t;
3982 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003983 }
3984 break;
3985 }
3986 }
3987 return first;
3988}
3989
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003990const char*
Erik Pilkington0024acd2017-07-28 00:43:49 +00003991parse_integer_literal(const char* first, const char* last, StringView lit, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003992{
3993 const char* t = parse_number(first, last);
3994 if (t != first && t != last && *t == 'E')
3995 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003996 db.names.push_back(
3997 db.make<IntegerExpr>(lit, StringView(first, t)));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003998 first = t+1;
3999 }
4000 return first;
4001}
4002
4003// <expr-primary> ::= L <type> <value number> E # integer literal
4004// ::= L <type> <value float> E # floating literal
4005// ::= L <string type> E # string literal
4006// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
4007// ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
4008// ::= L <mangled-name> E # external name
4009
Howard Hinnant6c33e762013-06-17 18:10:34 +00004010const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004011parse_expr_primary(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004012{
4013 if (last - first >= 4 && *first == 'L')
4014 {
4015 switch (first[1])
4016 {
4017 case 'w':
Howard Hinnant93433df2013-06-20 21:49:34 +00004018 {
4019 const char* t = parse_integer_literal(first+2, last, "wchar_t", db);
4020 if (t != first+2)
4021 first = t;
4022 }
4023 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004024 case 'b':
4025 if (first[3] == 'E')
4026 {
4027 switch (first[2])
4028 {
4029 case '0':
Erik Pilkington0024acd2017-07-28 00:43:49 +00004030 db.names.push_back(db.make<BoolExpr>(0));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004031 first += 4;
4032 break;
4033 case '1':
Erik Pilkington0024acd2017-07-28 00:43:49 +00004034 db.names.push_back(db.make<BoolExpr>(1));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004035 first += 4;
4036 break;
4037 }
4038 }
4039 break;
4040 case 'c':
Howard Hinnant93433df2013-06-20 21:49:34 +00004041 {
4042 const char* t = parse_integer_literal(first+2, last, "char", db);
4043 if (t != first+2)
4044 first = t;
4045 }
4046 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004047 case 'a':
Howard Hinnant93433df2013-06-20 21:49:34 +00004048 {
4049 const char* t = parse_integer_literal(first+2, last, "signed char", db);
4050 if (t != first+2)
4051 first = t;
4052 }
4053 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004054 case 'h':
Howard Hinnant93433df2013-06-20 21:49:34 +00004055 {
4056 const char* t = parse_integer_literal(first+2, last, "unsigned char", db);
4057 if (t != first+2)
4058 first = t;
4059 }
4060 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004061 case 's':
Howard Hinnant93433df2013-06-20 21:49:34 +00004062 {
4063 const char* t = parse_integer_literal(first+2, last, "short", db);
4064 if (t != first+2)
4065 first = t;
4066 }
4067 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004068 case 't':
Howard Hinnant93433df2013-06-20 21:49:34 +00004069 {
4070 const char* t = parse_integer_literal(first+2, last, "unsigned short", db);
4071 if (t != first+2)
4072 first = t;
4073 }
4074 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004075 case 'i':
Howard Hinnant93433df2013-06-20 21:49:34 +00004076 {
4077 const char* t = parse_integer_literal(first+2, last, "", db);
4078 if (t != first+2)
4079 first = t;
4080 }
4081 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004082 case 'j':
Howard Hinnant93433df2013-06-20 21:49:34 +00004083 {
4084 const char* t = parse_integer_literal(first+2, last, "u", db);
4085 if (t != first+2)
4086 first = t;
4087 }
4088 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004089 case 'l':
Howard Hinnant93433df2013-06-20 21:49:34 +00004090 {
4091 const char* t = parse_integer_literal(first+2, last, "l", db);
4092 if (t != first+2)
4093 first = t;
4094 }
4095 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004096 case 'm':
Howard Hinnant93433df2013-06-20 21:49:34 +00004097 {
4098 const char* t = parse_integer_literal(first+2, last, "ul", db);
4099 if (t != first+2)
4100 first = t;
4101 }
4102 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004103 case 'x':
Howard Hinnant93433df2013-06-20 21:49:34 +00004104 {
4105 const char* t = parse_integer_literal(first+2, last, "ll", db);
4106 if (t != first+2)
4107 first = t;
4108 }
4109 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004110 case 'y':
Howard Hinnant93433df2013-06-20 21:49:34 +00004111 {
4112 const char* t = parse_integer_literal(first+2, last, "ull", db);
4113 if (t != first+2)
4114 first = t;
4115 }
4116 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004117 case 'n':
Howard Hinnant93433df2013-06-20 21:49:34 +00004118 {
4119 const char* t = parse_integer_literal(first+2, last, "__int128", db);
4120 if (t != first+2)
4121 first = t;
4122 }
4123 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004124 case 'o':
Howard Hinnant93433df2013-06-20 21:49:34 +00004125 {
4126 const char* t = parse_integer_literal(first+2, last, "unsigned __int128", db);
4127 if (t != first+2)
4128 first = t;
4129 }
4130 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004131 case 'f':
Howard Hinnant93433df2013-06-20 21:49:34 +00004132 {
4133 const char* t = parse_floating_number<float>(first+2, last, db);
4134 if (t != first+2)
4135 first = t;
4136 }
4137 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004138 case 'd':
Howard Hinnant93433df2013-06-20 21:49:34 +00004139 {
4140 const char* t = parse_floating_number<double>(first+2, last, db);
4141 if (t != first+2)
4142 first = t;
4143 }
4144 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004145 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00004146 {
4147 const char* t = parse_floating_number<long double>(first+2, last, db);
4148 if (t != first+2)
4149 first = t;
4150 }
4151 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004152 case '_':
4153 if (first[2] == 'Z')
4154 {
4155 const char* t = parse_encoding(first+3, last, db);
4156 if (t != first+3 && t != last && *t == 'E')
4157 first = t+1;
4158 }
4159 break;
4160 case 'T':
4161 // Invalid mangled name per
4162 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
4163 break;
4164 default:
4165 {
4166 // might be named type
4167 const char* t = parse_type(first+1, last, db);
4168 if (t != first+1 && t != last)
4169 {
4170 if (*t != 'E')
4171 {
4172 const char* n = t;
4173 for (; n != last && isdigit(*n); ++n)
4174 ;
4175 if (n != t && n != last && *n == 'E')
4176 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004177 if (db.names.empty())
4178 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004179 db.names.back() = db.make<IntegerCastExpr>(
4180 db.names.back(), StringView(t, n));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004181 first = n+1;
4182 break;
4183 }
4184 }
4185 else
4186 {
4187 first = t+1;
4188 break;
4189 }
4190 }
4191 }
4192 }
4193 }
4194 return first;
4195}
4196
Erik Pilkington0024acd2017-07-28 00:43:49 +00004197Node* maybe_change_special_sub_name(Node* inp, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004198{
Erik Pilkington0024acd2017-07-28 00:43:49 +00004199 if (inp->K != Node::KSpecialSubstitution)
4200 return inp;
4201 auto Kind = static_cast<SpecialSubstitution*>(inp)->SSK;
4202 switch (Kind)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004203 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00004204 case SpecialSubKind::string:
4205 case SpecialSubKind::istream:
4206 case SpecialSubKind::ostream:
4207 case SpecialSubKind::iostream:
4208 return db.make<ExpandedSpecialSubstitution>(Kind);
4209 default:
4210 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004211 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00004212 return inp;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004213}
4214
4215// <ctor-dtor-name> ::= C1 # complete object constructor
4216// ::= C2 # base object constructor
4217// ::= C3 # complete object allocating constructor
4218// extension ::= C5 # ?
4219// ::= D0 # deleting destructor
4220// ::= D1 # complete object destructor
4221// ::= D2 # base object destructor
4222// extension ::= D5 # ?
4223
Howard Hinnant6c33e762013-06-17 18:10:34 +00004224const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004225parse_ctor_dtor_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004226{
4227 if (last-first >= 2 && !db.names.empty())
4228 {
4229 switch (first[0])
4230 {
4231 case 'C':
4232 switch (first[1])
4233 {
4234 case '1':
4235 case '2':
4236 case '3':
4237 case '5':
Howard Hinnant753a30d2013-12-11 19:44:25 +00004238 if (db.names.empty())
4239 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004240 db.names.back() =
4241 maybe_change_special_sub_name(db.names.back(), db);
4242 db.names.push_back(
4243 db.make<CtorDtorName>(db.names.back(), false));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004244 first += 2;
4245 db.parsed_ctor_dtor_cv = true;
4246 break;
4247 }
4248 break;
4249 case 'D':
4250 switch (first[1])
4251 {
4252 case '0':
4253 case '1':
4254 case '2':
4255 case '5':
Howard Hinnant753a30d2013-12-11 19:44:25 +00004256 if (db.names.empty())
4257 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004258 db.names.push_back(
4259 db.make<CtorDtorName>(db.names.back(), true));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004260 first += 2;
4261 db.parsed_ctor_dtor_cv = true;
4262 break;
4263 }
4264 break;
4265 }
4266 }
4267 return first;
4268}
4269
4270// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
4271// ::= <closure-type-name>
4272//
4273// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
4274//
4275// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
4276
Howard Hinnant6c33e762013-06-17 18:10:34 +00004277const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004278parse_unnamed_type_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004279{
4280 if (last - first > 2 && first[0] == 'U')
4281 {
4282 char type = first[1];
4283 switch (type)
4284 {
4285 case 't':
4286 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004287 const char* t0 = first+2;
4288 if (t0 == last)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004289 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004290 StringView count;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004291 if (std::isdigit(*t0))
4292 {
4293 const char* t1 = t0 + 1;
4294 while (t1 != last && std::isdigit(*t1))
4295 ++t1;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004296 count = StringView(t0, t1);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004297 t0 = t1;
4298 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004299 if (t0 == last || *t0 != '_')
Howard Hinnant6c33e762013-06-17 18:10:34 +00004300 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004301 db.names.push_back(db.make<UnnamedTypeName>(count));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004302 first = t0 + 1;
4303 }
4304 break;
4305 case 'l':
4306 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00004307 size_t begin_pos = db.names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004308 const char* t0 = first+2;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004309 NodeArray lambda_params;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004310 if (first[2] == 'v')
4311 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004312 ++t0;
4313 }
4314 else
4315 {
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004316 while (true)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004317 {
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004318 const char* t1 = parse_type(t0, last, db);
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004319 if (t1 == t0)
4320 break;
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004321 t0 = t1;
4322 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00004323 if (db.names.size() < begin_pos)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004324 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004325 lambda_params = db.popTrailingNodeArray(begin_pos);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004326 }
4327 if (t0 == last || *t0 != 'E')
Erik Pilkington0024acd2017-07-28 00:43:49 +00004328 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004329 ++t0;
4330 if (t0 == last)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004331 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004332 StringView count;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004333 if (std::isdigit(*t0))
4334 {
4335 const char* t1 = t0 + 1;
4336 while (t1 != last && std::isdigit(*t1))
4337 ++t1;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004338 count = StringView(t0, t1);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004339 t0 = t1;
4340 }
4341 if (t0 == last || *t0 != '_')
Howard Hinnant6c33e762013-06-17 18:10:34 +00004342 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004343 db.names.push_back(db.make<LambdaTypeName>(lambda_params, count));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004344 first = t0 + 1;
4345 }
4346 break;
4347 }
4348 }
4349 return first;
4350}
4351
4352// <unqualified-name> ::= <operator-name>
4353// ::= <ctor-dtor-name>
4354// ::= <source-name>
4355// ::= <unnamed-type-name>
4356
Howard Hinnant6c33e762013-06-17 18:10:34 +00004357const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004358parse_unqualified_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004359{
4360 if (first != last)
4361 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004362 const char* t;
4363 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004364 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004365 case 'C':
4366 case 'D':
4367 t = parse_ctor_dtor_name(first, last, db);
4368 if (t != first)
4369 first = t;
4370 break;
4371 case 'U':
4372 t = parse_unnamed_type_name(first, last, db);
4373 if (t != first)
4374 first = t;
4375 break;
4376 case '1':
4377 case '2':
4378 case '3':
4379 case '4':
4380 case '5':
4381 case '6':
4382 case '7':
4383 case '8':
4384 case '9':
4385 t = parse_source_name(first, last, db);
4386 if (t != first)
4387 first = t;
4388 break;
4389 default:
4390 t = parse_operator_name(first, last, db);
4391 if (t != first)
4392 first = t;
4393 break;
4394 };
4395 }
4396 return first;
4397}
4398
4399// <unscoped-name> ::= <unqualified-name>
4400// ::= St <unqualified-name> # ::std::
4401// extension ::= StL<unqualified-name>
4402
Howard Hinnant6c33e762013-06-17 18:10:34 +00004403const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004404parse_unscoped_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004405{
4406 if (last - first >= 2)
4407 {
4408 const char* t0 = first;
4409 bool St = false;
4410 if (first[0] == 'S' && first[1] == 't')
4411 {
4412 t0 += 2;
4413 St = true;
4414 if (t0 != last && *t0 == 'L')
4415 ++t0;
4416 }
4417 const char* t1 = parse_unqualified_name(t0, last, db);
4418 if (t1 != t0)
4419 {
4420 if (St)
Howard Hinnant753a30d2013-12-11 19:44:25 +00004421 {
4422 if (db.names.empty())
4423 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004424 db.names.back() =
4425 db.make<StdQualifiedName>(db.names.back());
Howard Hinnant753a30d2013-12-11 19:44:25 +00004426 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004427 first = t1;
4428 }
4429 }
4430 return first;
4431}
4432
4433// at <type> # alignof (a type)
4434
Howard Hinnant6c33e762013-06-17 18:10:34 +00004435const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004436parse_alignof_type(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004437{
4438 if (last - first >= 3 && first[0] == 'a' && first[1] == 't')
4439 {
4440 const char* t = parse_type(first+2, last, db);
4441 if (t != first+2)
4442 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004443 if (db.names.empty())
4444 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004445 db.names.back() =
4446 db.make<EnclosingExpr>("alignof (", db.names.back(), ")");
Howard Hinnant6c33e762013-06-17 18:10:34 +00004447 first = t;
4448 }
4449 }
4450 return first;
4451}
4452
4453// az <expression> # alignof (a expression)
4454
Howard Hinnant6c33e762013-06-17 18:10:34 +00004455const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004456parse_alignof_expr(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004457{
4458 if (last - first >= 3 && first[0] == 'a' && first[1] == 'z')
4459 {
4460 const char* t = parse_expression(first+2, last, db);
4461 if (t != first+2)
4462 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004463 if (db.names.empty())
4464 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004465 db.names.back() =
4466 db.make<EnclosingExpr>("alignof (", db.names.back(), ")");
Howard Hinnant6c33e762013-06-17 18:10:34 +00004467 first = t;
4468 }
4469 }
4470 return first;
4471}
4472
Howard Hinnant6c33e762013-06-17 18:10:34 +00004473const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004474parse_noexcept_expression(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004475{
4476 const char* t1 = parse_expression(first, last, db);
4477 if (t1 != first)
4478 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004479 if (db.names.empty())
4480 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004481 db.names.back() =
4482 db.make<EnclosingExpr>("noexcept (", db.names.back(), ")");
Howard Hinnant6c33e762013-06-17 18:10:34 +00004483 first = t1;
4484 }
4485 return first;
4486}
4487
Howard Hinnant6c33e762013-06-17 18:10:34 +00004488const char*
Erik Pilkington0024acd2017-07-28 00:43:49 +00004489parse_prefix_expression(const char* first, const char* last, StringView op, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004490{
4491 const char* t1 = parse_expression(first, last, db);
4492 if (t1 != first)
4493 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004494 if (db.names.empty())
4495 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004496 db.names.back() = db.make<PrefixExpr>(op, db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004497 first = t1;
4498 }
4499 return first;
4500}
4501
Howard Hinnant6c33e762013-06-17 18:10:34 +00004502const char*
Erik Pilkington0024acd2017-07-28 00:43:49 +00004503parse_binary_expression(const char* first, const char* last, StringView op, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004504{
4505 const char* t1 = parse_expression(first, last, db);
4506 if (t1 != first)
4507 {
4508 const char* t2 = parse_expression(t1, last, db);
4509 if (t2 != t1)
4510 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004511 if (db.names.size() < 2)
4512 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004513 auto op2 = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004514 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00004515 auto op1 = db.names.back();
4516 db.names.back() = db.make<BinaryExpr>(op1, op, op2);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004517 first = t2;
4518 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004519 }
4520 return first;
4521}
4522
4523// <expression> ::= <unary operator-name> <expression>
4524// ::= <binary operator-name> <expression> <expression>
4525// ::= <ternary operator-name> <expression> <expression> <expression>
4526// ::= cl <expression>+ E # call
4527// ::= cv <type> <expression> # conversion with one argument
4528// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
4529// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
4530// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
4531// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
4532// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
4533// ::= [gs] dl <expression> # delete expression
4534// ::= [gs] da <expression> # delete[] expression
4535// ::= pp_ <expression> # prefix ++
4536// ::= mm_ <expression> # prefix --
4537// ::= ti <type> # typeid (type)
4538// ::= te <expression> # typeid (expression)
4539// ::= dc <type> <expression> # dynamic_cast<type> (expression)
4540// ::= sc <type> <expression> # static_cast<type> (expression)
4541// ::= cc <type> <expression> # const_cast<type> (expression)
4542// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
4543// ::= st <type> # sizeof (a type)
4544// ::= sz <expression> # sizeof (an expression)
4545// ::= at <type> # alignof (a type)
4546// ::= az <expression> # alignof (an expression)
4547// ::= nx <expression> # noexcept (expression)
4548// ::= <template-param>
4549// ::= <function-param>
4550// ::= dt <expression> <unresolved-name> # expr.name
4551// ::= pt <expression> <unresolved-name> # expr->name
4552// ::= ds <expression> <expression> # expr.*expr
4553// ::= sZ <template-param> # size of a parameter pack
4554// ::= sZ <function-param> # size of a function parameter pack
4555// ::= sp <expression> # pack expansion
4556// ::= tw <expression> # throw expression
4557// ::= tr # throw with no operand (rethrow)
4558// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
4559// # freestanding dependent name (e.g., T::x),
4560// # objectless nonstatic member reference
4561// ::= <expr-primary>
4562
Howard Hinnant6c33e762013-06-17 18:10:34 +00004563const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004564parse_expression(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004565{
4566 if (last - first >= 2)
4567 {
4568 const char* t = first;
4569 bool parsed_gs = false;
4570 if (last - first >= 4 && t[0] == 'g' && t[1] == 's')
4571 {
4572 t += 2;
4573 parsed_gs = true;
4574 }
4575 switch (*t)
4576 {
4577 case 'L':
4578 first = parse_expr_primary(first, last, db);
4579 break;
4580 case 'T':
4581 first = parse_template_param(first, last, db);
4582 break;
4583 case 'f':
4584 first = parse_function_param(first, last, db);
4585 break;
4586 case 'a':
4587 switch (t[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004588 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004589 case 'a':
Howard Hinnant93433df2013-06-20 21:49:34 +00004590 t = parse_binary_expression(first+2, last, "&&", db);
4591 if (t != first+2)
4592 first = t;
4593 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004594 case 'd':
Howard Hinnant93433df2013-06-20 21:49:34 +00004595 t = parse_prefix_expression(first+2, last, "&", db);
4596 if (t != first+2)
4597 first = t;
4598 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004599 case 'n':
Howard Hinnant93433df2013-06-20 21:49:34 +00004600 t = parse_binary_expression(first+2, last, "&", db);
4601 if (t != first+2)
4602 first = t;
4603 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004604 case 'N':
Howard Hinnant93433df2013-06-20 21:49:34 +00004605 t = parse_binary_expression(first+2, last, "&=", db);
4606 if (t != first+2)
4607 first = t;
4608 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004609 case 'S':
Howard Hinnant93433df2013-06-20 21:49:34 +00004610 t = parse_binary_expression(first+2, last, "=", db);
4611 if (t != first+2)
4612 first = t;
4613 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004614 case 't':
4615 first = parse_alignof_type(first, last, db);
4616 break;
4617 case 'z':
4618 first = parse_alignof_expr(first, last, db);
4619 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004620 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004621 break;
4622 case 'c':
4623 switch (t[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004624 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004625 case 'c':
4626 first = parse_const_cast_expr(first, last, db);
4627 break;
4628 case 'l':
4629 first = parse_call_expr(first, last, db);
4630 break;
4631 case 'm':
Howard Hinnant93433df2013-06-20 21:49:34 +00004632 t = parse_binary_expression(first+2, last, ",", db);
4633 if (t != first+2)
4634 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004635 break;
4636 case 'o':
Howard Hinnant93433df2013-06-20 21:49:34 +00004637 t = parse_prefix_expression(first+2, last, "~", db);
4638 if (t != first+2)
4639 first = t;
4640 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004641 case 'v':
4642 first = parse_conversion_expr(first, last, db);
4643 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004644 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004645 break;
4646 case 'd':
4647 switch (t[1])
4648 {
4649 case 'a':
4650 {
4651 const char* t1 = parse_expression(t+2, last, db);
4652 if (t1 != t+2)
4653 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004654 if (db.names.empty())
4655 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004656 db.names.back() = db.make<DeleteExpr>(
4657 db.names.back(), parsed_gs, /*is_array=*/true);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004658 first = t1;
4659 }
4660 }
4661 break;
4662 case 'c':
4663 first = parse_dynamic_cast_expr(first, last, db);
4664 break;
4665 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00004666 t = parse_prefix_expression(first+2, last, "*", db);
4667 if (t != first+2)
4668 first = t;
4669 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004670 case 'l':
4671 {
4672 const char* t1 = parse_expression(t+2, last, db);
4673 if (t1 != t+2)
4674 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004675 if (db.names.empty())
4676 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004677 db.names.back() = db.make<DeleteExpr>(
4678 db.names.back(), parsed_gs, /*is_array=*/false);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004679 first = t1;
4680 }
4681 }
4682 break;
4683 case 'n':
4684 return parse_unresolved_name(first, last, db);
4685 case 's':
4686 first = parse_dot_star_expr(first, last, db);
4687 break;
4688 case 't':
4689 first = parse_dot_expr(first, last, db);
4690 break;
4691 case 'v':
Howard Hinnant93433df2013-06-20 21:49:34 +00004692 t = parse_binary_expression(first+2, last, "/", db);
4693 if (t != first+2)
4694 first = t;
4695 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004696 case 'V':
Howard Hinnant93433df2013-06-20 21:49:34 +00004697 t = parse_binary_expression(first+2, last, "/=", db);
4698 if (t != first+2)
4699 first = t;
4700 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004701 }
4702 break;
4703 case 'e':
4704 switch (t[1])
4705 {
4706 case 'o':
Howard Hinnant93433df2013-06-20 21:49:34 +00004707 t = parse_binary_expression(first+2, last, "^", db);
4708 if (t != first+2)
4709 first = t;
4710 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004711 case 'O':
Howard Hinnant93433df2013-06-20 21:49:34 +00004712 t = parse_binary_expression(first+2, last, "^=", db);
4713 if (t != first+2)
4714 first = t;
4715 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004716 case 'q':
Howard Hinnant93433df2013-06-20 21:49:34 +00004717 t = parse_binary_expression(first+2, last, "==", db);
4718 if (t != first+2)
4719 first = t;
4720 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004721 }
4722 break;
4723 case 'g':
4724 switch (t[1])
4725 {
4726 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00004727 t = parse_binary_expression(first+2, last, ">=", db);
4728 if (t != first+2)
4729 first = t;
4730 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004731 case 't':
Howard Hinnant93433df2013-06-20 21:49:34 +00004732 t = parse_binary_expression(first+2, last, ">", db);
4733 if (t != first+2)
4734 first = t;
4735 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004736 }
4737 break;
4738 case 'i':
4739 if (t[1] == 'x')
4740 {
4741 const char* t1 = parse_expression(first+2, last, db);
4742 if (t1 != first+2)
4743 {
4744 const char* t2 = parse_expression(t1, last, db);
4745 if (t2 != t1)
4746 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004747 if (db.names.size() < 2)
4748 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004749 auto op2 = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004750 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00004751 auto op1 = db.names.back();
4752 db.names.back() =
4753 db.make<ArraySubscriptExpr>(op1, op2);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004754 first = t2;
4755 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004756 else if (!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00004757 db.names.pop_back();
4758 }
4759 }
4760 break;
4761 case 'l':
4762 switch (t[1])
4763 {
4764 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00004765 t = parse_binary_expression(first+2, last, "<=", db);
4766 if (t != first+2)
4767 first = t;
4768 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004769 case 's':
Howard Hinnant93433df2013-06-20 21:49:34 +00004770 t = parse_binary_expression(first+2, last, "<<", db);
4771 if (t != first+2)
4772 first = t;
4773 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004774 case 'S':
Howard Hinnant93433df2013-06-20 21:49:34 +00004775 t = parse_binary_expression(first+2, last, "<<=", db);
4776 if (t != first+2)
4777 first = t;
4778 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004779 case 't':
Howard Hinnant93433df2013-06-20 21:49:34 +00004780 t = parse_binary_expression(first+2, last, "<", db);
4781 if (t != first+2)
4782 first = t;
4783 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004784 }
4785 break;
4786 case 'm':
4787 switch (t[1])
4788 {
4789 case 'i':
Howard Hinnant93433df2013-06-20 21:49:34 +00004790 t = parse_binary_expression(first+2, last, "-", db);
4791 if (t != first+2)
4792 first = t;
4793 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004794 case 'I':
Howard Hinnant93433df2013-06-20 21:49:34 +00004795 t = parse_binary_expression(first+2, last, "-=", db);
4796 if (t != first+2)
4797 first = t;
4798 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004799 case 'l':
Howard Hinnant93433df2013-06-20 21:49:34 +00004800 t = parse_binary_expression(first+2, last, "*", db);
4801 if (t != first+2)
4802 first = t;
4803 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004804 case 'L':
Howard Hinnant93433df2013-06-20 21:49:34 +00004805 t = parse_binary_expression(first+2, last, "*=", db);
4806 if (t != first+2)
4807 first = t;
4808 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004809 case 'm':
4810 if (first+2 != last && first[2] == '_')
Howard Hinnant93433df2013-06-20 21:49:34 +00004811 {
4812 t = parse_prefix_expression(first+3, last, "--", db);
4813 if (t != first+3)
4814 first = t;
4815 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004816 else
4817 {
4818 const char* t1 = parse_expression(first+2, last, db);
4819 if (t1 != first+2)
4820 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004821 if (db.names.empty())
4822 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004823 db.names.back() =
4824 db.make<PostfixExpr>(db.names.back(), "--");
Howard Hinnant6c33e762013-06-17 18:10:34 +00004825 first = t1;
4826 }
4827 }
4828 break;
4829 }
4830 break;
4831 case 'n':
4832 switch (t[1])
4833 {
4834 case 'a':
4835 case 'w':
4836 first = parse_new_expr(first, last, db);
4837 break;
4838 case 'e':
Howard Hinnant93433df2013-06-20 21:49:34 +00004839 t = parse_binary_expression(first+2, last, "!=", db);
4840 if (t != first+2)
4841 first = t;
4842 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004843 case 'g':
Howard Hinnant93433df2013-06-20 21:49:34 +00004844 t = parse_prefix_expression(first+2, last, "-", db);
4845 if (t != first+2)
4846 first = t;
4847 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004848 case 't':
Howard Hinnant93433df2013-06-20 21:49:34 +00004849 t = parse_prefix_expression(first+2, last, "!", db);
4850 if (t != first+2)
4851 first = t;
4852 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004853 case 'x':
Howard Hinnant93433df2013-06-20 21:49:34 +00004854 t = parse_noexcept_expression(first+2, last, db);
4855 if (t != first+2)
4856 first = t;
4857 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004858 }
4859 break;
4860 case 'o':
4861 switch (t[1])
4862 {
4863 case 'n':
4864 return parse_unresolved_name(first, last, db);
4865 case 'o':
Howard Hinnant93433df2013-06-20 21:49:34 +00004866 t = parse_binary_expression(first+2, last, "||", db);
4867 if (t != first+2)
4868 first = t;
4869 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004870 case 'r':
Howard Hinnant93433df2013-06-20 21:49:34 +00004871 t = parse_binary_expression(first+2, last, "|", db);
4872 if (t != first+2)
4873 first = t;
4874 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004875 case 'R':
Howard Hinnant93433df2013-06-20 21:49:34 +00004876 t = parse_binary_expression(first+2, last, "|=", db);
4877 if (t != first+2)
4878 first = t;
4879 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004880 }
4881 break;
4882 case 'p':
4883 switch (t[1])
4884 {
4885 case 'm':
Howard Hinnant93433df2013-06-20 21:49:34 +00004886 t = parse_binary_expression(first+2, last, "->*", db);
4887 if (t != first+2)
4888 first = t;
4889 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004890 case 'l':
Howard Hinnant93433df2013-06-20 21:49:34 +00004891 t = parse_binary_expression(first+2, last, "+", db);
4892 if (t != first+2)
4893 first = t;
4894 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004895 case 'L':
Howard Hinnant93433df2013-06-20 21:49:34 +00004896 t = parse_binary_expression(first+2, last, "+=", db);
4897 if (t != first+2)
4898 first = t;
4899 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004900 case 'p':
4901 if (first+2 != last && first[2] == '_')
Howard Hinnant93433df2013-06-20 21:49:34 +00004902 {
4903 t = parse_prefix_expression(first+3, last, "++", db);
4904 if (t != first+3)
4905 first = t;
4906 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004907 else
4908 {
4909 const char* t1 = parse_expression(first+2, last, db);
4910 if (t1 != first+2)
4911 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004912 if (db.names.empty())
4913 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004914 db.names.back() =
4915 db.make<PostfixExpr>(db.names.back(), "++");
Howard Hinnant6c33e762013-06-17 18:10:34 +00004916 first = t1;
4917 }
4918 }
4919 break;
4920 case 's':
Howard Hinnant93433df2013-06-20 21:49:34 +00004921 t = parse_prefix_expression(first+2, last, "+", db);
4922 if (t != first+2)
4923 first = t;
4924 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004925 case 't':
4926 first = parse_arrow_expr(first, last, db);
4927 break;
4928 }
4929 break;
4930 case 'q':
4931 if (t[1] == 'u')
4932 {
4933 const char* t1 = parse_expression(first+2, last, db);
4934 if (t1 != first+2)
4935 {
4936 const char* t2 = parse_expression(t1, last, db);
4937 if (t2 != t1)
4938 {
4939 const char* t3 = parse_expression(t2, last, db);
4940 if (t3 != t2)
4941 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00004942 if (db.names.size() < 3)
4943 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004944 auto op3 = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004945 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00004946 auto op2 = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004947 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00004948 auto op1 = db.names.back();
4949 db.names.back() =
4950 db.make<ConditionalExpr>(op1, op2, op3);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004951 first = t3;
4952 }
4953 else
4954 {
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004955 if (db.names.size() < 2)
4956 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004957 db.names.pop_back();
4958 db.names.pop_back();
4959 }
4960 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004961 else if (!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00004962 db.names.pop_back();
4963 }
4964 }
4965 break;
4966 case 'r':
4967 switch (t[1])
4968 {
4969 case 'c':
4970 first = parse_reinterpret_cast_expr(first, last, db);
4971 break;
4972 case 'm':
Howard Hinnant93433df2013-06-20 21:49:34 +00004973 t = parse_binary_expression(first+2, last, "%", db);
4974 if (t != first+2)
4975 first = t;
4976 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004977 case 'M':
Howard Hinnant93433df2013-06-20 21:49:34 +00004978 t = parse_binary_expression(first+2, last, "%=", db);
4979 if (t != first+2)
4980 first = t;
4981 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004982 case 's':
Howard Hinnant93433df2013-06-20 21:49:34 +00004983 t = parse_binary_expression(first+2, last, ">>", db);
4984 if (t != first+2)
4985 first = t;
4986 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004987 case 'S':
Howard Hinnant93433df2013-06-20 21:49:34 +00004988 t = parse_binary_expression(first+2, last, ">>=", db);
4989 if (t != first+2)
4990 first = t;
4991 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004992 }
4993 break;
4994 case 's':
4995 switch (t[1])
4996 {
4997 case 'c':
4998 first = parse_static_cast_expr(first, last, db);
4999 break;
5000 case 'p':
5001 first = parse_pack_expansion(first, last, db);
5002 break;
5003 case 'r':
5004 return parse_unresolved_name(first, last, db);
5005 case 't':
5006 first = parse_sizeof_type_expr(first, last, db);
5007 break;
5008 case 'z':
5009 first = parse_sizeof_expr_expr(first, last, db);
5010 break;
5011 case 'Z':
5012 if (last - t >= 3)
5013 {
5014 switch (t[2])
5015 {
5016 case 'T':
5017 first = parse_sizeof_param_pack_expr(first, last, db);
5018 break;
5019 case 'f':
5020 first = parse_sizeof_function_param_pack_expr(first, last, db);
5021 break;
5022 }
5023 }
5024 break;
5025 }
5026 break;
5027 case 't':
5028 switch (t[1])
5029 {
5030 case 'e':
5031 case 'i':
5032 first = parse_typeid_expr(first, last, db);
5033 break;
5034 case 'r':
Erik Pilkington0024acd2017-07-28 00:43:49 +00005035 db.names.push_back(db.make<NameType>("throw"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005036 first += 2;
5037 break;
5038 case 'w':
5039 first = parse_throw_expr(first, last, db);
5040 break;
5041 }
5042 break;
5043 case '1':
5044 case '2':
5045 case '3':
5046 case '4':
5047 case '5':
5048 case '6':
5049 case '7':
5050 case '8':
5051 case '9':
5052 return parse_unresolved_name(first, last, db);
5053 }
5054 }
5055 return first;
5056}
5057
5058// <template-arg> ::= <type> # type or template
5059// ::= X <expression> E # expression
5060// ::= <expr-primary> # simple expressions
5061// ::= J <template-arg>* E # argument pack
5062// ::= LZ <encoding> E # extension
5063
Howard Hinnant6c33e762013-06-17 18:10:34 +00005064const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005065parse_template_arg(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005066{
5067 if (first != last)
5068 {
5069 const char* t;
5070 switch (*first)
5071 {
5072 case 'X':
5073 t = parse_expression(first+1, last, db);
5074 if (t != first+1)
5075 {
5076 if (t != last && *t == 'E')
5077 first = t+1;
5078 }
5079 break;
5080 case 'J':
5081 t = first+1;
5082 if (t == last)
5083 return first;
5084 while (*t != 'E')
5085 {
5086 const char* t1 = parse_template_arg(t, last, db);
5087 if (t1 == t)
5088 return first;
5089 t = t1;
5090 }
5091 first = t+1;
5092 break;
5093 case 'L':
5094 // <expr-primary> or LZ <encoding> E
5095 if (first+1 != last && first[1] == 'Z')
5096 {
5097 t = parse_encoding(first+2, last, db);
5098 if (t != first+2 && t != last && *t == 'E')
5099 first = t+1;
5100 }
5101 else
5102 first = parse_expr_primary(first, last, db);
5103 break;
5104 default:
5105 // <type>
5106 first = parse_type(first, last, db);
5107 break;
5108 }
5109 }
5110 return first;
5111}
5112
5113// <template-args> ::= I <template-arg>* E
5114// extension, the abi says <template-arg>+
5115
Howard Hinnant6c33e762013-06-17 18:10:34 +00005116const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005117parse_template_args(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005118{
5119 if (last - first >= 2 && *first == 'I')
5120 {
5121 if (db.tag_templates)
5122 db.template_param.back().clear();
5123 const char* t = first+1;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005124 size_t begin_idx = db.names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005125 while (*t != 'E')
5126 {
5127 if (db.tag_templates)
5128 db.template_param.emplace_back(db.names.get_allocator());
5129 size_t k0 = db.names.size();
5130 const char* t1 = parse_template_arg(t, last, db);
5131 size_t k1 = db.names.size();
5132 if (db.tag_templates)
5133 db.template_param.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00005134 if (t1 == t || t1 == last || k0 > k1)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005135 return first;
5136 if (db.tag_templates)
5137 {
5138 db.template_param.back().emplace_back(db.names.get_allocator());
5139 for (size_t k = k0; k < k1; ++k)
5140 db.template_param.back().back().push_back(db.names[k]);
5141 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005142 t = t1;
5143 }
Erik Pilkingtonffdace52017-07-30 20:09:55 +00005144 if (begin_idx > db.names.size())
5145 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005146 first = t + 1;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005147 TemplateParams* tp = db.make<TemplateParams>(
5148 db.popTrailingNodeArray(begin_idx));
5149 db.names.push_back(tp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005150 }
5151 return first;
5152}
5153
Erik Pilkington0024acd2017-07-28 00:43:49 +00005154// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
5155// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
Howard Hinnant6c33e762013-06-17 18:10:34 +00005156//
5157// <prefix> ::= <prefix> <unqualified-name>
5158// ::= <template-prefix> <template-args>
5159// ::= <template-param>
5160// ::= <decltype>
5161// ::= # empty
5162// ::= <substitution>
5163// ::= <prefix> <data-member-prefix>
5164// extension ::= L
5165//
5166// <template-prefix> ::= <prefix> <template unqualified-name>
5167// ::= <template-param>
5168// ::= <substitution>
5169
Howard Hinnant6c33e762013-06-17 18:10:34 +00005170const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005171parse_nested_name(const char* first, const char* last, Db& db,
Richard Smith24ecd092014-05-12 18:44:13 +00005172 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005173{
5174 if (first != last && *first == 'N')
5175 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005176 Qualifiers cv;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005177 const char* t0 = parse_cv_qualifiers(first+1, last, cv);
5178 if (t0 == last)
5179 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005180 db.ref = FrefQualNone;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005181 if (*t0 == 'R')
5182 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005183 db.ref = FrefQualLValue;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005184 ++t0;
5185 }
5186 else if (*t0 == 'O')
5187 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005188 db.ref = FrefQualRValue;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005189 ++t0;
5190 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005191 db.names.push_back(db.make<EmptyName>());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005192 if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't')
5193 {
5194 t0 += 2;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005195 db.names.back() = db.make<NameType>("std");
Howard Hinnant6c33e762013-06-17 18:10:34 +00005196 }
5197 if (t0 == last)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005198 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005199 bool pop_subs = false;
Richard Smith24ecd092014-05-12 18:44:13 +00005200 bool component_ends_with_template_args = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005201 while (*t0 != 'E')
5202 {
Richard Smith24ecd092014-05-12 18:44:13 +00005203 component_ends_with_template_args = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005204 const char* t1;
5205 switch (*t0)
5206 {
5207 case 'S':
5208 if (t0 + 1 != last && t0[1] == 't')
5209 goto do_parse_unqualified_name;
5210 t1 = parse_substitution(t0, last, db);
5211 if (t1 != t0 && t1 != last)
5212 {
Erik Pilkingtonffdace52017-07-30 20:09:55 +00005213 if (db.names.size() < 2)
5214 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005215 auto name = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005216 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00005217 if (db.names.back()->K != Node::KEmptyName)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005218 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005219 db.names.back() = db.make<QualifiedName>(
5220 db.names.back(), name);
5221 db.subs.push_back(
5222 Db::sub_type(1, db.names.back(),
5223 db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005224 }
5225 else
Erik Pilkington0024acd2017-07-28 00:43:49 +00005226 db.names.back() = name;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005227 pop_subs = true;
5228 t0 = t1;
5229 }
5230 else
5231 return first;
5232 break;
5233 case 'T':
5234 t1 = parse_template_param(t0, last, db);
5235 if (t1 != t0 && t1 != last)
5236 {
Erik Pilkingtonffdace52017-07-30 20:09:55 +00005237 if (db.names.size() < 2)
5238 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005239 auto name = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005240 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00005241 if (db.names.back()->K != Node::KEmptyName)
5242 db.names.back() =
5243 db.make<QualifiedName>(db.names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005244 else
Erik Pilkington0024acd2017-07-28 00:43:49 +00005245 db.names.back() = name;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005246 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005247 pop_subs = true;
5248 t0 = t1;
5249 }
5250 else
5251 return first;
5252 break;
5253 case 'D':
5254 if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')
5255 goto do_parse_unqualified_name;
5256 t1 = parse_decltype(t0, last, db);
5257 if (t1 != t0 && t1 != last)
5258 {
Erik Pilkingtonffdace52017-07-30 20:09:55 +00005259 if (db.names.size() < 2)
5260 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005261 auto name = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005262 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00005263 if (db.names.back()->K != Node::KEmptyName)
5264 db.names.back() =
5265 db.make<QualifiedName>(db.names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005266 else
Erik Pilkington0024acd2017-07-28 00:43:49 +00005267 db.names.back() = name;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005268 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005269 pop_subs = true;
5270 t0 = t1;
5271 }
5272 else
5273 return first;
5274 break;
5275 case 'I':
5276 t1 = parse_template_args(t0, last, db);
5277 if (t1 != t0 && t1 != last)
5278 {
Erik Pilkingtonffdace52017-07-30 20:09:55 +00005279 if (db.names.size() < 2)
5280 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005281 auto name = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005282 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00005283 db.names.back() = db.make<NameWithTemplateArgs>(
5284 db.names.back(), name);
5285 db.subs.push_back(Db::sub_type(
5286 1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005287 t0 = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00005288 component_ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005289 }
5290 else
5291 return first;
5292 break;
5293 case 'L':
5294 if (++t0 == last)
5295 return first;
5296 break;
5297 default:
5298 do_parse_unqualified_name:
5299 t1 = parse_unqualified_name(t0, last, db);
5300 if (t1 != t0 && t1 != last)
5301 {
Erik Pilkingtonffdace52017-07-30 20:09:55 +00005302 if (db.names.size() < 2)
5303 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005304 auto name = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005305 db.names.pop_back();
Erik Pilkington0024acd2017-07-28 00:43:49 +00005306 if (db.names.back()->K != Node::KEmptyName)
5307 db.names.back() =
5308 db.make<QualifiedName>(db.names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005309 else
Erik Pilkington0024acd2017-07-28 00:43:49 +00005310 db.names.back() = name;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005311 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005312 pop_subs = true;
5313 t0 = t1;
5314 }
5315 else
5316 return first;
5317 }
5318 }
5319 first = t0 + 1;
5320 db.cv = cv;
Howard Hinnantf6725172013-06-21 17:04:24 +00005321 if (pop_subs && !db.subs.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00005322 db.subs.pop_back();
Richard Smith24ecd092014-05-12 18:44:13 +00005323 if (ends_with_template_args)
5324 *ends_with_template_args = component_ends_with_template_args;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005325 }
5326 return first;
5327}
5328
5329// <discriminator> := _ <non-negative number> # when number < 10
5330// := __ <non-negative number> _ # when number >= 10
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00005331// extension := decimal-digit+ # at the end of string
Howard Hinnant6c33e762013-06-17 18:10:34 +00005332
5333const char*
5334parse_discriminator(const char* first, const char* last)
5335{
5336 // parse but ignore discriminator
5337 if (first != last)
5338 {
5339 if (*first == '_')
5340 {
5341 const char* t1 = first+1;
5342 if (t1 != last)
5343 {
5344 if (std::isdigit(*t1))
5345 first = t1+1;
5346 else if (*t1 == '_')
5347 {
5348 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
5349 ;
5350 if (t1 != last && *t1 == '_')
5351 first = t1 + 1;
5352 }
5353 }
5354 }
5355 else if (std::isdigit(*first))
5356 {
5357 const char* t1 = first+1;
5358 for (; t1 != last && std::isdigit(*t1); ++t1)
5359 ;
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00005360 if (t1 == last)
5361 first = last;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005362 }
5363 }
5364 return first;
5365}
5366
5367// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
5368// := Z <function encoding> E s [<discriminator>]
5369// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
5370
Howard Hinnant6c33e762013-06-17 18:10:34 +00005371const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005372parse_local_name(const char* first, const char* last, Db& db,
Richard Smith24ecd092014-05-12 18:44:13 +00005373 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005374{
5375 if (first != last && *first == 'Z')
5376 {
5377 const char* t = parse_encoding(first+1, last, db);
5378 if (t != first+1 && t != last && *t == 'E' && ++t != last)
5379 {
5380 switch (*t)
5381 {
5382 case 's':
5383 first = parse_discriminator(t+1, last);
Howard Hinnant753a30d2013-12-11 19:44:25 +00005384 if (db.names.empty())
5385 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005386 db.names.back() = db.make<QualifiedName>(
5387 db.names.back(), db.make<NameType>("string literal"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005388 break;
5389 case 'd':
5390 if (++t != last)
5391 {
5392 const char* t1 = parse_number(t, last);
5393 if (t1 != last && *t1 == '_')
5394 {
5395 t = t1 + 1;
Richard Smith24ecd092014-05-12 18:44:13 +00005396 t1 = parse_name(t, last, db,
5397 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005398 if (t1 != t)
5399 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005400 if (db.names.size() < 2)
5401 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005402 auto name = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005403 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005404 if (db.names.empty())
5405 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005406 db.names.back() =
5407 db.make<QualifiedName>(db.names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005408 first = t1;
5409 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005410 else if (!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00005411 db.names.pop_back();
5412 }
5413 }
5414 break;
5415 default:
5416 {
Richard Smith24ecd092014-05-12 18:44:13 +00005417 const char* t1 = parse_name(t, last, db,
5418 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005419 if (t1 != t)
5420 {
5421 // parse but ignore discriminator
5422 first = parse_discriminator(t1, last);
Howard Hinnant753a30d2013-12-11 19:44:25 +00005423 if (db.names.size() < 2)
5424 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005425 auto name = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005426 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005427 if (db.names.empty())
5428 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005429 db.names.back() =
5430 db.make<QualifiedName>(db.names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005431 }
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005432 else if (!db.names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00005433 db.names.pop_back();
5434 }
5435 break;
5436 }
5437 }
5438 }
5439 return first;
5440}
5441
5442// <name> ::= <nested-name> // N
5443// ::= <local-name> # See Scope Encoding below // Z
5444// ::= <unscoped-template-name> <template-args>
5445// ::= <unscoped-name>
5446
5447// <unscoped-template-name> ::= <unscoped-name>
5448// ::= <substitution>
5449
Howard Hinnant6c33e762013-06-17 18:10:34 +00005450const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005451parse_name(const char* first, const char* last, Db& db,
Richard Smith24ecd092014-05-12 18:44:13 +00005452 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005453{
5454 if (last - first >= 2)
5455 {
5456 const char* t0 = first;
5457 // extension: ignore L here
5458 if (*t0 == 'L')
5459 ++t0;
5460 switch (*t0)
5461 {
5462 case 'N':
5463 {
Richard Smith24ecd092014-05-12 18:44:13 +00005464 const char* t1 = parse_nested_name(t0, last, db,
5465 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005466 if (t1 != t0)
5467 first = t1;
5468 break;
5469 }
5470 case 'Z':
5471 {
Richard Smith24ecd092014-05-12 18:44:13 +00005472 const char* t1 = parse_local_name(t0, last, db,
5473 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005474 if (t1 != t0)
5475 first = t1;
5476 break;
5477 }
5478 default:
5479 {
5480 const char* t1 = parse_unscoped_name(t0, last, db);
5481 if (t1 != t0)
5482 {
5483 if (t1 != last && *t1 == 'I') // <unscoped-template-name> <template-args>
5484 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005485 if (db.names.empty())
5486 return first;
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005487 db.subs.push_back(Db::sub_type(1, db.names.back(), db.names.get_allocator()));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005488 t0 = t1;
5489 t1 = parse_template_args(t0, last, db);
5490 if (t1 != t0)
5491 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005492 if (db.names.size() < 2)
5493 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005494 auto tmp = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005495 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005496 if (db.names.empty())
5497 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005498 db.names.back() =
5499 db.make<NameWithTemplateArgs>(
5500 db.names.back(), tmp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005501 first = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00005502 if (ends_with_template_args)
5503 *ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005504 }
5505 }
5506 else // <unscoped-name>
5507 first = t1;
5508 }
5509 else
5510 { // try <substitution> <template-args>
5511 t1 = parse_substitution(t0, last, db);
Howard Hinnantb4033ff2013-06-20 01:55:07 +00005512 if (t1 != t0 && t1 != last && *t1 == 'I')
Howard Hinnant6c33e762013-06-17 18:10:34 +00005513 {
5514 t0 = t1;
5515 t1 = parse_template_args(t0, last, db);
5516 if (t1 != t0)
5517 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005518 if (db.names.size() < 2)
5519 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005520 auto tmp = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005521 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005522 if (db.names.empty())
5523 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005524 db.names.back() =
5525 db.make<NameWithTemplateArgs>(
5526 db.names.back(), tmp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005527 first = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00005528 if (ends_with_template_args)
5529 *ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005530 }
5531 }
5532 }
5533 break;
5534 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005535 }
5536 }
5537 return first;
5538}
5539
5540// <call-offset> ::= h <nv-offset> _
5541// ::= v <v-offset> _
5542//
5543// <nv-offset> ::= <offset number>
5544// # non-virtual base override
5545//
5546// <v-offset> ::= <offset number> _ <virtual offset number>
5547// # virtual base override, with vcall offset
5548
5549const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00005550parse_call_offset(const char* first, const char* last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005551{
5552 if (first != last)
5553 {
5554 switch (*first)
5555 {
5556 case 'h':
5557 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005558 const char* t = parse_number(first + 1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005559 if (t != first + 1 && t != last && *t == '_')
5560 first = t + 1;
5561 }
5562 break;
5563 case 'v':
5564 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005565 const char* t = parse_number(first + 1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005566 if (t != first + 1 && t != last && *t == '_')
5567 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005568 const char* t2 = parse_number(++t, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005569 if (t2 != t && t2 != last && *t2 == '_')
5570 first = t2 + 1;
5571 }
5572 }
5573 break;
5574 }
5575 }
5576 return first;
5577}
5578
5579// <special-name> ::= TV <type> # virtual table
5580// ::= TT <type> # VTT structure (construction vtable index)
5581// ::= TI <type> # typeinfo structure
5582// ::= TS <type> # typeinfo name (null-terminated byte string)
5583// ::= Tc <call-offset> <call-offset> <base encoding>
5584// # base is the nominal target function of thunk
5585// # first call-offset is 'this' adjustment
5586// # second call-offset is result adjustment
5587// ::= T <call-offset> <base encoding>
5588// # base is the nominal target function of thunk
5589// ::= GV <object name> # Guard variable for one-time initialization
5590// # No <type>
David Bozierc2fa8f12017-01-31 15:18:56 +00005591// ::= TW <object name> # Thread-local wrapper
5592// ::= TH <object name> # Thread-local initialization
Howard Hinnantf2700352011-12-09 20:07:56 +00005593// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
5594// extension ::= GR <object name> # reference temporary for object
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005595
5596const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005597parse_special_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005598{
5599 if (last - first > 2)
5600 {
5601 const char* t;
5602 switch (*first)
5603 {
5604 case 'T':
5605 switch (first[1])
5606 {
5607 case 'V':
5608 // TV <type> # virtual table
Howard Hinnant6c33e762013-06-17 18:10:34 +00005609 t = parse_type(first+2, last, db);
5610 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005611 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005612 if (db.names.empty())
5613 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005614 db.names.back() =
5615 db.make<SpecialName>("vtable for ", db.names.back());
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005616 first = t;
5617 }
5618 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005619 case 'T':
5620 // TT <type> # VTT structure (construction vtable index)
5621 t = parse_type(first+2, last, db);
Howard Hinnantf2700352011-12-09 20:07:56 +00005622 if (t != first+2)
5623 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005624 if (db.names.empty())
5625 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005626 db.names.back() =
5627 db.make<SpecialName>("VTT for ", db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005628 first = t;
5629 }
5630 break;
5631 case 'I':
5632 // TI <type> # typeinfo structure
5633 t = parse_type(first+2, last, db);
5634 if (t != first+2)
5635 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005636 if (db.names.empty())
5637 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005638 db.names.back() =
5639 db.make<SpecialName>("typeinfo for ", db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005640 first = t;
5641 }
5642 break;
5643 case 'S':
5644 // TS <type> # typeinfo name (null-terminated byte string)
5645 t = parse_type(first+2, last, db);
5646 if (t != first+2)
5647 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005648 if (db.names.empty())
5649 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005650 db.names.back() =
5651 db.make<SpecialName>("typeinfo name for ", db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005652 first = t;
5653 }
5654 break;
5655 case 'c':
5656 // Tc <call-offset> <call-offset> <base encoding>
5657 {
5658 const char* t0 = parse_call_offset(first+2, last);
5659 if (t0 == first+2)
5660 break;
5661 const char* t1 = parse_call_offset(t0, last);
5662 if (t1 == t0)
5663 break;
5664 t = parse_encoding(t1, last, db);
5665 if (t != t1)
5666 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005667 if (db.names.empty())
5668 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005669 db.names.back() =
5670 db.make<SpecialName>("covariant return thunk to ",
5671 db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005672 first = t;
5673 }
5674 }
5675 break;
5676 case 'C':
5677 // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
5678 t = parse_type(first+2, last, db);
5679 if (t != first+2)
5680 {
5681 const char* t0 = parse_number(t, last);
Howard Hinnantf2700352011-12-09 20:07:56 +00005682 if (t0 != t && t0 != last && *t0 == '_')
5683 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005684 const char* t1 = parse_type(++t0, last, db);
Howard Hinnantf2700352011-12-09 20:07:56 +00005685 if (t1 != t0)
5686 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005687 if (db.names.size() < 2)
5688 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005689 auto left = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005690 db.names.pop_back();
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005691 if (db.names.empty())
5692 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005693 db.names.back() = db.make<CtorVtableSpecialName>(
5694 left, db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005695 first = t1;
Howard Hinnantf2700352011-12-09 20:07:56 +00005696 }
5697 }
5698 }
5699 break;
David Bozierc2fa8f12017-01-31 15:18:56 +00005700 case 'W':
5701 // TW <object name> # Thread-local wrapper
5702 t = parse_name(first + 2, last, db);
5703 if (t != first + 2)
5704 {
5705 if (db.names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005706 return first;
5707 db.names.back() =
5708 db.make<SpecialName>("thread-local wrapper routine for ",
5709 db.names.back());
David Bozierc2fa8f12017-01-31 15:18:56 +00005710 first = t;
5711 }
5712 break;
5713 case 'H':
5714 //TH <object name> # Thread-local initialization
5715 t = parse_name(first + 2, last, db);
5716 if (t != first + 2)
5717 {
5718 if (db.names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005719 return first;
5720 db.names.back() = db.make<SpecialName>(
5721 "thread-local initialization routine for ", db.names.back());
David Bozierc2fa8f12017-01-31 15:18:56 +00005722 first = t;
5723 }
5724 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005725 default:
5726 // T <call-offset> <base encoding>
5727 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005728 const char* t0 = parse_call_offset(first+1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005729 if (t0 == first+1)
5730 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005731 t = parse_encoding(t0, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005732 if (t != t0)
5733 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005734 if (db.names.empty())
5735 return first;
Marshall Clowfdccce62015-10-12 20:45:05 +00005736 if (first[1] == 'v')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005737 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005738 db.names.back() =
5739 db.make<SpecialName>("virtual thunk to ",
5740 db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005741 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005742 }
5743 else
5744 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005745 db.names.back() =
5746 db.make<SpecialName>("non-virtual thunk to ",
5747 db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005748 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005749 }
5750 }
5751 }
5752 break;
5753 }
5754 break;
5755 case 'G':
Howard Hinnantf2700352011-12-09 20:07:56 +00005756 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005757 {
Howard Hinnantf2700352011-12-09 20:07:56 +00005758 case 'V':
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005759 // GV <object name> # Guard variable for one-time initialization
Howard Hinnant6c33e762013-06-17 18:10:34 +00005760 t = parse_name(first+2, last, db);
5761 if (t != first+2)
5762 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005763 if (db.names.empty())
5764 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005765 db.names.back() =
5766 db.make<SpecialName>("guard variable for ", db.names.back());
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005767 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005768 }
Howard Hinnantf2700352011-12-09 20:07:56 +00005769 break;
5770 case 'R':
5771 // extension ::= GR <object name> # reference temporary for object
Howard Hinnant6c33e762013-06-17 18:10:34 +00005772 t = parse_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005773 if (t != first+2)
5774 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005775 if (db.names.empty())
5776 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005777 db.names.back() =
5778 db.make<SpecialName>("reference temporary for ",
5779 db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005780 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005781 }
5782 break;
5783 }
5784 break;
5785 }
5786 }
5787 return first;
5788}
5789
Howard Hinnant753a30d2013-12-11 19:44:25 +00005790template <class T>
5791class save_value
5792{
5793 T& restore_;
5794 T original_value_;
5795public:
5796 save_value(T& restore)
5797 : restore_(restore),
5798 original_value_(restore)
5799 {}
5800
5801 ~save_value()
5802 {
5803 restore_ = std::move(original_value_);
5804 }
5805
5806 save_value(const save_value&) = delete;
5807 save_value& operator=(const save_value&) = delete;
5808};
5809
Howard Hinnant6c33e762013-06-17 18:10:34 +00005810// <encoding> ::= <function name> <bare-function-type>
5811// ::= <data name>
5812// ::= <special-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005813
5814const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005815parse_encoding(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005816{
5817 if (first != last)
5818 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005819 save_value<decltype(db.encoding_depth)> su(db.encoding_depth);
5820 ++db.encoding_depth;
5821 save_value<decltype(db.tag_templates)> sb(db.tag_templates);
5822 if (db.encoding_depth > 1)
5823 db.tag_templates = true;
Tamas Berghammer413296b2017-05-24 11:21:34 +00005824 save_value<decltype(db.parsed_ctor_dtor_cv)> sp(db.parsed_ctor_dtor_cv);
5825 db.parsed_ctor_dtor_cv = false;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005826 switch (*first)
5827 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005828 case 'G':
5829 case 'T':
5830 first = parse_special_name(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005831 break;
5832 default:
Howard Hinnant6c33e762013-06-17 18:10:34 +00005833 {
Richard Smith24ecd092014-05-12 18:44:13 +00005834 bool ends_with_template_args = false;
5835 const char* t = parse_name(first, last, db,
5836 &ends_with_template_args);
Erik Pilkington0024acd2017-07-28 00:43:49 +00005837 if (db.names.empty())
5838 return first;
5839 Qualifiers cv = db.cv;
5840 FunctionRefQual ref = db.ref;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005841 if (t != first)
Howard Hinnantab87dcf2011-12-15 20:02:15 +00005842 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005843 if (t != last && *t != 'E' && *t != '.')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005844 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005845 save_value<bool> sb2(db.tag_templates);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005846 db.tag_templates = false;
5847 const char* t2;
Howard Hinnant753a30d2013-12-11 19:44:25 +00005848 if (db.names.empty())
5849 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005850 if (!db.names.back())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005851 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005852 Node* return_type = nullptr;
Richard Smith24ecd092014-05-12 18:44:13 +00005853 if (!db.parsed_ctor_dtor_cv && ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005854 {
5855 t2 = parse_type(t, last, db);
5856 if (t2 == t)
5857 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005858 if (db.names.size() < 1)
Howard Hinnant753a30d2013-12-11 19:44:25 +00005859 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005860 return_type = db.names.back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005861 db.names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005862 t = t2;
5863 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005864
5865 Node* result = nullptr;
5866
Howard Hinnant6c33e762013-06-17 18:10:34 +00005867 if (t != last && *t == 'v')
5868 {
5869 ++t;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005870 Node* name = db.names.back();
5871 db.names.pop_back();
5872 result = db.make<TopLevelFunctionDecl>(
5873 return_type, name, NodeArray());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005874 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005875 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005876 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005877 size_t params_begin = db.names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005878 while (true)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005879 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005880 t2 = parse_type(t, last, db);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005881 if (t2 == t)
5882 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005883 t = t2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005884 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005885 if (db.names.size() < params_begin)
5886 return first;
5887 NodeArray params =
5888 db.popTrailingNodeArray(params_begin);
5889 if (db.names.empty())
5890 return first;
5891 Node* name = db.names.back();
5892 db.names.pop_back();
5893 result = db.make<TopLevelFunctionDecl>(
5894 return_type, name, params);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005895 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005896 if (ref != FrefQualNone)
5897 result = db.make<FunctionRefQualType>(result, ref);
5898 if (cv != QualNone)
5899 result = db.make<FunctionQualType>(result, cv);
5900 db.names.push_back(result);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005901 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005902 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005903 else
5904 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005905 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005906 break;
5907 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005908 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005909 }
5910 return first;
5911}
5912
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005913// _block_invoke
5914// _block_invoke<decimal-digit>+
5915// _block_invoke_<decimal-digit>+
5916
5917const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005918parse_block_invoke(const char* first, const char* last, Db& db)
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005919{
5920 if (last - first >= 13)
5921 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005922 // FIXME: strcmp?
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005923 const char test[] = "_block_invoke";
5924 const char* t = first;
5925 for (int i = 0; i < 13; ++i, ++t)
5926 {
5927 if (*t != test[i])
5928 return first;
5929 }
5930 if (t != last)
5931 {
5932 if (*t == '_')
5933 {
5934 // must have at least 1 decimal digit
Howard Hinnant6c33e762013-06-17 18:10:34 +00005935 if (++t == last || !std::isdigit(*t))
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005936 return first;
5937 ++t;
5938 }
5939 // parse zero or more digits
5940 while (t != last && isdigit(*t))
5941 ++t;
5942 }
Howard Hinnant753a30d2013-12-11 19:44:25 +00005943 if (db.names.empty())
5944 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005945 db.names.back() =
5946 db.make<SpecialName>("invocation function for block in ",
5947 db.names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005948 first = t;
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005949 }
5950 return first;
5951}
5952
Howard Hinnant6c33e762013-06-17 18:10:34 +00005953// extension
5954// <dot-suffix> := .<anything and everything>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005955
5956const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005957parse_dot_suffix(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005958{
Howard Hinnant6c33e762013-06-17 18:10:34 +00005959 if (first != last && *first == '.')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005960 {
Howard Hinnant753a30d2013-12-11 19:44:25 +00005961 if (db.names.empty())
5962 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005963 db.names.back() =
5964 db.make<DotSuffix>(db.names.back(), StringView(first, last));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005965 first = last;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005966 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005967 return first;
5968}
5969
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005970// <block-involcaton-function> ___Z<encoding>_block_invoke
5971// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+
5972// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005973// <mangled-name> ::= _Z<encoding>
5974// ::= <type>
5975
5976void
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005977demangle(const char* first, const char* last, Db& db, int& status)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005978{
Howard Hinnanteb8d46c2013-06-23 17:14:35 +00005979 if (first >= last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005980 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005981 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005982 return;
5983 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005984 if (*first == '_')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005985 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005986 if (last - first >= 4)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005987 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005988 if (first[1] == 'Z')
5989 {
5990 const char* t = parse_encoding(first+2, last, db);
5991 if (t != first+2 && t != last && *t == '.')
5992 t = parse_dot_suffix(t, last, db);
5993 if (t != last)
5994 status = invalid_mangled_name;
5995 }
5996 else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z')
5997 {
5998 const char* t = parse_encoding(first+4, last, db);
5999 if (t != first+4 && t != last)
6000 {
6001 const char* t1 = parse_block_invoke(t, last, db);
6002 if (t1 != last)
6003 status = invalid_mangled_name;
6004 }
6005 else
6006 status = invalid_mangled_name;
6007 }
6008 else
6009 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00006010 }
6011 else
Howard Hinnant6c33e762013-06-17 18:10:34 +00006012 status = invalid_mangled_name;
6013 }
6014 else
6015 {
6016 const char* t = parse_type(first, last, db);
6017 if (t != last)
6018 status = invalid_mangled_name;
6019 }
Howard Hinnanteb8d46c2013-06-23 17:14:35 +00006020 if (status == success && db.names.empty())
6021 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00006022}
6023
Howard Hinnant6c33e762013-06-17 18:10:34 +00006024} // unnamed namespace
6025
Saleem Abdulrasoolb4ec5792015-12-04 02:14:58 +00006026extern "C" _LIBCXXABI_FUNC_VIS char *
Saleem Abdulrasool77a304b2015-12-04 02:14:41 +00006027__cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status) {
Howard Hinnant6c33e762013-06-17 18:10:34 +00006028 if (mangled_name == nullptr || (buf != nullptr && n == nullptr))
Howard Hinnantd213ffd2011-05-05 15:27:28 +00006029 {
6030 if (status)
Howard Hinnant6c33e762013-06-17 18:10:34 +00006031 *status = invalid_args;
6032 return nullptr;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00006033 }
Saleem Abdulrasool8cfa5a32016-11-14 01:55:54 +00006034
Howard Hinnant8ad6a222013-07-26 22:14:53 +00006035 size_t internal_size = buf != nullptr ? *n : 0;
Howard Hinnant6c33e762013-06-17 18:10:34 +00006036 arena<bs> a;
Howard Hinnant6c33e762013-06-17 18:10:34 +00006037 Db db(a);
Howard Hinnant6c33e762013-06-17 18:10:34 +00006038 db.template_param.emplace_back(a);
Howard Hinnant6c33e762013-06-17 18:10:34 +00006039 int internal_status = success;
Jonathan Roelofs0cbb1da2017-01-18 18:12:39 +00006040 size_t len = std::strlen(mangled_name);
Howard Hinnantb2d1f942013-06-23 19:52:45 +00006041 demangle(mangled_name, mangled_name + len, db,
Howard Hinnant6c33e762013-06-17 18:10:34 +00006042 internal_status);
Erik Pilkington0024acd2017-07-28 00:43:49 +00006043
Howard Hinnantb2d1f942013-06-23 19:52:45 +00006044 if (internal_status == success && db.fix_forward_references &&
6045 !db.template_param.empty() && !db.template_param.front().empty())
6046 {
6047 db.fix_forward_references = false;
6048 db.tag_templates = false;
6049 db.names.clear();
6050 db.subs.clear();
6051 demangle(mangled_name, mangled_name + len, db, internal_status);
6052 if (db.fix_forward_references)
6053 internal_status = invalid_mangled_name;
6054 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00006055
Howard Hinnant6c33e762013-06-17 18:10:34 +00006056 if (internal_status == success)
6057 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00006058 if (!buf)
Howard Hinnant6c33e762013-06-17 18:10:34 +00006059 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00006060 internal_size = 1024;
6061 buf = static_cast<char*>(std::malloc(internal_size));
Howard Hinnant6c33e762013-06-17 18:10:34 +00006062 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00006063
6064 if (buf)
Howard Hinnant6c33e762013-06-17 18:10:34 +00006065 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00006066 OutputStream s(buf, internal_size);
6067 db.names.back()->print(s);
6068 s += '\0';
6069 if (n) *n = s.getCurrentPosition();
6070 buf = s.getBuffer();
Howard Hinnant6c33e762013-06-17 18:10:34 +00006071 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00006072 else
6073 internal_status = memory_alloc_failure;
Howard Hinnant6c33e762013-06-17 18:10:34 +00006074 }
6075 else
6076 buf = nullptr;
6077 if (status)
6078 *status = internal_status;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00006079 return buf;
6080}
6081
Howard Hinnant6c33e762013-06-17 18:10:34 +00006082} // __cxxabiv1