blob: 5faf0ae263b606b12aa72a7a0154860e6e1e17bb [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
Erik Pilkington1c300b92017-11-21 15:04:08 +000010// FIXME: (possibly) incomplete list of features that clang mangles that this
11// file does not yet support:
12// - enable_if attribute
Erik Pilkington1c300b92017-11-21 15:04:08 +000013// - C++ modules TS
Erik Pilkington761e6b02018-01-31 20:17:06 +000014// - All C++14 and C++17 features
Erik Pilkington1c300b92017-11-21 15:04:08 +000015
Howard Hinnant6c33e762013-06-17 18:10:34 +000016#define _LIBCPP_NO_EXCEPTIONS
Howard Hinnantd213ffd2011-05-05 15:27:28 +000017
Saleem Abdulrasoolb4ec5792015-12-04 02:14:58 +000018#include "__cxxabi_config.h"
19
Howard Hinnant6c33e762013-06-17 18:10:34 +000020#include <vector>
Howard Hinnantd213ffd2011-05-05 15:27:28 +000021#include <algorithm>
Howard Hinnant6c33e762013-06-17 18:10:34 +000022#include <numeric>
Erik Pilkington761e6b02018-01-31 20:17:06 +000023#include <cassert>
Erik Pilkington77101542017-07-28 00:53:30 +000024#include <cstdio>
Howard Hinnant6c33e762013-06-17 18:10:34 +000025#include <cstdlib>
26#include <cstring>
27#include <cctype>
Howard Hinnantd213ffd2011-05-05 15:27:28 +000028
Nico Weberb4c998b2015-09-20 18:10:46 +000029#ifdef _MSC_VER
30// snprintf is implemented in VS 2015
31#if _MSC_VER < 1900
32#define snprintf _snprintf_s
33#endif
34#endif
35
Erik Pilkington761e6b02018-01-31 20:17:06 +000036#ifndef NDEBUG
37#if __has_attribute(noinline) && __has_attribute(used)
38#define DUMP_METHOD __attribute__((noinline,used))
39#else
40#define DUMP_METHOD
41#endif
42#endif
Howard Hinnantd213ffd2011-05-05 15:27:28 +000043
Erik Pilkington761e6b02018-01-31 20:17:06 +000044namespace {
Howard Hinnantd213ffd2011-05-05 15:27:28 +000045
Erik Pilkington0024acd2017-07-28 00:43:49 +000046class StringView {
47 const char *First;
48 const char *Last;
49
50public:
51 template <size_t N>
52 StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {}
Erik Pilkington7de232a2017-08-10 02:48:13 +000053 StringView(const char *First_, const char *Last_) : First(First_), Last(Last_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +000054 StringView() : First(nullptr), Last(nullptr) {}
55
56 StringView substr(size_t From, size_t To) {
57 if (To >= size())
58 To = size() - 1;
59 if (From >= size())
60 From = size() - 1;
61 return StringView(First + From, First + To);
62 }
63
64 StringView dropFront(size_t N) const {
65 if (N >= size())
66 N = size() - 1;
67 return StringView(First + N, Last);
68 }
69
70 bool startsWith(StringView Str) const {
71 if (Str.size() > size())
72 return false;
73 return std::equal(Str.begin(), Str.end(), begin());
74 }
75
76 const char &operator[](size_t Idx) const { return *(begin() + Idx); }
77
78 const char *begin() const { return First; }
79 const char *end() const { return Last; }
80 size_t size() const { return static_cast<size_t>(Last - First); }
Erik Pilkington761e6b02018-01-31 20:17:06 +000081 bool empty() const { return First == Last; }
Erik Pilkington0024acd2017-07-28 00:43:49 +000082};
83
84bool operator==(const StringView &LHS, const StringView &RHS) {
85 return LHS.size() == RHS.size() &&
86 std::equal(LHS.begin(), LHS.end(), RHS.begin());
87}
88
89// Stream that AST nodes write their string representation into after the AST
90// has been parsed.
91class OutputStream {
92 char *Buffer;
93 size_t CurrentPosition;
94 size_t BufferCapacity;
95
96 // Ensure there is at least n more positions in buffer.
97 void grow(size_t N) {
98 if (N + CurrentPosition >= BufferCapacity) {
99 BufferCapacity *= 2;
100 if (BufferCapacity < N + CurrentPosition)
101 BufferCapacity = N + CurrentPosition;
102 Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
103 }
104 }
105
106public:
107 OutputStream(char *StartBuf, size_t Size)
108 : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {}
109
Erik Pilkington761e6b02018-01-31 20:17:06 +0000110 /// If a ParameterPackExpansion (or similar type) is encountered, the offset
111 /// into the pack that we're currently printing.
112 unsigned CurrentPackIndex = std::numeric_limits<unsigned>::max();
113
Erik Pilkington0024acd2017-07-28 00:43:49 +0000114 OutputStream &operator+=(StringView R) {
115 size_t Size = R.size();
116 if (Size == 0)
117 return *this;
118 grow(Size);
119 memmove(Buffer + CurrentPosition, R.begin(), Size);
120 CurrentPosition += Size;
121 return *this;
122 }
123
124 OutputStream &operator+=(char C) {
125 grow(1);
126 Buffer[CurrentPosition++] = C;
127 return *this;
128 }
129
Erik Pilkington761e6b02018-01-31 20:17:06 +0000130 size_t getCurrentPosition() const { return CurrentPosition; };
Erik Pilkington0024acd2017-07-28 00:43:49 +0000131
132 char back() const {
133 return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0';
134 }
135
136 bool empty() const { return CurrentPosition == 0; }
137
138 char *getBuffer() { return Buffer; }
139 char *getBufferEnd() { return Buffer + CurrentPosition - 1; }
140 size_t getBufferCapacity() { return BufferCapacity; }
141};
142
Erik Pilkington761e6b02018-01-31 20:17:06 +0000143template <class T>
144class SwapAndRestore {
145 T &Restore;
146 T OriginalValue;
147public:
148 SwapAndRestore(T& Restore_, T NewVal)
149 : Restore(Restore_), OriginalValue(Restore) {
150 Restore = std::move(NewVal);
151 }
152 ~SwapAndRestore() { Restore = std::move(OriginalValue); }
153
154 SwapAndRestore(const SwapAndRestore &) = delete;
155 SwapAndRestore &operator=(const SwapAndRestore &) = delete;
156};
157
Erik Pilkington0024acd2017-07-28 00:43:49 +0000158// Base class of all AST nodes. The AST is built by the parser, then is
159// traversed by the printLeft/Right functions to produce a demangled string.
160class Node {
161public:
162 enum Kind : unsigned char {
163 KDotSuffix,
164 KVendorExtQualType,
165 KQualType,
166 KConversionOperatorType,
167 KPostfixQualifiedType,
Erik Pilkington13fb7dc2018-02-13 00:15:53 +0000168 KElaboratedTypeSpefType,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000169 KNameType,
Erik Pilkington5bff4122017-11-22 20:38:22 +0000170 KAbiTagAttr,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000171 KObjCProtoName,
172 KPointerType,
173 KLValueReferenceType,
174 KRValueReferenceType,
175 KPointerToMemberType,
176 KArrayType,
177 KFunctionType,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000178 KFunctionEncoding,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000179 KFunctionQualType,
180 KFunctionRefQualType,
181 KLiteralOperator,
182 KSpecialName,
183 KCtorVtableSpecialName,
184 KQualifiedName,
185 KEmptyName,
186 KVectorType,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000187 KParameterPack,
188 KTemplateArgumentPack,
189 KParameterPackExpansion,
190 KTemplateArgs,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000191 KNameWithTemplateArgs,
192 KGlobalQualifiedName,
193 KStdQualifiedName,
194 KExpandedSpecialSubstitution,
195 KSpecialSubstitution,
196 KCtorDtorName,
197 KDtorName,
198 KUnnamedTypeName,
199 KLambdaTypeName,
200 KExpr,
201 };
202
Erik Pilkington761e6b02018-01-31 20:17:06 +0000203 static constexpr unsigned NoParameterPack =
204 std::numeric_limits<unsigned>::max();
205 unsigned ParameterPackSize = NoParameterPack;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000206
Erik Pilkington761e6b02018-01-31 20:17:06 +0000207 Kind K;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000208
Erik Pilkington761e6b02018-01-31 20:17:06 +0000209 /// Three-way bool to track a cached value. Unknown is possible if this node
210 /// has an unexpanded parameter pack below it that may affect this cache.
211 enum class Cache : unsigned char { Yes, No, Unknown, };
Erik Pilkington0024acd2017-07-28 00:43:49 +0000212
Erik Pilkington761e6b02018-01-31 20:17:06 +0000213 /// Tracks if this node has a component on its right side, in which case we
214 /// need to call printRight.
215 Cache RHSComponentCache;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000216
Erik Pilkington761e6b02018-01-31 20:17:06 +0000217 /// Track if this node is a (possibly qualified) array type. This can affect
218 /// how we format the output string.
219 Cache ArrayCache;
220
221 /// Track if this node is a (possibly qualified) function type. This can
222 /// affect how we format the output string.
223 Cache FunctionCache;
224
225 Node(Kind K_, unsigned ParameterPackSize_ = NoParameterPack,
226 Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No,
227 Cache FunctionCache_ = Cache::No)
228 : ParameterPackSize(ParameterPackSize_), K(K_),
229 RHSComponentCache(RHSComponentCache_), ArrayCache(ArrayCache_),
230 FunctionCache(FunctionCache_) {}
231
232 bool containsUnexpandedParameterPack() const {
233 return ParameterPackSize != NoParameterPack;
234 }
235
236 bool hasRHSComponent(OutputStream &S) const {
237 if (RHSComponentCache != Cache::Unknown)
238 return RHSComponentCache == Cache::Yes;
239 return hasRHSComponentSlow(S);
240 }
241
242 bool hasArray(OutputStream &S) const {
243 if (ArrayCache != Cache::Unknown)
244 return ArrayCache == Cache::Yes;
245 return hasArraySlow(S);
246 }
247
248 bool hasFunction(OutputStream &S) const {
249 if (FunctionCache != Cache::Unknown)
250 return FunctionCache == Cache::Yes;
251 return hasFunctionSlow(S);
252 }
253
254 Kind getKind() const { return K; }
255
256 virtual bool hasRHSComponentSlow(OutputStream &) const { return false; }
257 virtual bool hasArraySlow(OutputStream &) const { return false; }
258 virtual bool hasFunctionSlow(OutputStream &) const { return false; }
259
260 /// If this node is a pack expansion that expands to 0 elements. This can have
261 /// an effect on how we should format the output.
262 bool isEmptyPackExpansion() const;
263
264 void print(OutputStream &S) const {
265 printLeft(S);
266 if (RHSComponentCache != Cache::No)
267 printRight(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000268 }
269
270 // Print the "left" side of this Node into OutputStream.
271 virtual void printLeft(OutputStream &) const = 0;
272
273 // Print the "right". This distinction is necessary to represent C++ types
274 // that appear on the RHS of their subtype, such as arrays or functions.
275 // Since most types don't have such a component, provide a default
276 // implemenation.
277 virtual void printRight(OutputStream &) const {}
278
279 virtual StringView getBaseName() const { return StringView(); }
280
281 // Silence compiler warnings, this dtor will never be called.
282 virtual ~Node() = default;
Erik Pilkington761e6b02018-01-31 20:17:06 +0000283
284#ifndef NDEBUG
285 DUMP_METHOD void dump() const {
286 char *Buffer = static_cast<char*>(std::malloc(1024));
287 OutputStream S(Buffer, 1024);
288 print(S);
289 S += '\0';
290 printf("Symbol dump for %p: %s\n", (const void*)this, S.getBuffer());
291 std::free(S.getBuffer());
292 }
293#endif
Erik Pilkington0024acd2017-07-28 00:43:49 +0000294};
295
296class NodeArray {
297 Node **Elements;
298 size_t NumElements;
299
300public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000301 NodeArray() : Elements(nullptr), NumElements(0) {}
Erik Pilkington414f1a52017-08-09 22:45:35 +0000302 NodeArray(Node **Elements_, size_t NumElements_)
303 : Elements(Elements_), NumElements(NumElements_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000304
305 bool empty() const { return NumElements == 0; }
306 size_t size() const { return NumElements; }
307
Erik Pilkington761e6b02018-01-31 20:17:06 +0000308 Node **begin() const { return Elements; }
309 Node **end() const { return Elements + NumElements; }
310
311 Node *operator[](size_t Idx) const { return Elements[Idx]; }
312
313 void printWithComma(OutputStream &S) const {
314 bool FirstElement = true;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000315 for (size_t Idx = 0; Idx != NumElements; ++Idx) {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000316 if (Elements[Idx]->isEmptyPackExpansion())
317 continue;
318 if (!FirstElement)
319 S += ", ";
320 FirstElement = false;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000321 Elements[Idx]->print(S);
322 }
323 }
324};
325
326class DotSuffix final : public Node {
327 const Node *Prefix;
328 const StringView Suffix;
329
330public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000331 DotSuffix(Node *Prefix_, StringView Suffix_)
332 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000333
334 void printLeft(OutputStream &s) const override {
335 Prefix->print(s);
336 s += " (";
337 s += Suffix;
338 s += ")";
339 }
340};
341
342class VendorExtQualType final : public Node {
Erik Pilkington0024acd2017-07-28 00:43:49 +0000343 const Node *Ty;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000344 StringView Ext;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000345
346public:
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000347 VendorExtQualType(Node *Ty_, StringView Ext_)
348 : Node(KVendorExtQualType, Ty_->ParameterPackSize),
Erik Pilkington761e6b02018-01-31 20:17:06 +0000349 Ty(Ty_), Ext(Ext_) {}
350
Erik Pilkington0024acd2017-07-28 00:43:49 +0000351 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000352 Ty->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000353 S += " ";
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000354 S += Ext;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000355 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000356};
357
358enum Qualifiers {
359 QualNone = 0,
360 QualConst = 0x1,
361 QualVolatile = 0x2,
362 QualRestrict = 0x4,
363};
364
365void addQualifiers(Qualifiers &Q1, Qualifiers Q2) {
366 Q1 = static_cast<Qualifiers>(Q1 | Q2);
367}
368
369class QualType : public Node {
370protected:
371 const Qualifiers Quals;
372 const Node *Child;
373
374 void printQuals(OutputStream &S) const {
375 if (Quals & QualConst)
376 S += " const";
377 if (Quals & QualVolatile)
378 S += " volatile";
379 if (Quals & QualRestrict)
380 S += " restrict";
381 }
382
383public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000384 QualType(Node *Child_, Qualifiers Quals_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000385 : Node(KQualType, Child_->ParameterPackSize, Child_->RHSComponentCache,
386 Child_->ArrayCache, Child_->FunctionCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000387 Quals(Quals_), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000388
Erik Pilkington761e6b02018-01-31 20:17:06 +0000389 bool hasRHSComponentSlow(OutputStream &S) const override {
390 return Child->hasRHSComponent(S);
391 }
392 bool hasArraySlow(OutputStream &S) const override {
393 return Child->hasArray(S);
394 }
395 bool hasFunctionSlow(OutputStream &S) const override {
396 return Child->hasFunction(S);
397 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000398
399 void printLeft(OutputStream &S) const override {
400 Child->printLeft(S);
401 printQuals(S);
402 }
403
404 void printRight(OutputStream &S) const override { Child->printRight(S); }
405};
406
407class ConversionOperatorType final : public Node {
408 const Node *Ty;
409
410public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000411 ConversionOperatorType(Node *Ty_)
412 : Node(KConversionOperatorType, Ty_->ParameterPackSize), Ty(Ty_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000413
414 void printLeft(OutputStream &S) const override {
415 S += "operator ";
416 Ty->print(S);
417 }
418};
419
420class PostfixQualifiedType final : public Node {
421 const Node *Ty;
422 const StringView Postfix;
423
424public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000425 PostfixQualifiedType(Node *Ty_, StringView Postfix_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000426 : Node(KPostfixQualifiedType, Ty_->ParameterPackSize),
427 Ty(Ty_), Postfix(Postfix_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000428
429 void printLeft(OutputStream &s) const override {
430 Ty->printLeft(s);
431 s += Postfix;
432 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000433};
434
435class NameType final : public Node {
436 const StringView Name;
437
438public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000439 NameType(StringView Name_) : Node(KNameType), Name(Name_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000440
441 StringView getName() const { return Name; }
442 StringView getBaseName() const override { return Name; }
443
444 void printLeft(OutputStream &s) const override { s += Name; }
445};
446
Erik Pilkington13fb7dc2018-02-13 00:15:53 +0000447class ElaboratedTypeSpefType : public Node {
448 StringView Kind;
449 Node *Child;
450public:
451 ElaboratedTypeSpefType(StringView Kind_, Node *Child_)
452 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {
453 ParameterPackSize = Child->ParameterPackSize;
454 }
455
456 void printLeft(OutputStream &S) const override {
457 S += Kind;
458 S += ' ';
459 Child->print(S);
460 }
461};
462
Erik Pilkington5bff4122017-11-22 20:38:22 +0000463class AbiTagAttr final : public Node {
464 const Node* Base;
465 StringView Tag;
466public:
467 AbiTagAttr(const Node* Base_, StringView Tag_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000468 : Node(KAbiTagAttr, Base_->ParameterPackSize, Base_->RHSComponentCache,
469 Base_->ArrayCache, Base_->FunctionCache),
470 Base(Base_), Tag(Tag_) {}
Erik Pilkington5bff4122017-11-22 20:38:22 +0000471
472 void printLeft(OutputStream &S) const override {
473 Base->printLeft(S);
474 S += "[abi:";
475 S += Tag;
476 S += "]";
477 }
478};
479
Erik Pilkington0024acd2017-07-28 00:43:49 +0000480class ObjCProtoName : public Node {
481 Node *Ty;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000482 StringView Protocol;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000483
484 friend class PointerType;
485
486public:
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000487 ObjCProtoName(Node *Ty_, StringView Protocol_)
Erik Pilkington414f1a52017-08-09 22:45:35 +0000488 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000489
490 bool isObjCObject() const {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000491 return Ty->getKind() == KNameType &&
Erik Pilkington0024acd2017-07-28 00:43:49 +0000492 static_cast<NameType *>(Ty)->getName() == "objc_object";
493 }
494
495 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000496 Ty->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000497 S += "<";
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000498 S += Protocol;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000499 S += ">";
500 }
501};
502
503class PointerType final : public Node {
504 const Node *Pointee;
505
506public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000507 PointerType(Node *Pointee_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000508 : Node(KPointerType, Pointee_->ParameterPackSize,
509 Pointee_->RHSComponentCache),
510 Pointee(Pointee_) {}
511
512 bool hasRHSComponentSlow(OutputStream &S) const override {
513 return Pointee->hasRHSComponent(S);
514 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000515
516 void printLeft(OutputStream &s) const override {
517 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
Erik Pilkington761e6b02018-01-31 20:17:06 +0000518 if (Pointee->getKind() != KObjCProtoName ||
Erik Pilkington0024acd2017-07-28 00:43:49 +0000519 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
520 Pointee->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000521 if (Pointee->hasArray(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000522 s += " ";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000523 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000524 s += "(";
525 s += "*";
526 } else {
527 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
528 s += "id<";
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000529 s += objcProto->Protocol;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000530 s += ">";
531 }
532 }
533
534 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000535 if (Pointee->getKind() != KObjCProtoName ||
Erik Pilkington0024acd2017-07-28 00:43:49 +0000536 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000537 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000538 s += ")";
539 Pointee->printRight(s);
540 }
541 }
542};
543
544class LValueReferenceType final : public Node {
545 const Node *Pointee;
546
547public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000548 LValueReferenceType(Node *Pointee_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000549 : Node(KLValueReferenceType, Pointee_->ParameterPackSize,
550 Pointee_->RHSComponentCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000551 Pointee(Pointee_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000552
Erik Pilkington761e6b02018-01-31 20:17:06 +0000553 bool hasRHSComponentSlow(OutputStream &S) const override {
554 return Pointee->hasRHSComponent(S);
555 }
556
Erik Pilkington0024acd2017-07-28 00:43:49 +0000557 void printLeft(OutputStream &s) const override {
558 Pointee->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000559 if (Pointee->hasArray(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000560 s += " ";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000561 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000562 s += "(&";
563 else
564 s += "&";
565 }
566 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000567 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000568 s += ")";
569 Pointee->printRight(s);
570 }
571};
572
573class RValueReferenceType final : public Node {
574 const Node *Pointee;
575
576public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000577 RValueReferenceType(Node *Pointee_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000578 : Node(KRValueReferenceType, Pointee_->ParameterPackSize,
579 Pointee_->RHSComponentCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000580 Pointee(Pointee_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000581
Erik Pilkington761e6b02018-01-31 20:17:06 +0000582 bool hasRHSComponentSlow(OutputStream &S) const override {
583 return Pointee->hasRHSComponent(S);
584 }
585
Erik Pilkington0024acd2017-07-28 00:43:49 +0000586 void printLeft(OutputStream &s) const override {
587 Pointee->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000588 if (Pointee->hasArray(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000589 s += " ";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000590 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000591 s += "(&&";
592 else
593 s += "&&";
594 }
595
596 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000597 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000598 s += ")";
599 Pointee->printRight(s);
600 }
601};
602
603class PointerToMemberType final : public Node {
604 const Node *ClassType;
605 const Node *MemberType;
606
607public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000608 PointerToMemberType(Node *ClassType_, Node *MemberType_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000609 : Node(KPointerToMemberType,
610 std::min(MemberType_->ParameterPackSize,
611 ClassType_->ParameterPackSize),
612 MemberType_->RHSComponentCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000613 ClassType(ClassType_), MemberType(MemberType_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000614
Erik Pilkington761e6b02018-01-31 20:17:06 +0000615 bool hasRHSComponentSlow(OutputStream &S) const override {
616 return MemberType->hasRHSComponent(S);
617 }
618
Erik Pilkington0024acd2017-07-28 00:43:49 +0000619 void printLeft(OutputStream &s) const override {
620 MemberType->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000621 if (MemberType->hasArray(s) || MemberType->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000622 s += "(";
623 else
624 s += " ";
625 ClassType->print(s);
626 s += "::*";
627 }
628
629 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000630 if (MemberType->hasArray(s) || MemberType->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000631 s += ")";
632 MemberType->printRight(s);
633 }
634};
635
636class NodeOrString {
637 const void *First;
638 const void *Second;
639
640public:
641 /* implicit */ NodeOrString(StringView Str) {
642 const char *FirstChar = Str.begin();
643 const char *SecondChar = Str.end();
644 if (SecondChar == nullptr) {
645 assert(FirstChar == SecondChar);
646 ++FirstChar, ++SecondChar;
647 }
648 First = static_cast<const void *>(FirstChar);
649 Second = static_cast<const void *>(SecondChar);
650 }
651
652 /* implicit */ NodeOrString(Node *N)
653 : First(static_cast<const void *>(N)), Second(nullptr) {}
654 NodeOrString() : First(nullptr), Second(nullptr) {}
655
656 bool isString() const { return Second && First; }
657 bool isNode() const { return First && !Second; }
658 bool isEmpty() const { return !First && !Second; }
659
660 StringView asString() const {
661 assert(isString());
662 return StringView(static_cast<const char *>(First),
663 static_cast<const char *>(Second));
664 }
665
666 const Node *asNode() const {
667 assert(isNode());
668 return static_cast<const Node *>(First);
669 }
670};
671
672class ArrayType final : public Node {
673 Node *Base;
674 NodeOrString Dimension;
675
676public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000677 ArrayType(Node *Base_, NodeOrString Dimension_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000678 : Node(KArrayType, Base_->ParameterPackSize,
679 /*RHSComponentCache=*/Cache::Yes,
680 /*ArrayCache=*/Cache::Yes),
681 Base(Base_), Dimension(Dimension_) {
682 if (Dimension.isNode())
683 ParameterPackSize =
684 std::min(ParameterPackSize, Dimension.asNode()->ParameterPackSize);
685 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000686
687 // Incomplete array type.
Erik Pilkington761e6b02018-01-31 20:17:06 +0000688 ArrayType(Node *Base_)
689 : Node(KArrayType, Base_->ParameterPackSize,
690 /*RHSComponentCache=*/Cache::Yes,
691 /*ArrayCache=*/Cache::Yes),
692 Base(Base_) {}
693
694 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
695 bool hasArraySlow(OutputStream &) const override { return true; }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000696
697 void printLeft(OutputStream &S) const override { Base->printLeft(S); }
698
699 void printRight(OutputStream &S) const override {
700 if (S.back() != ']')
701 S += " ";
702 S += "[";
703 if (Dimension.isString())
704 S += Dimension.asString();
705 else if (Dimension.isNode())
706 Dimension.asNode()->print(S);
707 S += "]";
708 Base->printRight(S);
709 }
710};
711
712class FunctionType final : public Node {
713 Node *Ret;
714 NodeArray Params;
715
716public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000717 FunctionType(Node *Ret_, NodeArray Params_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000718 : Node(KFunctionType, Ret_->ParameterPackSize,
719 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
720 /*FunctionCache=*/Cache::Yes),
721 Ret(Ret_), Params(Params_) {
722 for (Node *P : Params)
723 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
724 }
725
726 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
727 bool hasFunctionSlow(OutputStream &) const override { return true; }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000728
729 // Handle C++'s ... quirky decl grammer by using the left & right
730 // distinction. Consider:
731 // int (*f(float))(char) {}
732 // f is a function that takes a float and returns a pointer to a function
733 // that takes a char and returns an int. If we're trying to print f, start
734 // by printing out the return types's left, then print our parameters, then
735 // finally print right of the return type.
736 void printLeft(OutputStream &S) const override {
737 Ret->printLeft(S);
738 S += " ";
739 }
740
741 void printRight(OutputStream &S) const override {
742 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000743 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000744 S += ")";
745 Ret->printRight(S);
746 }
747};
748
Erik Pilkington761e6b02018-01-31 20:17:06 +0000749class FunctionEncoding final : public Node {
Erik Pilkington0024acd2017-07-28 00:43:49 +0000750 const Node *Ret;
751 const Node *Name;
752 NodeArray Params;
753
754public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000755 FunctionEncoding(Node *Ret_, Node *Name_, NodeArray Params_)
756 : Node(KFunctionEncoding, NoParameterPack,
757 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
758 /*FunctionCache=*/Cache::Yes),
759 Ret(Ret_), Name(Name_), Params(Params_) {
760 for (Node *P : Params)
761 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
762 if (Ret)
763 ParameterPackSize = std::min(ParameterPackSize, Ret->ParameterPackSize);
764 }
765
766 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
767 bool hasFunctionSlow(OutputStream &) const override { return true; }
768
769 Node *getName() { return const_cast<Node *>(Name); }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000770
771 void printLeft(OutputStream &S) const override {
772 if (Ret) {
773 Ret->printLeft(S);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000774 if (!Ret->hasRHSComponent(S))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000775 S += " ";
776 }
777 Name->print(S);
778 }
779
780 void printRight(OutputStream &S) const override {
781 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000782 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000783 S += ")";
784 if (Ret)
785 Ret->printRight(S);
786 }
787};
788
789enum FunctionRefQual : unsigned char {
790 FrefQualNone,
791 FrefQualLValue,
792 FrefQualRValue,
793};
794
795class FunctionRefQualType : public Node {
796 Node *Fn;
797 FunctionRefQual Quals;
798
799 friend class FunctionQualType;
800
801public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000802 FunctionRefQualType(Node *Fn_, FunctionRefQual Quals_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000803 : Node(KFunctionRefQualType, Fn_->ParameterPackSize,
804 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
805 /*FunctionCache=*/Cache::Yes),
806 Fn(Fn_), Quals(Quals_) {}
807
808 bool hasFunctionSlow(OutputStream &) const override { return true; }
809 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000810
811 void printQuals(OutputStream &S) const {
812 if (Quals == FrefQualLValue)
813 S += " &";
814 else
815 S += " &&";
816 }
817
818 void printLeft(OutputStream &S) const override { Fn->printLeft(S); }
819
820 void printRight(OutputStream &S) const override {
821 Fn->printRight(S);
822 printQuals(S);
823 }
824};
825
826class FunctionQualType final : public QualType {
827public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000828 FunctionQualType(Node *Child_, Qualifiers Quals_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000829 : QualType(Child_, Quals_) {
830 K = KFunctionQualType;
831 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000832
833 void printLeft(OutputStream &S) const override { Child->printLeft(S); }
834
835 void printRight(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000836 if (Child->getKind() == KFunctionRefQualType) {
Erik Pilkington0024acd2017-07-28 00:43:49 +0000837 auto *RefQuals = static_cast<const FunctionRefQualType *>(Child);
838 RefQuals->Fn->printRight(S);
839 printQuals(S);
840 RefQuals->printQuals(S);
841 } else {
842 Child->printRight(S);
843 printQuals(S);
844 }
845 }
846};
847
848class LiteralOperator : public Node {
849 const Node *OpName;
850
851public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000852 LiteralOperator(Node *OpName_)
853 : Node(KLiteralOperator, OpName_->ParameterPackSize), OpName(OpName_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000854
855 void printLeft(OutputStream &S) const override {
856 S += "operator\"\" ";
857 OpName->print(S);
858 }
859};
860
861class SpecialName final : public Node {
862 const StringView Special;
863 const Node *Child;
864
865public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000866 SpecialName(StringView Special_, Node* Child_)
867 : Node(KSpecialName, Child_->ParameterPackSize), Special(Special_),
868 Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000869
870 void printLeft(OutputStream &S) const override {
871 S += Special;
872 Child->print(S);
873 }
874};
875
876class CtorVtableSpecialName final : public Node {
877 const Node *FirstType;
878 const Node *SecondType;
879
880public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000881 CtorVtableSpecialName(Node *FirstType_, Node *SecondType_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000882 : Node(KCtorVtableSpecialName, std::min(FirstType_->ParameterPackSize,
883 SecondType_->ParameterPackSize)),
884 FirstType(FirstType_), SecondType(SecondType_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000885
886 void printLeft(OutputStream &S) const override {
887 S += "construction vtable for ";
888 FirstType->print(S);
889 S += "-in-";
890 SecondType->print(S);
891 }
892};
893
894class QualifiedName final : public Node {
895 // qualifier::name
896 const Node *Qualifier;
897 const Node *Name;
898
Erik Pilkington0024acd2017-07-28 00:43:49 +0000899public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000900 QualifiedName(Node* Qualifier_, Node* Name_)
901 : Node(KQualifiedName,
902 std::min(Qualifier_->ParameterPackSize, Name_->ParameterPackSize)),
903 Qualifier(Qualifier_), Name(Name_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000904
905 StringView getBaseName() const override { return Name->getBaseName(); }
906
907 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000908 Qualifier->print(S);
909 S += "::";
Erik Pilkington0024acd2017-07-28 00:43:49 +0000910 Name->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000911 }
912};
913
914class EmptyName : public Node {
915public:
916 EmptyName() : Node(KEmptyName) {}
917 void printLeft(OutputStream &) const override {}
918};
919
920class VectorType final : public Node {
921 const Node *BaseType;
922 const NodeOrString Dimension;
923 const bool IsPixel;
924
925public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000926 VectorType(NodeOrString Dimension_)
927 : Node(KVectorType), BaseType(nullptr), Dimension(Dimension_),
Erik Pilkington761e6b02018-01-31 20:17:06 +0000928 IsPixel(true) {
929 if (Dimension.isNode())
930 ParameterPackSize = Dimension.asNode()->ParameterPackSize;
931 }
Erik Pilkington414f1a52017-08-09 22:45:35 +0000932 VectorType(Node *BaseType_, NodeOrString Dimension_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000933 : Node(KVectorType, BaseType_->ParameterPackSize), BaseType(BaseType_),
934 Dimension(Dimension_), IsPixel(false) {
935 if (Dimension.isNode())
936 ParameterPackSize =
937 std::min(ParameterPackSize, Dimension.asNode()->ParameterPackSize);
938 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000939
940 void printLeft(OutputStream &S) const override {
941 if (IsPixel) {
942 S += "pixel vector[";
943 S += Dimension.asString();
944 S += "]";
945 } else {
946 BaseType->print(S);
947 S += " vector[";
948 if (Dimension.isNode())
949 Dimension.asNode()->print(S);
950 else if (Dimension.isString())
951 S += Dimension.asString();
952 S += "]";
953 }
954 }
955};
956
Erik Pilkington761e6b02018-01-31 20:17:06 +0000957/// An unexpanded parameter pack (either in the expression or type context). If
958/// this AST is correct, this node will have a ParameterPackExpansion node above
959/// it.
960///
961/// This node is created when some <template-args> are found that apply to an
962/// <encoding>, and is stored in the TemplateParams table. In order for this to
963/// appear in the final AST, it has to referenced via a <template-param> (ie,
964/// T_).
965class ParameterPack final : public Node {
966 NodeArray Data;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000967public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000968 ParameterPack(NodeArray Data_)
969 : Node(KParameterPack, static_cast<unsigned>(Data_.size())), Data(Data_) {
970 ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
971 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
972 return P->ArrayCache == Cache::No;
973 }))
974 ArrayCache = Cache::No;
975 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
976 return P->FunctionCache == Cache::No;
977 }))
978 FunctionCache = Cache::No;
979 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
980 return P->RHSComponentCache == Cache::No;
981 }))
982 RHSComponentCache = Cache::No;
983 }
984
985 bool hasRHSComponentSlow(OutputStream &S) const override {
986 size_t Idx = S.CurrentPackIndex;
987 return Idx < Data.size() && Data[Idx]->hasRHSComponent(S);
988 }
989 bool hasArraySlow(OutputStream &S) const override {
990 size_t Idx = S.CurrentPackIndex;
991 return Idx < Data.size() && Data[Idx]->hasArray(S);
992 }
993 bool hasFunctionSlow(OutputStream &S) const override {
994 size_t Idx = S.CurrentPackIndex;
995 return Idx < Data.size() && Data[Idx]->hasFunction(S);
996 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000997
998 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000999 size_t Idx = S.CurrentPackIndex;
1000 if (Idx < Data.size())
1001 Data[Idx]->printLeft(S);
1002 }
1003 void printRight(OutputStream &S) const override {
1004 size_t Idx = S.CurrentPackIndex;
1005 if (Idx < Data.size())
1006 Data[Idx]->printRight(S);
1007 }
1008};
1009
1010/// A variadic template argument. This node represents an occurance of
1011/// J<something>E in some <template-args>. It isn't itself unexpanded, unless
1012/// one of it's Elements is. The parser inserts a ParameterPack into the
1013/// TemplateParams table if the <template-args> this pack belongs to apply to an
1014/// <encoding>.
1015class TemplateArgumentPack final : public Node {
1016 NodeArray Elements;
1017public:
1018 TemplateArgumentPack(NodeArray Elements_)
1019 : Node(KTemplateArgumentPack), Elements(Elements_) {
1020 for (Node *E : Elements)
1021 ParameterPackSize = std::min(E->ParameterPackSize, ParameterPackSize);
1022 }
1023
1024 NodeArray getElements() const { return Elements; }
1025
1026 void printLeft(OutputStream &S) const override {
1027 Elements.printWithComma(S);
1028 }
1029};
1030
1031/// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1032/// which each have Child->ParameterPackSize elements.
1033class ParameterPackExpansion final : public Node {
1034 const Node *Child;
1035
1036public:
1037 ParameterPackExpansion(Node* Child_)
1038 : Node(KParameterPackExpansion), Child(Child_) {}
1039
1040 const Node *getChild() const { return Child; }
1041
1042 void printLeft(OutputStream &S) const override {
1043 unsigned PackSize = Child->ParameterPackSize;
1044 if (PackSize == NoParameterPack) {
1045 Child->print(S);
1046 S += "...";
Erik Pilkington0024acd2017-07-28 00:43:49 +00001047 return;
1048 }
1049
Erik Pilkington761e6b02018-01-31 20:17:06 +00001050 SwapAndRestore<unsigned> SavePackIndex(S.CurrentPackIndex, 0);
1051 for (unsigned I = 0; I != PackSize; ++I) {
1052 if (I != 0)
1053 S += ", ";
1054 S.CurrentPackIndex = I;
1055 Child->print(S);
1056 }
1057 }
1058};
Erik Pilkington0024acd2017-07-28 00:43:49 +00001059
Erik Pilkington761e6b02018-01-31 20:17:06 +00001060inline bool Node::isEmptyPackExpansion() const {
1061 if (getKind() == KParameterPackExpansion) {
1062 auto *AsPack = static_cast<const ParameterPackExpansion *>(this);
1063 return AsPack->getChild()->isEmptyPackExpansion();
1064 }
1065 if (getKind() == KTemplateArgumentPack) {
1066 auto *AsTemplateArg = static_cast<const TemplateArgumentPack *>(this);
1067 for (Node *E : AsTemplateArg->getElements())
1068 if (!E->isEmptyPackExpansion())
1069 return false;
1070 return true;
1071 }
1072 return ParameterPackSize == 0;
1073}
1074
1075class TemplateArgs final : public Node {
1076 NodeArray Params;
1077
1078public:
1079 TemplateArgs(NodeArray Params_) : Node(KTemplateArgs), Params(Params_) {
1080 for (Node *P : Params)
1081 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
1082 }
1083
1084 NodeArray getParams() { return Params; }
1085
1086 void printLeft(OutputStream &S) const override {
Erik Pilkington0024acd2017-07-28 00:43:49 +00001087 S += "<";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001088 bool FirstElement = true;
1089 for (size_t Idx = 0, E = Params.size(); Idx != E; ++Idx) {
1090 if (Params[Idx]->isEmptyPackExpansion())
1091 continue;
1092 if (!FirstElement)
1093 S += ", ";
1094 FirstElement = false;
1095 Params[Idx]->print(S);
1096 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001097 if (S.back() == '>')
1098 S += " ";
1099 S += ">";
Erik Pilkington0024acd2017-07-28 00:43:49 +00001100 }
1101};
1102
1103class NameWithTemplateArgs final : public Node {
1104 // name<template_args>
1105 Node *Name;
1106 Node *TemplateArgs;
1107
1108public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001109 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001110 : Node(KNameWithTemplateArgs, std::min(Name_->ParameterPackSize,
1111 TemplateArgs_->ParameterPackSize)),
1112 Name(Name_), TemplateArgs(TemplateArgs_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001113
1114 StringView getBaseName() const override { return Name->getBaseName(); }
1115
1116 void printLeft(OutputStream &S) const override {
1117 Name->print(S);
1118 TemplateArgs->print(S);
1119 }
1120};
1121
1122class GlobalQualifiedName final : public Node {
1123 Node *Child;
1124
1125public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001126 GlobalQualifiedName(Node* Child_)
1127 : Node(KGlobalQualifiedName, Child_->ParameterPackSize), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001128
1129 StringView getBaseName() const override { return Child->getBaseName(); }
1130
1131 void printLeft(OutputStream &S) const override {
1132 S += "::";
1133 Child->print(S);
1134 }
1135};
1136
1137class StdQualifiedName final : public Node {
1138 Node *Child;
1139
1140public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001141 StdQualifiedName(Node *Child_)
1142 : Node(KStdQualifiedName, Child_->ParameterPackSize), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001143
1144 StringView getBaseName() const override { return Child->getBaseName(); }
1145
1146 void printLeft(OutputStream &S) const override {
1147 S += "std::";
1148 Child->print(S);
1149 }
1150};
1151
1152enum class SpecialSubKind {
1153 allocator,
1154 basic_string,
1155 string,
1156 istream,
1157 ostream,
1158 iostream,
1159};
1160
1161class ExpandedSpecialSubstitution final : public Node {
1162 SpecialSubKind SSK;
1163
1164public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001165 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1166 : Node(KExpandedSpecialSubstitution), SSK(SSK_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001167
1168 StringView getBaseName() const override {
1169 switch (SSK) {
1170 case SpecialSubKind::allocator:
1171 return StringView("allocator");
1172 case SpecialSubKind::basic_string:
1173 return StringView("basic_string");
1174 case SpecialSubKind::string:
1175 return StringView("basic_string");
1176 case SpecialSubKind::istream:
1177 return StringView("basic_istream");
1178 case SpecialSubKind::ostream:
1179 return StringView("basic_ostream");
1180 case SpecialSubKind::iostream:
1181 return StringView("basic_iostream");
1182 }
Erik Pilkingtond25d9012017-08-01 02:38:40 +00001183 _LIBCPP_UNREACHABLE();
Erik Pilkington0024acd2017-07-28 00:43:49 +00001184 }
1185
1186 void printLeft(OutputStream &S) const override {
1187 switch (SSK) {
1188 case SpecialSubKind::allocator:
1189 S += "std::basic_string<char, std::char_traits<char>, "
1190 "std::allocator<char> >";
1191 break;
1192 case SpecialSubKind::basic_string:
1193 case SpecialSubKind::string:
1194 S += "std::basic_string<char, std::char_traits<char>, "
1195 "std::allocator<char> >";
1196 break;
1197 case SpecialSubKind::istream:
1198 S += "std::basic_istream<char, std::char_traits<char> >";
1199 break;
1200 case SpecialSubKind::ostream:
1201 S += "std::basic_ostream<char, std::char_traits<char> >";
1202 break;
1203 case SpecialSubKind::iostream:
1204 S += "std::basic_iostream<char, std::char_traits<char> >";
1205 break;
1206 }
1207 }
1208};
1209
1210class SpecialSubstitution final : public Node {
1211public:
1212 SpecialSubKind SSK;
1213
Erik Pilkington414f1a52017-08-09 22:45:35 +00001214 SpecialSubstitution(SpecialSubKind SSK_)
1215 : Node(KSpecialSubstitution), SSK(SSK_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001216
1217 StringView getBaseName() const override {
1218 switch (SSK) {
1219 case SpecialSubKind::allocator:
1220 return StringView("allocator");
1221 case SpecialSubKind::basic_string:
1222 return StringView("basic_string");
1223 case SpecialSubKind::string:
1224 return StringView("string");
1225 case SpecialSubKind::istream:
1226 return StringView("istream");
1227 case SpecialSubKind::ostream:
1228 return StringView("ostream");
1229 case SpecialSubKind::iostream:
1230 return StringView("iostream");
1231 }
Erik Pilkingtond25d9012017-08-01 02:38:40 +00001232 _LIBCPP_UNREACHABLE();
Erik Pilkington0024acd2017-07-28 00:43:49 +00001233 }
1234
1235 void printLeft(OutputStream &S) const override {
1236 switch (SSK) {
1237 case SpecialSubKind::allocator:
1238 S += "std::allocator";
1239 break;
1240 case SpecialSubKind::basic_string:
1241 S += "std::basic_string";
1242 break;
1243 case SpecialSubKind::string:
1244 S += "std::string";
1245 break;
1246 case SpecialSubKind::istream:
1247 S += "std::istream";
1248 break;
1249 case SpecialSubKind::ostream:
1250 S += "std::ostream";
1251 break;
1252 case SpecialSubKind::iostream:
1253 S += "std::iostream";
1254 break;
1255 }
1256 }
1257};
1258
1259class CtorDtorName final : public Node {
1260 const Node *Basename;
1261 const bool IsDtor;
1262
1263public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001264 CtorDtorName(Node *Basename_, bool IsDtor_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001265 : Node(KCtorDtorName, Basename_->ParameterPackSize),
1266 Basename(Basename_), IsDtor(IsDtor_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001267
1268 void printLeft(OutputStream &S) const override {
1269 if (IsDtor)
1270 S += "~";
1271 S += Basename->getBaseName();
1272 }
1273};
1274
1275class DtorName : public Node {
1276 const Node *Base;
1277
1278public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001279 DtorName(Node *Base_) : Node(KDtorName), Base(Base_) {
1280 ParameterPackSize = Base->ParameterPackSize;
1281 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001282
1283 void printLeft(OutputStream &S) const override {
1284 S += "~";
1285 Base->printLeft(S);
1286 }
1287};
1288
1289class UnnamedTypeName : public Node {
1290 const StringView Count;
1291
1292public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001293 UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001294
1295 void printLeft(OutputStream &S) const override {
1296 S += "'unnamed";
1297 S += Count;
1298 S += "\'";
1299 }
1300};
1301
1302class LambdaTypeName : public Node {
1303 NodeArray Params;
1304 StringView Count;
1305
1306public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001307 LambdaTypeName(NodeArray Params_, StringView Count_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001308 : Node(KLambdaTypeName), Params(Params_), Count(Count_) {
1309 for (Node *P : Params)
1310 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
1311 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001312
1313 void printLeft(OutputStream &S) const override {
1314 S += "\'lambda";
1315 S += Count;
1316 S += "\'(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001317 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001318 S += ")";
1319 }
1320};
1321
1322// -- Expression Nodes --
1323
1324struct Expr : public Node {
1325 Expr() : Node(KExpr) {}
1326};
1327
1328class BinaryExpr : public Expr {
1329 const Node *LHS;
1330 const StringView InfixOperator;
1331 const Node *RHS;
1332
1333public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001334 BinaryExpr(Node *LHS_, StringView InfixOperator_, Node *RHS_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001335 : LHS(LHS_), InfixOperator(InfixOperator_), RHS(RHS_) {
1336 ParameterPackSize =
1337 std::min(LHS->ParameterPackSize, RHS->ParameterPackSize);
1338 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001339
1340 void printLeft(OutputStream &S) const override {
1341 // might be a template argument expression, then we need to disambiguate
1342 // with parens.
1343 if (InfixOperator == ">")
1344 S += "(";
1345
1346 S += "(";
1347 LHS->print(S);
1348 S += ") ";
1349 S += InfixOperator;
1350 S += " (";
1351 RHS->print(S);
1352 S += ")";
1353
1354 if (InfixOperator == ">")
1355 S += ")";
1356 }
1357};
1358
1359class ArraySubscriptExpr : public Expr {
1360 const Node *Op1;
1361 const Node *Op2;
1362
1363public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001364 ArraySubscriptExpr(Node *Op1_, Node *Op2_) : Op1(Op1_), Op2(Op2_) {
1365 ParameterPackSize =
1366 std::min(Op1->ParameterPackSize, Op2->ParameterPackSize);
1367 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001368
1369 void printLeft(OutputStream &S) const override {
1370 S += "(";
1371 Op1->print(S);
1372 S += ")[";
1373 Op2->print(S);
1374 S += "]";
1375 }
1376};
1377
1378class PostfixExpr : public Expr {
1379 const Node *Child;
1380 const StringView Operand;
1381
1382public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001383 PostfixExpr(Node *Child_, StringView Operand_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001384 : Child(Child_), Operand(Operand_) {
1385 ParameterPackSize = Child->ParameterPackSize;
1386 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001387
1388 void printLeft(OutputStream &S) const override {
1389 S += "(";
1390 Child->print(S);
1391 S += ")";
1392 S += Operand;
1393 }
1394};
1395
1396class ConditionalExpr : public Expr {
1397 const Node *Cond;
1398 const Node *Then;
1399 const Node *Else;
1400
1401public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001402 ConditionalExpr(Node *Cond_, Node *Then_, Node *Else_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001403 : Cond(Cond_), Then(Then_), Else(Else_) {
1404 ParameterPackSize =
1405 std::min(Cond->ParameterPackSize,
1406 std::min(Then->ParameterPackSize, Else->ParameterPackSize));
1407 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001408
1409 void printLeft(OutputStream &S) const override {
1410 S += "(";
1411 Cond->print(S);
1412 S += ") ? (";
1413 Then->print(S);
1414 S += ") : (";
1415 Else->print(S);
1416 S += ")";
1417 }
1418};
1419
1420class MemberExpr : public Expr {
1421 const Node *LHS;
1422 const StringView Kind;
1423 const Node *RHS;
1424
1425public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001426 MemberExpr(Node *LHS_, StringView Kind_, Node *RHS_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001427 : LHS(LHS_), Kind(Kind_), RHS(RHS_) {
1428 ParameterPackSize =
1429 std::min(LHS->ParameterPackSize, RHS->ParameterPackSize);
1430 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001431
1432 void printLeft(OutputStream &S) const override {
1433 LHS->print(S);
1434 S += Kind;
1435 RHS->print(S);
1436 }
1437};
1438
1439class EnclosingExpr : public Expr {
1440 const StringView Prefix;
1441 const Node *Infix;
1442 const StringView Postfix;
1443
1444public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001445 EnclosingExpr(StringView Prefix_, Node *Infix_, StringView Postfix_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001446 : Prefix(Prefix_), Infix(Infix_), Postfix(Postfix_) {
1447 ParameterPackSize = Infix->ParameterPackSize;
1448 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001449
1450 void printLeft(OutputStream &S) const override {
1451 S += Prefix;
1452 Infix->print(S);
1453 S += Postfix;
1454 }
1455};
1456
1457class CastExpr : public Expr {
1458 // cast_kind<to>(from)
1459 const StringView CastKind;
1460 const Node *To;
1461 const Node *From;
1462
1463public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001464 CastExpr(StringView CastKind_, Node *To_, Node *From_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001465 : CastKind(CastKind_), To(To_), From(From_) {
1466 ParameterPackSize =
1467 std::min(To->ParameterPackSize, From->ParameterPackSize);
1468 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001469
1470 void printLeft(OutputStream &S) const override {
1471 S += CastKind;
1472 S += "<";
1473 To->printLeft(S);
1474 S += ">(";
1475 From->printLeft(S);
1476 S += ")";
1477 }
1478};
1479
1480class SizeofParamPackExpr : public Expr {
Erik Pilkington761e6b02018-01-31 20:17:06 +00001481 Node *Pack;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001482
1483public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001484 SizeofParamPackExpr(Node *Pack_) : Pack(Pack_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001485
1486 void printLeft(OutputStream &S) const override {
1487 S += "sizeof...(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001488 ParameterPackExpansion PPE(Pack);
1489 PPE.printLeft(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001490 S += ")";
1491 }
1492};
1493
1494class CallExpr : public Expr {
1495 const Node *Callee;
1496 NodeArray Args;
1497
1498public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001499 CallExpr(Node *Callee_, NodeArray Args_) : Callee(Callee_), Args(Args_) {
1500 for (Node *P : Args)
1501 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
1502 ParameterPackSize = std::min(ParameterPackSize, Callee->ParameterPackSize);
1503 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001504
1505 void printLeft(OutputStream &S) const override {
1506 Callee->print(S);
1507 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001508 Args.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001509 S += ")";
1510 }
1511};
1512
1513class NewExpr : public Expr {
1514 // new (expr_list) type(init_list)
1515 NodeArray ExprList;
1516 Node *Type;
1517 NodeArray InitList;
1518 bool IsGlobal; // ::operator new ?
1519 bool IsArray; // new[] ?
1520public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001521 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
1522 bool IsArray_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001523 : ExprList(ExprList_), Type(Type_), InitList(InitList_),
1524 IsGlobal(IsGlobal_), IsArray(IsArray_) {
1525 for (Node *E : ExprList)
1526 ParameterPackSize = std::min(ParameterPackSize, E->ParameterPackSize);
1527 for (Node *I : InitList)
1528 ParameterPackSize = std::min(ParameterPackSize, I->ParameterPackSize);
1529 if (Type)
1530 ParameterPackSize = std::min(ParameterPackSize, Type->ParameterPackSize);
1531 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001532
1533 void printLeft(OutputStream &S) const override {
1534 if (IsGlobal)
1535 S += "::operator ";
1536 S += "new";
1537 if (IsArray)
1538 S += "[]";
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001539 S += ' ';
Erik Pilkington0024acd2017-07-28 00:43:49 +00001540 if (!ExprList.empty()) {
1541 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001542 ExprList.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001543 S += ")";
1544 }
1545 Type->print(S);
1546 if (!InitList.empty()) {
1547 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001548 InitList.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001549 S += ")";
1550 }
Erik Pilkington761e6b02018-01-31 20:17:06 +00001551
Erik Pilkington0024acd2017-07-28 00:43:49 +00001552 }
1553};
1554
1555class DeleteExpr : public Expr {
1556 Node *Op;
1557 bool IsGlobal;
1558 bool IsArray;
1559
1560public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001561 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001562 : Op(Op_), IsGlobal(IsGlobal_), IsArray(IsArray_) {
1563 ParameterPackSize = Op->ParameterPackSize;
1564 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001565
1566 void printLeft(OutputStream &S) const override {
1567 if (IsGlobal)
1568 S += "::";
1569 S += "delete";
1570 if (IsArray)
1571 S += "[] ";
1572 Op->print(S);
1573 }
1574};
1575
1576class PrefixExpr : public Expr {
1577 StringView Prefix;
1578 Node *Child;
1579
1580public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001581 PrefixExpr(StringView Prefix_, Node *Child_) : Prefix(Prefix_), Child(Child_) {
1582 ParameterPackSize = Child->ParameterPackSize;
1583 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001584
1585 void printLeft(OutputStream &S) const override {
1586 S += Prefix;
1587 S += "(";
1588 Child->print(S);
1589 S += ")";
1590 }
1591};
1592
1593class FunctionParam : public Expr {
1594 StringView Number;
1595
1596public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001597 FunctionParam(StringView Number_) : Number(Number_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001598
1599 void printLeft(OutputStream &S) const override {
1600 S += "fp";
1601 S += Number;
1602 }
1603};
1604
Erik Pilkington0024acd2017-07-28 00:43:49 +00001605class ConversionExpr : public Expr {
Erik Pilkington761e6b02018-01-31 20:17:06 +00001606 const Node *Type;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001607 NodeArray Expressions;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001608
1609public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001610 ConversionExpr(const Node *Type_, NodeArray Expressions_)
1611 : Type(Type_), Expressions(Expressions_) {
1612 for (Node *E : Expressions)
1613 ParameterPackSize = std::min(ParameterPackSize, E->ParameterPackSize);
1614 ParameterPackSize = std::min(ParameterPackSize, Type->ParameterPackSize);
1615 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001616
1617 void printLeft(OutputStream &S) const override {
1618 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001619 Type->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001620 S += ")(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001621 Expressions.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001622 S += ")";
1623 }
1624};
1625
1626class ThrowExpr : public Expr {
1627 const Node *Op;
1628
1629public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001630 ThrowExpr(Node *Op_) : Op(Op_) {
1631 ParameterPackSize = Op->ParameterPackSize;
1632 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001633
1634 void printLeft(OutputStream &S) const override {
1635 S += "throw ";
1636 Op->print(S);
1637 }
1638};
1639
1640class BoolExpr : public Expr {
1641 bool Value;
1642
1643public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001644 BoolExpr(bool Value_) : Value(Value_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001645
1646 void printLeft(OutputStream &S) const override {
1647 S += Value ? StringView("true") : StringView("false");
1648 }
1649};
1650
1651class IntegerCastExpr : public Expr {
1652 // ty(integer)
1653 Node *Ty;
1654 StringView Integer;
1655
1656public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001657 IntegerCastExpr(Node *Ty_, StringView Integer_) : Ty(Ty_), Integer(Integer_) {
1658 ParameterPackSize = Ty->ParameterPackSize;
1659 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001660
1661 void printLeft(OutputStream &S) const override {
1662 S += "(";
1663 Ty->print(S);
1664 S += ")";
1665 S += Integer;
1666 }
1667};
1668
1669class IntegerExpr : public Expr {
1670 StringView Type;
1671 StringView Value;
1672
1673public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001674 IntegerExpr(StringView Type_, StringView Value_) : Type(Type_), Value(Value_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001675
1676 void printLeft(OutputStream &S) const override {
1677 if (Type.size() > 3) {
1678 S += "(";
1679 S += Type;
1680 S += ")";
1681 }
1682
1683 if (Value[0] == 'n') {
1684 S += "-";
1685 S += Value.dropFront(1);
1686 } else
1687 S += Value;
1688
1689 if (Type.size() <= 3)
1690 S += Type;
1691 }
1692};
1693
1694template <class Float> struct FloatData;
1695
1696template <class Float> class FloatExpr : public Expr {
1697 const StringView Contents;
1698
1699public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001700 FloatExpr(StringView Contents_) : Contents(Contents_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001701
1702 void printLeft(OutputStream &s) const override {
1703 const char *first = Contents.begin();
1704 const char *last = Contents.end() + 1;
1705
1706 const size_t N = FloatData<Float>::mangled_size;
1707 if (static_cast<std::size_t>(last - first) > N) {
1708 last = first + N;
1709 union {
1710 Float value;
1711 char buf[sizeof(Float)];
1712 };
1713 const char *t = first;
1714 char *e = buf;
1715 for (; t != last; ++t, ++e) {
1716 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1717 : static_cast<unsigned>(*t - 'a' + 10);
1718 ++t;
1719 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1720 : static_cast<unsigned>(*t - 'a' + 10);
1721 *e = static_cast<char>((d1 << 4) + d0);
1722 }
1723#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1724 std::reverse(buf, e);
1725#endif
1726 char num[FloatData<Float>::max_demangled_size] = {0};
1727 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
1728 s += StringView(num, num + n);
1729 }
1730 }
1731};
1732
Erik Pilkington0024acd2017-07-28 00:43:49 +00001733class BumpPointerAllocator {
1734 struct BlockMeta {
1735 BlockMeta* Next;
1736 size_t Current;
1737 };
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001738
Erik Pilkington0024acd2017-07-28 00:43:49 +00001739 static constexpr size_t AllocSize = 4096;
1740 static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001741
Erik Pilkington0024acd2017-07-28 00:43:49 +00001742 alignas(16) char InitialBuffer[AllocSize];
1743 BlockMeta* BlockList = nullptr;
1744
1745 void grow() {
1746 char* NewMeta = new char[AllocSize];
1747 BlockList = new (NewMeta) BlockMeta{BlockList, 0};
1748 }
1749
1750 void* allocateMassive(size_t NBytes) {
1751 NBytes += sizeof(BlockMeta);
1752 BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(new char[NBytes]);
1753 BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
1754 return static_cast<void*>(NewMeta + 1);
1755 }
1756
1757public:
1758 BumpPointerAllocator()
1759 : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
1760
1761 void* allocate(size_t N) {
1762 N = (N + 15u) & ~15u;
1763 if (N + BlockList->Current >= UsableAllocSize) {
1764 if (N > UsableAllocSize)
1765 return allocateMassive(N);
1766 grow();
1767 }
1768 BlockList->Current += N;
1769 return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
1770 BlockList->Current - N);
1771 }
1772
1773 ~BumpPointerAllocator() {
1774 while (BlockList) {
1775 BlockMeta* Tmp = BlockList;
1776 BlockList = BlockList->Next;
1777 if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
1778 delete[] reinterpret_cast<char*>(Tmp);
1779 }
1780 }
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001781};
1782
Erik Pilkingtonba34a242017-08-09 21:30:57 +00001783template <class T, size_t N>
1784class PODSmallVector {
1785 static_assert(std::is_pod<T>::value,
1786 "T is required to be a plain old data type");
1787
1788 T* First;
1789 T* Last;
1790 T* Cap;
1791 T Inline[N];
1792
1793 bool isInline() const { return First == Inline; }
1794
1795 void clearInline() {
1796 First = Inline;
1797 Last = Inline;
1798 Cap = Inline + N;
1799 }
1800
1801 void reserve(size_t NewCap) {
1802 size_t S = size();
1803 if (isInline()) {
1804 auto* Tmp = static_cast<T*>(std::malloc(NewCap * sizeof(T)));
1805 std::copy(First, Last, Tmp);
1806 First = Tmp;
1807 } else
1808 First = static_cast<T*>(std::realloc(First, NewCap * sizeof(T)));
1809 Last = First + S;
1810 Cap = First + NewCap;
1811 }
1812
1813public:
1814 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
1815
1816 PODSmallVector(const PODSmallVector&) = delete;
1817 PODSmallVector& operator=(const PODSmallVector&) = delete;
1818
1819 PODSmallVector(PODSmallVector&& Other) : PODSmallVector() {
1820 if (Other.isInline()) {
1821 std::copy(Other.begin(), Other.end(), First);
1822 Last = First + Other.size();
1823 Other.clear();
1824 return;
1825 }
1826
1827 First = Other.First;
1828 Last = Other.Last;
1829 Cap = Other.Cap;
1830 Other.clearInline();
1831 }
1832
1833 PODSmallVector& operator=(PODSmallVector&& Other) {
1834 if (Other.isInline()) {
1835 if (!isInline()) {
1836 std::free(First);
1837 clearInline();
1838 }
1839 std::copy(Other.begin(), Other.end(), First);
1840 Last = First + Other.size();
1841 Other.clear();
1842 return *this;
1843 }
1844
1845 if (isInline()) {
1846 First = Other.First;
1847 Last = Other.Last;
1848 Cap = Other.Cap;
1849 Other.clearInline();
1850 return *this;
1851 }
1852
1853 std::swap(First, Other.First);
1854 std::swap(Last, Other.Last);
1855 std::swap(Cap, Other.Cap);
1856 Other.clear();
1857 return *this;
1858 }
1859
1860 void push_back(const T& Elem) {
1861 if (Last == Cap)
1862 reserve(size() * 2);
1863 *Last++ = Elem;
1864 }
1865
1866 void pop_back() {
1867 assert(Last != First && "Popping empty vector!");
1868 --Last;
1869 }
1870
1871 void dropBack(size_t Index) {
1872 assert(Index <= size() && "dropBack() can't expand!");
1873 Last = First + Index;
1874 }
1875
1876 T* begin() { return First; }
1877 T* end() { return Last; }
1878
1879 bool empty() const { return First == Last; }
1880 size_t size() const { return static_cast<size_t>(Last - First); }
1881 T& back() {
1882 assert(Last != First && "Calling back() on empty vector!");
1883 return *(Last - 1);
1884 }
1885 T& operator[](size_t Index) {
1886 assert(Index < size() && "Invalid access!");
1887 return *(begin() + Index);
1888 }
1889 void clear() { Last = First; }
1890
1891 ~PODSmallVector() {
1892 if (!isInline())
1893 std::free(First);
1894 }
1895};
1896
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001897struct Db {
1898 const char *First;
1899 const char *Last;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00001900
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001901 // Name stack, this is used by the parser to hold temporary names that were
1902 // parsed. The parser colapses multiple names into new nodes to construct
1903 // the AST. Once the parser is finished, names.size() == 1.
1904 PODSmallVector<Node *, 32> Names;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00001905
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001906 // Substitution table. Itanium supports name substitutions as a means of
1907 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
1908 // table.
1909 PODSmallVector<Node *, 32> Subs;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00001910
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001911 // Template parameter table. Like the above, but referenced like "T42_".
1912 // This has a smaller size compared to Subs and Names because it can be
1913 // stored on the stack.
1914 PODSmallVector<Node *, 8> TemplateParams;
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001915
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001916 Qualifiers CV = QualNone;
1917 FunctionRefQual RefQuals = FrefQualNone;
1918 unsigned EncodingDepth = 0;
1919 bool ParsedCtorDtorCV = false;
1920 bool TagTemplates = true;
1921 bool FixForwardReferences = false;
1922 bool TryToParseTemplateArgs = true;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001923
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001924 BumpPointerAllocator ASTAllocator;
1925
1926 template <class T, class... Args> T *make(Args &&... args) {
1927 return new (ASTAllocator.allocate(sizeof(T)))
1928 T(std::forward<Args>(args)...);
1929 }
1930
1931 template <class It> NodeArray makeNodeArray(It begin, It end) {
1932 size_t sz = static_cast<size_t>(end - begin);
1933 void *mem = ASTAllocator.allocate(sizeof(Node *) * sz);
1934 Node **data = new (mem) Node *[sz];
1935 std::copy(begin, end, data);
1936 return NodeArray(data, sz);
1937 }
1938
1939 NodeArray popTrailingNodeArray(size_t FromPosition) {
1940 assert(FromPosition <= Names.size());
1941 NodeArray res =
1942 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
1943 Names.dropBack(FromPosition);
1944 return res;
1945 }
1946
1947 bool consumeIf(StringView S) {
1948 if (StringView(First, Last).startsWith(S)) {
1949 First += S.size();
1950 return true;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001951 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001952 return false;
1953 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001954
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001955 bool consumeIf(char C) {
1956 if (First != Last && *First == C) {
1957 ++First;
1958 return true;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001959 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001960 return false;
1961 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001962
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001963 char consume() { return First != Last ? *First++ : '\0'; }
1964
1965 char look(unsigned Lookahead = 0) {
1966 if (static_cast<size_t>(Last - First) <= Lookahead)
1967 return '\0';
1968 return First[Lookahead];
1969 }
1970
1971 size_t numLeft() const { return static_cast<size_t>(Last - First); }
1972
1973 StringView parseNumber(bool AllowNegative = false);
1974 Qualifiers parseCVQualifiers();
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00001975 bool parsePositiveInteger(size_t *Out);
1976 StringView parseBareSourceName();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001977
1978 /// Parse the <expr> production.
1979 Node *parseExpr();
1980 Node *parsePrefixExpr(StringView Kind);
1981 Node *parseBinaryExpr(StringView Kind);
1982 Node *parseIntegerLiteral(StringView Lit);
1983 Node *parseExprPrimary();
1984 template <class Float> Node *parseFloatingLiteral();
1985 Node *parseFunctionParam();
1986 Node *parseNewExpr();
1987 Node *parseConversionExpr();
1988
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00001989 /// Parse the <type> production.
1990 Node *parseType();
1991 Node *parseFunctionType();
1992 Node *parseVectorType();
1993 Node *parseDecltype();
1994 Node *parseArrayType();
1995 Node *parsePointerToMemberType();
1996 Node *parseClassEnumType();
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00001997 Node *parseQualifiedType(bool &AppliesToFunction);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00001998
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001999 // FIXME: remove this when all the parse_* functions have been rewritten.
2000 template <const char *(*parse_fn)(const char *, const char *, Db &)>
2001 Node *legacyParse() {
2002 size_t BeforeType = Names.size();
2003 const char *OrigFirst = First;
2004 const char *T = parse_fn(First, Last, *this);
2005 if (T == OrigFirst || BeforeType + 1 != Names.size())
2006 return nullptr;
2007 First = T;
2008 Node *R = Names.back();
2009 Names.pop_back();
2010 return R;
2011 }
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002012 template <const char *(*parse_fn)(const char *, const char *, Db &, bool *)>
2013 Node *legacyParse() {
2014 size_t BeforeType = Names.size();
2015 const char *OrigFirst = First;
2016 const char *T = parse_fn(First, Last, *this, nullptr);
2017 if (T == OrigFirst || BeforeType + 1 != Names.size())
2018 return nullptr;
2019 First = T;
2020 Node *R = Names.back();
2021 Names.pop_back();
2022 return R;
2023 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00002024};
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002025
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002026const char *parse_expression(const char *first, const char *last, Db &db) {
2027 db.First = first;
2028 db.Last = last;
2029 Node *R = db.parseExpr();
2030 if (R == nullptr)
2031 return first;
2032 db.Names.push_back(R);
2033 return db.First;
2034}
2035
2036const char *parse_expr_primary(const char *first, const char *last, Db &db) {
2037 db.First = first;
2038 db.Last = last;
2039 Node *R = db.parseExprPrimary();
2040 if (R == nullptr)
2041 return first;
2042 db.Names.push_back(R);
2043 return db.First;
2044}
2045
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002046const char *parse_type(const char *first, const char *last, Db &db) {
2047 db.First = first;
2048 db.Last = last;
2049 Node *R = db.parseType();
2050 if (R == nullptr)
2051 return first;
2052 db.Names.push_back(R);
2053 return db.First;
2054}
2055
2056const char *parse_decltype(const char *first, const char *last, Db &db) {
2057 db.First = first;
2058 db.Last = last;
2059 Node *R = db.parseDecltype();
2060 if (R == nullptr)
2061 return first;
2062 db.Names.push_back(R);
2063 return db.First;
2064}
2065
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002066const char *parse_type(const char *first, const char *last, Db &db);
2067const char *parse_encoding(const char *first, const char *last, Db &db);
2068const char *parse_name(const char *first, const char *last, Db &db,
2069 bool *ends_with_template_args = 0);
2070const char *parse_template_args(const char *first, const char *last, Db &db);
2071const char *parse_template_param(const char *, const char *, Db &);
2072const char *parse_operator_name(const char *first, const char *last, Db &db);
2073const char *parse_unqualified_name(const char *first, const char *last, Db &db);
2074const char *parse_decltype(const char *first, const char *last, Db &db);
2075const char *parse_unresolved_name(const char *, const char *, Db &);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002076const char *parse_substitution(const char *, const char *, Db &);
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002077
2078// <number> ::= [n] <non-negative decimal integer>
2079StringView Db::parseNumber(bool AllowNegative) {
2080 const char *Tmp = First;
2081 if (AllowNegative)
2082 consumeIf('n');
2083 if (numLeft() == 0 || !std::isdigit(*First))
2084 return StringView();
2085 while (numLeft() != 0 && std::isdigit(*First))
2086 ++First;
2087 return StringView(Tmp, First);
2088}
2089
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002090// <positive length number> ::= [0-9]*
2091bool Db::parsePositiveInteger(size_t *Out) {
2092 *Out = 0;
2093 if (look() < '0' || look() > '9')
2094 return true;
2095 while (look() >= '0' && look() <= '9') {
2096 *Out *= 10;
2097 *Out += static_cast<size_t>(consume() - '0');
2098 }
2099 return false;
2100}
2101
2102StringView Db::parseBareSourceName() {
2103 size_t Int = 0;
2104 if (parsePositiveInteger(&Int) || numLeft() < Int)
2105 return StringView();
2106 StringView R(First, First + Int);
2107 First += Int;
2108 return R;
2109}
2110
2111// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
2112//
2113// <ref-qualifier> ::= R # & ref-qualifier
2114// <ref-qualifier> ::= O # && ref-qualifier
2115Node *Db::parseFunctionType() {
2116 if (!consumeIf('F'))
2117 return nullptr;
2118 consumeIf('Y'); // extern "C"
2119 Node *ReturnType = parseType();
2120 if (ReturnType == nullptr)
2121 return nullptr;
2122
2123 FunctionRefQual ReferenceQualifier = FrefQualNone;
2124 size_t ParamsBegin = Names.size();
2125 while (true) {
2126 if (consumeIf('E'))
2127 break;
2128 if (consumeIf('v'))
2129 continue;
2130 if (consumeIf("RE")) {
2131 ReferenceQualifier = FrefQualLValue;
2132 break;
2133 }
2134 if (consumeIf("OE")) {
2135 ReferenceQualifier = FrefQualRValue;
2136 break;
2137 }
2138 Node *T = parseType();
2139 if (T == nullptr)
2140 return nullptr;
2141 Names.push_back(T);
2142 }
2143
2144 NodeArray Params = popTrailingNodeArray(ParamsBegin);
2145 Node *Fn = make<FunctionType>(ReturnType, Params);
2146 if (ReferenceQualifier != FrefQualNone)
2147 Fn = make<FunctionRefQualType>(Fn, ReferenceQualifier);
2148 return Fn;
2149}
2150
2151// extension:
2152// <vector-type> ::= Dv <positive dimension number> _ <extended element type>
2153// ::= Dv [<dimension expression>] _ <element type>
2154// <extended element type> ::= <element type>
2155// ::= p # AltiVec vector pixel
2156Node *Db::parseVectorType() {
2157 if (!consumeIf("Dv"))
2158 return nullptr;
2159 if (look() >= '1' && look() <= '9') {
2160 StringView DimensionNumber = parseNumber();
2161 if (!consumeIf('_'))
2162 return nullptr;
2163 if (consumeIf('p'))
2164 return make<VectorType>(DimensionNumber);
2165 Node *ElemType = parseType();
2166 if (ElemType == nullptr)
2167 return nullptr;
2168 return make<VectorType>(ElemType, DimensionNumber);
2169 }
2170
2171 if (!consumeIf('_')) {
2172 Node *DimExpr = parseExpr();
2173 if (!DimExpr)
2174 return nullptr;
2175 if (!consumeIf('_'))
2176 return nullptr;
2177 Node *ElemType = parseType();
2178 if (!ElemType)
2179 return nullptr;
2180 return make<VectorType>(ElemType, DimExpr);
2181 }
2182 Node *ElemType = parseType();
2183 if (!ElemType)
2184 return nullptr;
2185 return make<VectorType>(ElemType, StringView());
2186}
2187
2188// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
2189// ::= DT <expression> E # decltype of an expression (C++0x)
2190Node *Db::parseDecltype() {
2191 if (!consumeIf('D'))
2192 return nullptr;
2193 if (!consumeIf('t') && !consumeIf('T'))
2194 return nullptr;
2195 Node *E = parseExpr();
2196 if (E == nullptr)
2197 return nullptr;
2198 if (!consumeIf('E'))
2199 return nullptr;
2200 return make<EnclosingExpr>("decltype(", E, ")");
2201}
2202
2203// <array-type> ::= A <positive dimension number> _ <element type>
2204// ::= A [<dimension expression>] _ <element type>
2205Node *Db::parseArrayType() {
2206 if (!consumeIf('A'))
2207 return nullptr;
2208
2209 if (std::isdigit(look())) {
2210 StringView Dimension = parseNumber();
2211 if (!consumeIf('_'))
2212 return nullptr;
2213 Node *Ty = parseType();
2214 if (Ty == nullptr)
2215 return nullptr;
2216 return make<ArrayType>(Ty, Dimension);
2217 }
2218
2219 if (!consumeIf('_')) {
2220 Node *DimExpr = parseExpr();
2221 if (DimExpr == nullptr)
2222 return nullptr;
2223 if (!consumeIf('_'))
2224 return nullptr;
2225 Node *ElementType = parseType();
2226 if (ElementType == nullptr)
2227 return nullptr;
2228 return make<ArrayType>(ElementType, DimExpr);
2229 }
2230
2231 Node *Ty = parseType();
2232 if (Ty == nullptr)
2233 return nullptr;
2234 return make<ArrayType>(Ty);
2235}
2236
2237// <pointer-to-member-type> ::= M <class type> <member type>
2238Node *Db::parsePointerToMemberType() {
2239 if (!consumeIf('M'))
2240 return nullptr;
2241 Node *ClassType = parseType();
2242 if (ClassType == nullptr)
2243 return nullptr;
2244 Node *MemberType = parseType();
2245 if (MemberType == nullptr)
2246 return nullptr;
2247 return make<PointerToMemberType>(ClassType, MemberType);
2248}
2249
2250// <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
2251// ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
2252// ::= Tu <name> # dependent elaborated type specifier using 'union'
2253// ::= Te <name> # dependent elaborated type specifier using 'enum'
2254Node *Db::parseClassEnumType() {
Erik Pilkington13fb7dc2018-02-13 00:15:53 +00002255 StringView ElabSpef;
2256 if (consumeIf("Ts"))
2257 ElabSpef = "struct";
2258 else if (consumeIf("Tu"))
2259 ElabSpef = "union";
2260 else if (consumeIf("Te"))
2261 ElabSpef = "enum";
2262
2263 Node *Name = legacyParse<parse_name>();
2264 if (Name == nullptr)
2265 return nullptr;
2266
2267 if (!ElabSpef.empty())
2268 return make<ElaboratedTypeSpefType>(ElabSpef, Name);
2269
2270 return Name;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002271}
2272
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00002273// <qualified-type> ::= <qualifiers> <type>
2274// <qualifiers> ::= <extended-qualifier>* <CV-qualifiers>
2275// <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
2276Node *Db::parseQualifiedType(bool &AppliesToFunction) {
2277 if (consumeIf('U')) {
2278 StringView Qual = parseBareSourceName();
2279 if (Qual.empty())
2280 return nullptr;
2281
2282 // FIXME parse the optional <template-args> here!
2283
2284 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
2285 if (Qual.startsWith("objcproto")) {
2286 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
2287 StringView Proto;
2288 {
2289 SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
2290 SaveLast(Last, ProtoSourceName.end());
2291 Proto = parseBareSourceName();
2292 }
2293 if (Proto.empty())
2294 return nullptr;
2295 Node *Child = parseQualifiedType(AppliesToFunction);
2296 if (Child == nullptr)
2297 return nullptr;
2298 return make<ObjCProtoName>(Child, Proto);
2299 }
2300
2301 Node *Child = parseQualifiedType(AppliesToFunction);
2302 if (Child == nullptr)
2303 return nullptr;
2304 return make<VendorExtQualType>(Child, Qual);
2305 }
2306
2307 Qualifiers Quals = parseCVQualifiers();
2308 AppliesToFunction = look() == 'F';
2309 Node *Ty = parseType();
2310 if (Ty == nullptr)
2311 return nullptr;
2312 if (Quals != QualNone) {
2313 return AppliesToFunction ?
2314 make<FunctionQualType>(Ty, Quals) : make<QualType>(Ty, Quals);
2315 }
2316 return Ty;
2317}
2318
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002319// <type> ::= <builtin-type>
2320// ::= <qualified-type>
2321// ::= <function-type>
2322// ::= <class-enum-type>
2323// ::= <array-type>
2324// ::= <pointer-to-member-type>
2325// ::= <template-param>
2326// ::= <template-template-param> <template-args>
2327// ::= <decltype>
2328// ::= P <type> # pointer
2329// ::= R <type> # l-value reference
2330// ::= O <type> # r-value reference (C++11)
2331// ::= C <type> # complex pair (C99)
2332// ::= G <type> # imaginary (C99)
2333// ::= <substitution> # See Compression below
2334// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
2335// extension ::= <vector-type> # <vector-type> starts with Dv
2336//
2337// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
2338// <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
2339Node *Db::parseType() {
2340 Node *Result = nullptr;
2341
2342 switch (look()) {
2343 // ::= <qualified-type>
2344 case 'r':
2345 case 'V':
Erik Pilkingtoncf29d3b2018-02-13 00:15:46 +00002346 case 'K':
2347 case 'U': {
2348 bool AppliesToFunction = false;
2349 Result = parseQualifiedType(AppliesToFunction);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002350
2351 // Itanium C++ ABI 5.1.5.3:
2352 // For the purposes of substitution, the CV-qualifiers and ref-qualifier
2353 // of a function type are an indivisible part of the type.
2354 if (AppliesToFunction)
2355 return Result;
2356 break;
2357 }
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002358 // <builtin-type> ::= v # void
2359 case 'v':
2360 ++First;
2361 return make<NameType>("void");
2362 // ::= w # wchar_t
2363 case 'w':
2364 ++First;
2365 return make<NameType>("wchar_t");
2366 // ::= b # bool
2367 case 'b':
2368 ++First;
2369 return make<NameType>("bool");
2370 // ::= c # char
2371 case 'c':
2372 ++First;
2373 return make<NameType>("char");
2374 // ::= a # signed char
2375 case 'a':
2376 ++First;
2377 return make<NameType>("signed char");
2378 // ::= h # unsigned char
2379 case 'h':
2380 ++First;
2381 return make<NameType>("unsigned char");
2382 // ::= s # short
2383 case 's':
2384 ++First;
2385 return make<NameType>("short");
2386 // ::= t # unsigned short
2387 case 't':
2388 ++First;
2389 return make<NameType>("unsigned short");
2390 // ::= i # int
2391 case 'i':
2392 ++First;
2393 return make<NameType>("int");
2394 // ::= j # unsigned int
2395 case 'j':
2396 ++First;
2397 return make<NameType>("unsigned int");
2398 // ::= l # long
2399 case 'l':
2400 ++First;
2401 return make<NameType>("long");
2402 // ::= m # unsigned long
2403 case 'm':
2404 ++First;
2405 return make<NameType>("unsigned long");
2406 // ::= x # long long, __int64
2407 case 'x':
2408 ++First;
2409 return make<NameType>("long long");
2410 // ::= y # unsigned long long, __int64
2411 case 'y':
2412 ++First;
2413 return make<NameType>("unsigned long long");
2414 // ::= n # __int128
2415 case 'n':
2416 ++First;
2417 return make<NameType>("__int128");
2418 // ::= o # unsigned __int128
2419 case 'o':
2420 ++First;
2421 return make<NameType>("unsigned __int128");
2422 // ::= f # float
2423 case 'f':
2424 ++First;
2425 return make<NameType>("float");
2426 // ::= d # double
2427 case 'd':
2428 ++First;
2429 return make<NameType>("double");
2430 // ::= e # long double, __float80
2431 case 'e':
2432 ++First;
2433 return make<NameType>("long double");
2434 // ::= g # __float128
2435 case 'g':
2436 ++First;
2437 return make<NameType>("__float128");
2438 // ::= z # ellipsis
2439 case 'z':
2440 ++First;
2441 return make<NameType>("...");
2442
2443 // <builtin-type> ::= u <source-name> # vendor extended type
2444 case 'u': {
2445 ++First;
2446 StringView Res = parseBareSourceName();
2447 if (Res.empty())
2448 return nullptr;
2449 return make<NameType>(Res);
2450 }
2451 case 'D':
2452 switch (look(1)) {
2453 // ::= Dd # IEEE 754r decimal floating point (64 bits)
2454 case 'd':
2455 First += 2;
2456 return make<NameType>("decimal64");
2457 // ::= De # IEEE 754r decimal floating point (128 bits)
2458 case 'e':
2459 First += 2;
2460 return make<NameType>("decimal128");
2461 // ::= Df # IEEE 754r decimal floating point (32 bits)
2462 case 'f':
2463 First += 2;
2464 return make<NameType>("decimal32");
2465 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
2466 case 'h':
2467 First += 2;
2468 return make<NameType>("decimal16");
2469 // ::= Di # char32_t
2470 case 'i':
2471 First += 2;
2472 return make<NameType>("char32_t");
2473 // ::= Ds # char16_t
2474 case 's':
2475 First += 2;
2476 return make<NameType>("char16_t");
2477 // ::= Da # auto (in dependent new-expressions)
2478 case 'a':
2479 First += 2;
2480 return make<NameType>("auto");
2481 // ::= Dc # decltype(auto)
2482 case 'c':
2483 First += 2;
2484 return make<NameType>("decltype(auto)");
2485 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
2486 case 'n':
2487 First += 2;
2488 return make<NameType>("std::nullptr_t");
2489
2490 // ::= <decltype>
2491 case 't':
2492 case 'T': {
2493 Result = parseDecltype();
2494 break;
2495 }
2496 // extension ::= <vector-type> # <vector-type> starts with Dv
2497 case 'v': {
2498 Result = parseVectorType();
2499 break;
2500 }
2501 // ::= Dp <type> # pack expansion (C++0x)
2502 case 'p': {
2503 First += 2;
2504 Node *Child = parseType();
2505 if (!Child)
2506 return nullptr;
2507 Result = make<ParameterPackExpansion>(Child);
2508 break;
2509 }
2510 }
2511 break;
2512 // ::= <function-type>
2513 case 'F': {
2514 Result = parseFunctionType();
2515 break;
2516 }
2517 // ::= <array-type>
2518 case 'A': {
2519 Result = parseArrayType();
2520 break;
2521 }
2522 // ::= <pointer-to-member-type>
2523 case 'M': {
2524 Result = parsePointerToMemberType();
2525 break;
2526 }
2527 // ::= <template-param>
2528 case 'T': {
Erik Pilkington13fb7dc2018-02-13 00:15:53 +00002529 // This could be an elaborate type specifier on a <class-enum-type>.
2530 if (look(1) == 's' || look(1) == 'u' || look(1) == 'e') {
2531 Result = parseClassEnumType();
2532 break;
2533 }
2534
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002535 Result = legacyParse<parse_template_param>();
2536 if (Result == nullptr)
2537 return nullptr;
2538
2539 // Result could be either of:
2540 // <type> ::= <template-param>
2541 // <type> ::= <template-template-param> <template-args>
2542 //
2543 // <template-template-param> ::= <template-param>
2544 // ::= <substitution>
2545 //
2546 // If this is followed by some <template-args>, and we're permitted to
2547 // parse them, take the second production.
2548
2549 if (TryToParseTemplateArgs && look() == 'I') {
2550 Node *TA = legacyParse<parse_template_args>();
2551 if (TA == nullptr)
2552 return nullptr;
2553 Result = make<NameWithTemplateArgs>(Result, TA);
2554 }
2555 break;
2556 }
2557 // ::= P <type> # pointer
2558 case 'P': {
2559 ++First;
2560 Node *Ptr = parseType();
2561 if (Ptr == nullptr)
2562 return nullptr;
2563 Result = make<PointerType>(Ptr);
2564 break;
2565 }
2566 // ::= R <type> # l-value reference
2567 case 'R': {
2568 ++First;
2569 Node *Ref = parseType();
2570 if (Ref == nullptr)
2571 return nullptr;
2572 Result = make<LValueReferenceType>(Ref);
2573 break;
2574 }
2575 // ::= O <type> # r-value reference (C++11)
2576 case 'O': {
2577 ++First;
2578 Node *Ref = parseType();
2579 if (Ref == nullptr)
2580 return nullptr;
2581 Result = make<RValueReferenceType>(Ref);
2582 break;
2583 }
2584 // ::= C <type> # complex pair (C99)
2585 case 'C': {
2586 ++First;
2587 Node *P = parseType();
2588 if (P == nullptr)
2589 return nullptr;
2590 Result = make<PostfixQualifiedType>(P, " complex");
2591 break;
2592 }
2593 // ::= G <type> # imaginary (C99)
2594 case 'G': {
2595 ++First;
2596 Node *P = parseType();
2597 if (P == nullptr)
2598 return P;
2599 Result = make<PostfixQualifiedType>(P, " imaginary");
2600 break;
2601 }
2602 // ::= <substitution> # See Compression below
2603 case 'S': {
2604 if (look(1) && look(1) != 't') {
2605 Node *Sub = legacyParse<parse_substitution>();
2606 if (Sub == nullptr)
2607 return nullptr;
2608
2609 // Sub could be either of:
2610 // <type> ::= <substitution>
2611 // <type> ::= <template-template-param> <template-args>
2612 //
2613 // <template-template-param> ::= <template-param>
2614 // ::= <substitution>
2615 //
2616 // If this is followed by some <template-args>, and we're permitted to
2617 // parse them, take the second production.
2618
2619 if (TryToParseTemplateArgs && look() == 'I') {
2620 Node *TA = legacyParse<parse_template_args>();
2621 if (TA == nullptr)
2622 return nullptr;
2623 Result = make<NameWithTemplateArgs>(Sub, TA);
2624 break;
2625 }
2626
2627 // If all we parsed was a substitution, don't re-insert into the
2628 // substitution table.
2629 return Sub;
2630 }
2631 _LIBCPP_FALLTHROUGH();
2632 }
2633 // ::= <class-enum-type>
2634 default: {
2635 Result = parseClassEnumType();
2636 break;
2637 }
2638 }
2639
2640 // If we parsed a type, insert it into the substitution table. Note that all
2641 // <builtin-type>s and <substitution>s have already bailed out, because they
2642 // don't get substitutions.
2643 if (Result != nullptr)
2644 Subs.push_back(Result);
2645 return Result;
2646}
2647
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002648Node *Db::parsePrefixExpr(StringView Kind) {
2649 Node *E = parseExpr();
2650 if (E == nullptr)
2651 return nullptr;
2652 return make<PrefixExpr>(Kind, E);
2653}
2654
2655Node *Db::parseBinaryExpr(StringView Kind) {
2656 Node *LHS = parseExpr();
2657 if (LHS == nullptr)
2658 return nullptr;
2659 Node *RHS = parseExpr();
2660 if (RHS == nullptr)
2661 return nullptr;
2662 return make<BinaryExpr>(LHS, Kind, RHS);
2663}
2664
2665Node *Db::parseIntegerLiteral(StringView Lit) {
2666 StringView Tmp = parseNumber(true);
2667 if (!Tmp.empty() && consumeIf('E'))
2668 return make<IntegerExpr>(Lit, Tmp);
2669 return nullptr;
2670}
2671
2672Qualifiers Db::parseCVQualifiers() {
2673 Qualifiers CVR = QualNone;
2674 if (consumeIf('r'))
2675 addQualifiers(CVR, QualRestrict);
2676 if (consumeIf('V'))
2677 addQualifiers(CVR, QualVolatile);
2678 if (consumeIf('K'))
2679 addQualifiers(CVR, QualConst);
2680 return CVR;
2681}
2682
2683// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
2684// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
2685// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
2686// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
2687Node *Db::parseFunctionParam() {
2688 if (consumeIf("fp")) {
2689 parseCVQualifiers();
2690 StringView Num = parseNumber();
2691 if (!consumeIf('_'))
2692 return nullptr;
2693 return make<FunctionParam>(Num);
2694 }
2695 if (consumeIf("fL")) {
2696 if (parseNumber().empty())
2697 return nullptr;
2698 if (!consumeIf('p'))
2699 return nullptr;
2700 parseCVQualifiers();
2701 StringView Num = parseNumber();
2702 if (!consumeIf('_'))
2703 return nullptr;
2704 return make<FunctionParam>(Num);
2705 }
2706 return nullptr;
2707}
2708
2709// [gs] nw <expression>* _ <type> E # new (expr-list) type
2710// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
2711// [gs] na <expression>* _ <type> E # new[] (expr-list) type
2712// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
2713// <initializer> ::= pi <expression>* E # parenthesized initialization
2714Node *Db::parseNewExpr() {
2715 bool Global = consumeIf("gs");
2716 bool IsArray = look(1) == 'a';
2717 if (!consumeIf("nw") && !consumeIf("na"))
2718 return nullptr;
2719 size_t Exprs = Names.size();
2720 while (!consumeIf('_')) {
2721 Node *Ex = parseExpr();
2722 if (Ex == nullptr)
2723 return nullptr;
2724 Names.push_back(Ex);
2725 }
2726 NodeArray ExprList = popTrailingNodeArray(Exprs);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002727 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002728 if (Ty == nullptr)
2729 return Ty;
2730 if (consumeIf("pi")) {
2731 size_t InitsBegin = Names.size();
2732 while (!consumeIf('E')) {
2733 Node *Init = parseExpr();
2734 if (Init == nullptr)
2735 return Init;
2736 Names.push_back(Init);
2737 }
2738 NodeArray Inits = popTrailingNodeArray(InitsBegin);
2739 return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray);
2740 } else if (!consumeIf('E'))
2741 return nullptr;
2742 return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray);
2743}
2744
2745// cv <type> <expression> # conversion with one argument
2746// cv <type> _ <expression>* E # conversion with a different number of arguments
2747Node *Db::parseConversionExpr() {
2748 if (!consumeIf("cv"))
2749 return nullptr;
2750 Node *Ty;
2751 {
2752 SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002753 Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002754 }
2755
2756 if (Ty == nullptr)
2757 return nullptr;
2758
2759 if (consumeIf('_')) {
2760 size_t ExprsBegin = Names.size();
2761 while (!consumeIf('E')) {
2762 Node *E = parseExpr();
2763 if (E == nullptr)
2764 return E;
2765 Names.push_back(E);
2766 }
2767 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
2768 return make<ConversionExpr>(Ty, Exprs);
2769 }
2770
2771 Node *E[1] = {parseExpr()};
2772 if (E[0] == nullptr)
2773 return nullptr;
2774 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
2775}
2776
2777// <expr-primary> ::= L <type> <value number> E # integer literal
2778// ::= L <type> <value float> E # floating literal
2779// ::= L <string type> E # string literal
2780// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
2781// FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
2782// ::= L <mangled-name> E # external name
2783Node *Db::parseExprPrimary() {
2784 if (!consumeIf('L'))
2785 return nullptr;
2786 switch (look()) {
2787 case 'w':
2788 ++First;
2789 return parseIntegerLiteral("wchar_t");
2790 case 'b':
2791 if (consumeIf("b0E"))
2792 return make<BoolExpr>(0);
2793 if (consumeIf("b1E"))
2794 return make<BoolExpr>(1);
2795 return nullptr;
2796 case 'c':
2797 ++First;
2798 return parseIntegerLiteral("char");
2799 case 'a':
2800 ++First;
2801 return parseIntegerLiteral("signed char");
2802 case 'h':
2803 ++First;
2804 return parseIntegerLiteral("unsigned char");
2805 case 's':
2806 ++First;
2807 return parseIntegerLiteral("short");
2808 case 't':
2809 ++First;
2810 return parseIntegerLiteral("unsigned short");
2811 case 'i':
2812 ++First;
2813 return parseIntegerLiteral("");
2814 case 'j':
2815 ++First;
2816 return parseIntegerLiteral("u");
2817 case 'l':
2818 ++First;
2819 return parseIntegerLiteral("l");
2820 case 'm':
2821 ++First;
2822 return parseIntegerLiteral("ul");
2823 case 'x':
2824 ++First;
2825 return parseIntegerLiteral("ll");
2826 case 'y':
2827 ++First;
2828 return parseIntegerLiteral("ull");
2829 case 'n':
2830 ++First;
2831 return parseIntegerLiteral("__int128");
2832 case 'o':
2833 ++First;
2834 return parseIntegerLiteral("unsigned __int128");
2835 case 'f':
2836 ++First;
2837 return parseFloatingLiteral<float>();
2838 case 'd':
2839 ++First;
2840 return parseFloatingLiteral<double>();
2841 case 'e':
2842 ++First;
2843 return parseFloatingLiteral<long double>();
2844 case '_':
2845 if (consumeIf("_Z")) {
2846 Node *R = legacyParse<parse_encoding>();
2847 if (R != nullptr && consumeIf('E'))
2848 return R;
2849 }
2850 return nullptr;
2851 case 'T':
2852 // Invalid mangled name per
2853 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
2854 return nullptr;
2855 default: {
2856 // might be named type
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002857 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002858 if (T == nullptr)
2859 return nullptr;
2860 StringView N = parseNumber();
2861 if (!N.empty()) {
2862 if (!consumeIf('E'))
2863 return nullptr;
2864 return make<IntegerCastExpr>(T, N);
2865 }
2866 if (consumeIf('E'))
2867 return T;
2868 return nullptr;
2869 }
2870 }
2871}
2872
2873// <expression> ::= <unary operator-name> <expression>
2874// ::= <binary operator-name> <expression> <expression>
2875// ::= <ternary operator-name> <expression> <expression> <expression>
2876// ::= cl <expression>+ E # call
2877// ::= cv <type> <expression> # conversion with one argument
2878// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
2879// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
2880// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
2881// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
2882// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
2883// ::= [gs] dl <expression> # delete expression
2884// ::= [gs] da <expression> # delete[] expression
2885// ::= pp_ <expression> # prefix ++
2886// ::= mm_ <expression> # prefix --
2887// ::= ti <type> # typeid (type)
2888// ::= te <expression> # typeid (expression)
2889// ::= dc <type> <expression> # dynamic_cast<type> (expression)
2890// ::= sc <type> <expression> # static_cast<type> (expression)
2891// ::= cc <type> <expression> # const_cast<type> (expression)
2892// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
2893// ::= st <type> # sizeof (a type)
2894// ::= sz <expression> # sizeof (an expression)
2895// ::= at <type> # alignof (a type)
2896// ::= az <expression> # alignof (an expression)
2897// ::= nx <expression> # noexcept (expression)
2898// ::= <template-param>
2899// ::= <function-param>
2900// ::= dt <expression> <unresolved-name> # expr.name
2901// ::= pt <expression> <unresolved-name> # expr->name
2902// ::= ds <expression> <expression> # expr.*expr
2903// ::= sZ <template-param> # size of a parameter pack
2904// ::= sZ <function-param> # size of a function parameter pack
2905// ::= sp <expression> # pack expansion
2906// ::= tw <expression> # throw expression
2907// ::= tr # throw with no operand (rethrow)
2908// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
2909// # freestanding dependent name (e.g., T::x),
2910// # objectless nonstatic member reference
2911// ::= fL <binary-operator-name> <expression> <expression>
2912// ::= fR <binary-operator-name> <expression> <expression>
2913// ::= fl <binary-operator-name> <expression>
2914// ::= fr <binary-operator-name> <expression>
2915// ::= <expr-primary>
2916Node *Db::parseExpr() {
2917 bool Global = consumeIf("gs");
2918 if (numLeft() < 2)
2919 return nullptr;
2920
2921 switch (*First) {
2922 case 'L':
2923 return parseExprPrimary();
2924 case 'T':
2925 return legacyParse<parse_template_param>();
2926 case 'f':
2927 return parseFunctionParam();
2928 case 'a':
2929 switch (First[1]) {
2930 case 'a':
2931 First += 2;
2932 return parseBinaryExpr("&&");
2933 case 'd':
2934 First += 2;
2935 return parsePrefixExpr("&");
2936 case 'n':
2937 First += 2;
2938 return parseBinaryExpr("&");
2939 case 'N':
2940 First += 2;
2941 return parseBinaryExpr("&=");
2942 case 'S':
2943 First += 2;
2944 return parseBinaryExpr("=");
2945 case 't': {
2946 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002947 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002948 if (Ty == nullptr)
2949 return nullptr;
2950 return make<EnclosingExpr>("alignof (", Ty, ")");
2951 }
2952 case 'z': {
2953 First += 2;
2954 Node *Ty = parseExpr();
2955 if (Ty == nullptr)
2956 return nullptr;
2957 return make<EnclosingExpr>("alignof (", Ty, ")");
2958 }
2959 }
2960 return nullptr;
2961 case 'c':
2962 switch (First[1]) {
2963 // cc <type> <expression> # const_cast<type>(expression)
2964 case 'c': {
2965 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002966 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002967 if (Ty == nullptr)
2968 return Ty;
2969 Node *Ex = parseExpr();
2970 if (Ex == nullptr)
2971 return Ex;
2972 return make<CastExpr>("const_cast", Ty, Ex);
2973 }
2974 // cl <expression>+ E # call
2975 case 'l': {
2976 First += 2;
2977 Node *Callee = parseExpr();
2978 if (Callee == nullptr)
2979 return Callee;
2980 size_t ExprsBegin = Names.size();
2981 while (!consumeIf('E')) {
2982 Node *E = parseExpr();
2983 if (E == nullptr)
2984 return E;
2985 Names.push_back(E);
2986 }
2987 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin));
2988 }
2989 case 'm':
2990 First += 2;
2991 return parseBinaryExpr(",");
2992 case 'o':
2993 First += 2;
2994 return parsePrefixExpr("~");
2995 case 'v':
2996 return parseConversionExpr();
2997 }
2998 return nullptr;
2999 case 'd':
3000 switch (First[1]) {
3001 case 'a': {
3002 First += 2;
3003 Node *Ex = parseExpr();
3004 if (Ex == nullptr)
3005 return Ex;
3006 return make<DeleteExpr>(Ex, Global, /*is_array=*/true);
3007 }
3008 case 'c': {
3009 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003010 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003011 if (T == nullptr)
3012 return T;
3013 Node *Ex = parseExpr();
3014 if (Ex == nullptr)
3015 return Ex;
3016 return make<CastExpr>("dynamic_cast", T, Ex);
3017 }
3018 case 'e':
3019 First += 2;
3020 return parsePrefixExpr("*");
3021 case 'l': {
3022 First += 2;
3023 Node *E = parseExpr();
3024 if (E == nullptr)
3025 return E;
3026 return make<DeleteExpr>(E, Global, /*is_array=*/false);
3027 }
3028 case 'n':
3029 return legacyParse<parse_unresolved_name>();
3030 case 's': {
3031 First += 2;
3032 Node *LHS = parseExpr();
3033 if (LHS == nullptr)
3034 return nullptr;
3035 Node *RHS = parseExpr();
3036 if (RHS == nullptr)
3037 return nullptr;
3038 return make<MemberExpr>(LHS, ".*", RHS);
3039 }
3040 case 't': {
3041 First += 2;
3042 Node *LHS = parseExpr();
3043 if (LHS == nullptr)
3044 return LHS;
3045 Node *RHS = parseExpr();
3046 if (RHS == nullptr)
3047 return nullptr;
3048 return make<MemberExpr>(LHS, ".", RHS);
3049 }
3050 case 'v':
3051 First += 2;
3052 return parseBinaryExpr("/");
3053 case 'V':
3054 First += 2;
3055 return parseBinaryExpr("/=");
3056 }
3057 return nullptr;
3058 case 'e':
3059 switch (First[1]) {
3060 case 'o':
3061 First += 2;
3062 return parseBinaryExpr("^");
3063 case 'O':
3064 First += 2;
3065 return parseBinaryExpr("^=");
3066 case 'q':
3067 First += 2;
3068 return parseBinaryExpr("==");
3069 }
3070 return nullptr;
3071 case 'g':
3072 switch (First[1]) {
3073 case 'e':
3074 First += 2;
3075 return parseBinaryExpr(">=");
3076 case 't':
3077 First += 2;
3078 return parseBinaryExpr(">");
3079 }
3080 return nullptr;
3081 case 'i':
3082 if (First[1] == 'x') {
3083 First += 2;
3084 Node *Base = parseExpr();
3085 if (Base == nullptr)
3086 return nullptr;
3087 Node *Index = parseExpr();
3088 if (Index == nullptr)
3089 return Index;
3090 return make<ArraySubscriptExpr>(Base, Index);
3091 }
3092 return nullptr;
3093 case 'l':
3094 switch (First[1]) {
3095 case 'e':
3096 First += 2;
3097 return parseBinaryExpr("<=");
3098 case 's':
3099 First += 2;
3100 return parseBinaryExpr("<<");
3101 case 'S':
3102 First += 2;
3103 return parseBinaryExpr("<<=");
3104 case 't':
3105 First += 2;
3106 return parseBinaryExpr("<");
3107 }
3108 return nullptr;
3109 case 'm':
3110 switch (First[1]) {
3111 case 'i':
3112 First += 2;
3113 return parseBinaryExpr("-");
3114 case 'I':
3115 First += 2;
3116 return parseBinaryExpr("-=");
3117 case 'l':
3118 First += 2;
3119 return parseBinaryExpr("*");
3120 case 'L':
3121 First += 2;
3122 return parseBinaryExpr("*=");
3123 case 'm':
3124 First += 2;
3125 if (consumeIf('_'))
3126 return parsePrefixExpr("--");
3127 Node *Ex = parseExpr();
3128 if (Ex == nullptr)
3129 return nullptr;
3130 return make<PostfixExpr>(Ex, "--");
3131 }
3132 return nullptr;
3133 case 'n':
3134 switch (First[1]) {
3135 case 'a':
3136 case 'w':
3137 return parseNewExpr();
3138 case 'e':
3139 First += 2;
3140 return parseBinaryExpr("!=");
3141 case 'g':
3142 First += 2;
3143 return parsePrefixExpr("-");
3144 case 't':
3145 First += 2;
3146 return parsePrefixExpr("!");
3147 case 'x':
3148 First += 2;
3149 Node *Ex = parseExpr();
3150 if (Ex == nullptr)
3151 return Ex;
3152 return make<EnclosingExpr>("noexcept (", Ex, ")");
3153 }
3154 return nullptr;
3155 case 'o':
3156 switch (First[1]) {
3157 case 'n':
3158 return legacyParse<parse_unresolved_name>();
3159 case 'o':
3160 First += 2;
3161 return parseBinaryExpr("||");
3162 case 'r':
3163 First += 2;
3164 return parseBinaryExpr("|");
3165 case 'R':
3166 First += 2;
3167 return parseBinaryExpr("|=");
3168 }
3169 return nullptr;
3170 case 'p':
3171 switch (First[1]) {
3172 case 'm':
3173 First += 2;
3174 return parseBinaryExpr("->*");
3175 case 'l':
3176 First += 2;
3177 return parseBinaryExpr("+");
3178 case 'L':
3179 First += 2;
3180 return parseBinaryExpr("+=");
3181 case 'p': {
3182 First += 2;
3183 if (consumeIf('_'))
3184 return parsePrefixExpr("++");
3185 Node *Ex = parseExpr();
3186 if (Ex == nullptr)
3187 return Ex;
3188 return make<PostfixExpr>(Ex, "++");
3189 }
3190 case 's':
3191 First += 2;
3192 return parsePrefixExpr("+");
3193 case 't': {
3194 First += 2;
3195 Node *L = parseExpr();
3196 if (L == nullptr)
3197 return nullptr;
3198 Node *R = parseExpr();
3199 if (R == nullptr)
3200 return nullptr;
3201 return make<MemberExpr>(L, "->", R);
3202 }
3203 }
3204 return nullptr;
3205 case 'q':
3206 if (First[1] == 'u') {
3207 First += 2;
3208 Node *Cond = parseExpr();
Erik Pilkington24e8b732018-02-05 02:34:41 +00003209 if (Cond == nullptr)
3210 return nullptr;
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003211 Node *LHS = parseExpr();
Erik Pilkington24e8b732018-02-05 02:34:41 +00003212 if (LHS == nullptr)
3213 return nullptr;
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003214 Node *RHS = parseExpr();
Erik Pilkington24e8b732018-02-05 02:34:41 +00003215 if (RHS == nullptr)
3216 return nullptr;
3217 return make<ConditionalExpr>(Cond, LHS, RHS);
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003218 }
3219 return nullptr;
3220 case 'r':
3221 switch (First[1]) {
3222 case 'c': {
3223 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003224 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003225 if (T == nullptr)
3226 return T;
3227 Node *Ex = parseExpr();
3228 if (Ex == nullptr)
3229 return Ex;
3230 return make<CastExpr>("reinterpret_cast", T, Ex);
3231 }
3232 case 'm':
3233 First += 2;
3234 return parseBinaryExpr("%");
3235 case 'M':
3236 First += 2;
3237 return parseBinaryExpr("%=");
3238 case 's':
3239 First += 2;
3240 return parseBinaryExpr(">>");
3241 case 'S':
3242 First += 2;
3243 return parseBinaryExpr(">>=");
3244 }
3245 return nullptr;
3246 case 's':
3247 switch (First[1]) {
3248 case 'c': {
3249 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003250 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003251 if (T == nullptr)
3252 return T;
3253 Node *Ex = parseExpr();
3254 if (Ex == nullptr)
3255 return Ex;
3256 return make<CastExpr>("static_cast", T, Ex);
3257 }
3258 case 'p': {
3259 First += 2;
3260 Node *Child = parseExpr();
3261 if (Child == nullptr)
3262 return nullptr;
3263 return make<ParameterPackExpansion>(Child);
3264 }
3265 case 'r':
3266 return legacyParse<parse_unresolved_name>();
3267 case 't': {
3268 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003269 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003270 if (Ty == nullptr)
3271 return Ty;
3272 return make<EnclosingExpr>("sizeof (", Ty, ")");
3273 }
3274 case 'z': {
3275 First += 2;
3276 Node *Ex = parseExpr();
3277 if (Ex == nullptr)
3278 return Ex;
3279 return make<EnclosingExpr>("sizeof (", Ex, ")");
3280 }
3281 case 'Z':
3282 First += 2;
3283 if (look() == 'T') {
3284 Node *R = legacyParse<parse_template_param>();
3285 if (R == nullptr)
3286 return nullptr;
3287 return make<SizeofParamPackExpr>(R);
3288 } else if (look() == 'f') {
3289 Node *FP = parseFunctionParam();
3290 if (FP == nullptr)
3291 return nullptr;
3292 return make<EnclosingExpr>("sizeof...", FP, ")");
3293 }
3294 return nullptr;
3295 }
3296 return nullptr;
3297 case 't':
3298 switch (First[1]) {
3299 case 'e': {
3300 First += 2;
3301 Node *Ex = parseExpr();
3302 if (Ex == nullptr)
3303 return Ex;
3304 return make<EnclosingExpr>("typeid (", Ex, ")");
3305 }
3306 case 'i': {
3307 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003308 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003309 if (Ty == nullptr)
3310 return Ty;
3311 return make<EnclosingExpr>("typeid (", Ty, ")");
3312 }
3313 case 'r':
3314 First += 2;
3315 return make<NameType>("throw");
3316 case 'w': {
3317 First += 2;
3318 Node *Ex = parseExpr();
3319 if (Ex == nullptr)
3320 return nullptr;
3321 return make<ThrowExpr>(Ex);
3322 }
3323 }
3324 return nullptr;
3325 case '1':
3326 case '2':
3327 case '3':
3328 case '4':
3329 case '5':
3330 case '6':
3331 case '7':
3332 case '8':
3333 case '9':
3334 return legacyParse<parse_unresolved_name>();
3335 }
3336 return nullptr;
3337}
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003338
Howard Hinnant6c33e762013-06-17 18:10:34 +00003339// <number> ::= [n] <non-negative decimal integer>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003340
3341const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00003342parse_number(const char* first, const char* last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003343{
Howard Hinnant6c33e762013-06-17 18:10:34 +00003344 if (first != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003345 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003346 const char* t = first;
3347 if (*t == 'n')
3348 ++t;
3349 if (t != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003350 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003351 if (*t == '0')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003352 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003353 first = t+1;
3354 }
3355 else if ('1' <= *t && *t <= '9')
3356 {
3357 first = t+1;
3358 while (first != last && std::isdigit(*first))
3359 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003360 }
3361 }
3362 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003363 return first;
3364}
3365
3366template <class Float>
Erik Pilkington0024acd2017-07-28 00:43:49 +00003367struct FloatData;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003368
3369template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00003370struct FloatData<float>
Howard Hinnant6c33e762013-06-17 18:10:34 +00003371{
3372 static const size_t mangled_size = 8;
3373 static const size_t max_demangled_size = 24;
Howard Hinnantc62cbea2013-06-17 20:25:21 +00003374 static constexpr const char* spec = "%af";
Howard Hinnant6c33e762013-06-17 18:10:34 +00003375};
3376
Erik Pilkington0024acd2017-07-28 00:43:49 +00003377constexpr const char* FloatData<float>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003378
3379template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00003380struct FloatData<double>
Howard Hinnant6c33e762013-06-17 18:10:34 +00003381{
3382 static const size_t mangled_size = 16;
3383 static const size_t max_demangled_size = 32;
3384 static constexpr const char* spec = "%a";
Howard Hinnant6c33e762013-06-17 18:10:34 +00003385};
3386
Erik Pilkington0024acd2017-07-28 00:43:49 +00003387constexpr const char* FloatData<double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003388
3389template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00003390struct FloatData<long double>
Howard Hinnant6c33e762013-06-17 18:10:34 +00003391{
Dan Gohmand04ecd02016-01-13 16:39:30 +00003392#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
3393 defined(__wasm__)
Daniel Sanders52cf98b2015-07-30 16:11:04 +00003394 static const size_t mangled_size = 32;
Ben Craig9ef2c6e2016-01-20 14:10:23 +00003395#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
Logan Chien05d51bc2014-05-10 00:42:10 +00003396 static const size_t mangled_size = 16;
3397#else
Howard Hinnant6c33e762013-06-17 18:10:34 +00003398 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 +00003399#endif
Howard Hinnant6c33e762013-06-17 18:10:34 +00003400 static const size_t max_demangled_size = 40;
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003401 static constexpr const char *spec = "%LaL";
Howard Hinnant6c33e762013-06-17 18:10:34 +00003402};
3403
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003404constexpr const char *FloatData<long double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003405
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003406template <class Float> Node *Db::parseFloatingLiteral() {
3407 const size_t N = FloatData<Float>::mangled_size;
3408 if (numLeft() <= N)
3409 return nullptr;
3410 StringView Data(First, First + N);
3411 for (char C : Data)
3412 if (!std::isxdigit(C))
3413 return nullptr;
3414 First += N;
3415 if (!consumeIf('E'))
3416 return nullptr;
3417 return make<FloatExpr<Float>>(Data);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003418}
3419
Erik Pilkington5bff4122017-11-22 20:38:22 +00003420// <positive length number> ::= [0-9]*
Howard Hinnant6c33e762013-06-17 18:10:34 +00003421const char*
Erik Pilkington5bff4122017-11-22 20:38:22 +00003422parse_positive_integer(const char* first, const char* last, size_t* out)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003423{
3424 if (first != last)
3425 {
3426 char c = *first;
3427 if (isdigit(c) && first+1 != last)
3428 {
3429 const char* t = first+1;
3430 size_t n = static_cast<size_t>(c - '0');
3431 for (c = *t; isdigit(c); c = *t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003432 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003433 n = n * 10 + static_cast<size_t>(c - '0');
3434 if (++t == last)
3435 return first;
3436 }
Erik Pilkington5bff4122017-11-22 20:38:22 +00003437 *out = n;
3438 first = t;
3439 }
3440 }
3441 return first;
3442}
3443
3444// extension
3445// <abi-tag-seq> ::= <abi-tag>*
3446// <abi-tag> ::= B <positive length number> <identifier>
3447const char*
3448parse_abi_tag_seq(const char* first, const char* last, Db& db)
3449{
3450 while (first != last && *first == 'B' && first+1 != last)
3451 {
3452 size_t length;
3453 const char* t = parse_positive_integer(first+1, last, &length);
3454 if (t == first+1)
3455 return first;
3456 if (static_cast<size_t>(last - t) < length || db.Names.empty())
3457 return first;
3458 db.Names.back() = db.make<AbiTagAttr>(
3459 db.Names.back(), StringView(t, t + length));
3460 first = t + length;
3461 }
3462 return first;
3463}
3464
3465// <source-name> ::= <positive length number> <identifier> [<abi-tag-seq>]
3466const char*
3467parse_source_name(const char* first, const char* last, Db& db)
3468{
3469 if (first != last)
3470 {
3471 size_t length;
3472 const char* t = parse_positive_integer(first, last, &length);
3473 if (t == first)
3474 return first;
3475 if (static_cast<size_t>(last - t) >= length)
3476 {
3477 StringView r(t, t + length);
3478 if (r.substr(0, 10) == "_GLOBAL__N")
3479 db.Names.push_back(db.make<NameType>("(anonymous namespace)"));
3480 else
3481 db.Names.push_back(db.make<NameType>(r));
3482 first = t + length;
3483 first = parse_abi_tag_seq(first, last, db);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003484 }
3485 }
3486 return first;
3487}
3488
3489// <substitution> ::= S <seq-id> _
3490// ::= S_
3491// <substitution> ::= Sa # ::std::allocator
3492// <substitution> ::= Sb # ::std::basic_string
3493// <substitution> ::= Ss # ::std::basic_string < char,
3494// ::std::char_traits<char>,
3495// ::std::allocator<char> >
3496// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
3497// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
3498// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
3499
Howard Hinnant6c33e762013-06-17 18:10:34 +00003500const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003501parse_substitution(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003502{
3503 if (last - first >= 2)
3504 {
3505 if (*first == 'S')
3506 {
3507 switch (first[1])
3508 {
3509 case 'a':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003510 db.Names.push_back(
Erik Pilkington0024acd2017-07-28 00:43:49 +00003511 db.make<SpecialSubstitution>(
3512 SpecialSubKind::allocator));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003513 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003514 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003515 case 'b':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003516 db.Names.push_back(
Erik Pilkington0024acd2017-07-28 00:43:49 +00003517 db.make<SpecialSubstitution>(SpecialSubKind::basic_string));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003518 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003519 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003520 case 's':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003521 db.Names.push_back(
Erik Pilkington0024acd2017-07-28 00:43:49 +00003522 db.make<SpecialSubstitution>(
3523 SpecialSubKind::string));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003524 first += 2;
3525 break;
3526 case 'i':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003527 db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::istream));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003528 first += 2;
3529 break;
3530 case 'o':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003531 db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::ostream));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003532 first += 2;
3533 break;
3534 case 'd':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003535 db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::iostream));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003536 first += 2;
3537 break;
3538 case '_':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003539 if (!db.Subs.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003540 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003541 db.Names.push_back(db.Subs[0]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003542 first += 2;
3543 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003544 break;
3545 default:
Howard Hinnant6c33e762013-06-17 18:10:34 +00003546 if (std::isdigit(first[1]) || std::isupper(first[1]))
3547 {
3548 size_t sub = 0;
3549 const char* t = first+1;
3550 if (std::isdigit(*t))
3551 sub = static_cast<size_t>(*t - '0');
3552 else
3553 sub = static_cast<size_t>(*t - 'A') + 10;
3554 for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t)
3555 {
3556 sub *= 36;
3557 if (std::isdigit(*t))
3558 sub += static_cast<size_t>(*t - '0');
3559 else
3560 sub += static_cast<size_t>(*t - 'A') + 10;
3561 }
3562 if (t == last || *t != '_')
3563 return first;
3564 ++sub;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003565 if (sub < db.Subs.size())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003566 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003567 db.Names.push_back(db.Subs[sub]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003568 first = t+1;
3569 }
3570 }
3571 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003572 }
3573 }
3574 }
3575 return first;
3576}
3577
Erik Pilkington0024acd2017-07-28 00:43:49 +00003578// <CV-Qualifiers> ::= [r] [V] [K]
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003579
3580const char*
Erik Pilkington0024acd2017-07-28 00:43:49 +00003581parse_cv_qualifiers(const char* first, const char* last, Qualifiers& cv)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003582{
Erik Pilkington0024acd2017-07-28 00:43:49 +00003583 cv = QualNone;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003584 if (first != last)
3585 {
3586 if (*first == 'r')
3587 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003588 addQualifiers(cv, QualRestrict);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003589 ++first;
3590 }
3591 if (*first == 'V')
3592 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003593 addQualifiers(cv, QualVolatile);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003594 ++first;
3595 }
3596 if (*first == 'K')
3597 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003598 addQualifiers(cv, QualConst);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003599 ++first;
3600 }
3601 }
3602 return first;
3603}
3604
3605// <template-param> ::= T_ # first template parameter
3606// ::= T <parameter-2 non-negative number> _
3607
Howard Hinnant6c33e762013-06-17 18:10:34 +00003608const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003609parse_template_param(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003610{
3611 if (last - first >= 2)
3612 {
3613 if (*first == 'T')
3614 {
3615 if (first[1] == '_')
3616 {
Erik Pilkingtonba34a242017-08-09 21:30:57 +00003617 if (!db.TemplateParams.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003618 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003619 db.Names.push_back(db.TemplateParams[0]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003620 first += 2;
3621 }
3622 else
3623 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003624 db.Names.push_back(db.make<NameType>("T_"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003625 first += 2;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003626 db.FixForwardReferences = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003627 }
3628 }
3629 else if (isdigit(first[1]))
3630 {
3631 const char* t = first+1;
3632 size_t sub = static_cast<size_t>(*t - '0');
3633 for (++t; t != last && isdigit(*t); ++t)
3634 {
3635 sub *= 10;
3636 sub += static_cast<size_t>(*t - '0');
3637 }
Erik Pilkingtonba34a242017-08-09 21:30:57 +00003638 if (t == last || *t != '_')
Howard Hinnant6c33e762013-06-17 18:10:34 +00003639 return first;
3640 ++sub;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00003641 if (sub < db.TemplateParams.size())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003642 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003643 db.Names.push_back(db.TemplateParams[sub]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003644 first = t+1;
3645 }
3646 else
3647 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003648 db.Names.push_back(
Erik Pilkington0024acd2017-07-28 00:43:49 +00003649 db.make<NameType>(StringView(first, t + 1)));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003650 first = t+1;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003651 db.FixForwardReferences = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003652 }
3653 }
3654 }
3655 }
3656 return first;
3657}
3658
Howard Hinnant6c33e762013-06-17 18:10:34 +00003659// <simple-id> ::= <source-name> [ <template-args> ]
3660
Howard Hinnant6c33e762013-06-17 18:10:34 +00003661const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003662parse_simple_id(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003663{
3664 if (first != last)
3665 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003666 const char* t = parse_source_name(first, last, db);
3667 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003668 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003669 const char* t1 = parse_template_args(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003670 if (t1 != t)
3671 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003672 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003673 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003674 auto args = db.Names.back();
3675 db.Names.pop_back();
3676 db.Names.back() =
3677 db.make<NameWithTemplateArgs>(db.Names.back(), args);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003678 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003679 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003680 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003681 else
Howard Hinnant6c33e762013-06-17 18:10:34 +00003682 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003683 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003684 return first;
3685}
3686
Howard Hinnant6c33e762013-06-17 18:10:34 +00003687// <unresolved-type> ::= <template-param>
3688// ::= <decltype>
3689// ::= <substitution>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003690
3691const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003692parse_unresolved_type(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003693{
Howard Hinnant6c33e762013-06-17 18:10:34 +00003694 if (first != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003695 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003696 const char* t = first;
3697 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003698 {
Howard Hinnant86ccacd2012-09-13 23:49:59 +00003699 case 'T':
Howard Hinnant6c33e762013-06-17 18:10:34 +00003700 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003701 size_t k0 = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003702 t = parse_template_param(first, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003703 size_t k1 = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003704 if (t != first && k1 == k0 + 1)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003705 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003706 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003707 first = t;
Howard Hinnantab039992012-08-01 18:56:46 +00003708 }
3709 else
Howard Hinnant342f2f92012-11-30 18:43:50 +00003710 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003711 for (; k1 != k0; --k1)
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003712 db.Names.pop_back();
Howard Hinnant342f2f92012-11-30 18:43:50 +00003713 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003714 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003715 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003716 case 'D':
Howard Hinnant6c33e762013-06-17 18:10:34 +00003717 t = parse_decltype(first, last, db);
3718 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003719 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003720 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003721 return first;
Erik Pilkington761e6b02018-01-31 20:17:06 +00003722 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003723 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003724 }
3725 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003726 case 'S':
3727 t = parse_substitution(first, last, db);
3728 if (t != first)
3729 first = t;
3730 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003731 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003732 if (last - first > 2 && first[1] == 't')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003733 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003734 t = parse_unqualified_name(first+2, last, db);
3735 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003736 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003737 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003738 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003739 db.Names.back() =
3740 db.make<StdQualifiedName>(db.Names.back());
Erik Pilkington761e6b02018-01-31 20:17:06 +00003741 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003742 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003743 }
3744 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003745 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003746 break;
3747 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003748 }
3749 return first;
3750}
3751
3752// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
3753// ::= <simple-id> # e.g., ~A<2*N>
3754
3755const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003756parse_destructor_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003757{
3758 if (first != last)
3759 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003760 const char* t = parse_unresolved_type(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003761 if (t == first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003762 t = parse_simple_id(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003763 if (t != first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003764 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003765 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003766 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003767 db.Names.back() = db.make<DtorName>(db.Names.back());
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003768 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003769 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003770 }
3771 return first;
3772}
3773
3774// <base-unresolved-name> ::= <simple-id> # unresolved name
3775// extension ::= <operator-name> # unresolved operator-function-id
3776// extension ::= <operator-name> <template-args> # unresolved operator template-id
3777// ::= on <operator-name> # unresolved operator-function-id
3778// ::= on <operator-name> <template-args> # unresolved operator template-id
3779// ::= dn <destructor-name> # destructor or pseudo-destructor;
3780// # e.g. ~X or ~X<N-1>
3781
3782const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003783parse_base_unresolved_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003784{
3785 if (last - first >= 2)
3786 {
3787 if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n')
3788 {
3789 if (first[0] == 'o')
3790 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003791 const char* t = parse_operator_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003792 if (t != first+2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003793 {
3794 first = parse_template_args(t, last, db);
3795 if (first != t)
3796 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003797 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003798 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003799 auto args = db.Names.back();
3800 db.Names.pop_back();
3801 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00003802 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003803 db.Names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003804 }
3805 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003806 }
3807 else
3808 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003809 const char* t = parse_destructor_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003810 if (t != first+2)
3811 first = t;
3812 }
3813 }
3814 else
3815 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003816 const char* t = parse_simple_id(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003817 if (t == first)
3818 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003819 t = parse_operator_name(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003820 if (t != first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003821 {
3822 first = parse_template_args(t, last, db);
3823 if (first != t)
3824 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003825 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003826 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003827 auto args = db.Names.back();
3828 db.Names.pop_back();
3829 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00003830 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003831 db.Names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003832 }
3833 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003834 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003835 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003836 first = t;
3837 }
3838 }
3839 return first;
3840}
3841
Howard Hinnant6c33e762013-06-17 18:10:34 +00003842// <unresolved-qualifier-level> ::= <simple-id>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003843
3844const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003845parse_unresolved_qualifier_level(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003846{
Howard Hinnant6c33e762013-06-17 18:10:34 +00003847 return parse_simple_id(first, last, db);
Howard Hinnant889b02d2011-06-22 19:27:39 +00003848}
3849
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003850// <unresolved-name>
Howard Hinnant889b02d2011-06-22 19:27:39 +00003851// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003852// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3853// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3854// # A::x, N::y, A<T>::z; "gs" means leading "::"
Howard Hinnant889b02d2011-06-22 19:27:39 +00003855// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
Howard Hinnant6c33e762013-06-17 18:10:34 +00003856// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
Howard Hinnant889b02d2011-06-22 19:27:39 +00003857// # T::N::x /decltype(p)::N::x
3858// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003859
3860const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003861parse_unresolved_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003862{
3863 if (last - first > 2)
3864 {
Howard Hinnant889b02d2011-06-22 19:27:39 +00003865 const char* t = first;
3866 bool global = false;
3867 if (t[0] == 'g' && t[1] == 's')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003868 {
Howard Hinnant889b02d2011-06-22 19:27:39 +00003869 global = true;
3870 t += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003871 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003872 const char* t2 = parse_base_unresolved_name(t, last, db);
Howard Hinnant889b02d2011-06-22 19:27:39 +00003873 if (t2 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003874 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003875 if (global)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003876 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003877 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003878 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003879 db.Names.back() =
3880 db.make<GlobalQualifiedName>(db.Names.back());
Howard Hinnant753a30d2013-12-11 19:44:25 +00003881 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003882 first = t2;
Howard Hinnant889b02d2011-06-22 19:27:39 +00003883 }
3884 else if (last - t > 2 && t[0] == 's' && t[1] == 'r')
3885 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003886 if (t[2] == 'N')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003887 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003888 t += 3;
3889 const char* t1 = parse_unresolved_type(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003890 if (t1 == t || t1 == last)
3891 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003892 t = t1;
3893 t1 = parse_template_args(t, last, db);
3894 if (t1 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003895 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003896 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003897 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003898 auto args = db.Names.back();
3899 db.Names.pop_back();
3900 db.Names.back() = db.make<NameWithTemplateArgs>(
3901 db.Names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003902 t = t1;
3903 if (t == last)
3904 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003905 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003906 return first;
3907 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003908 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003909 while (*t != 'E')
3910 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003911 t1 = parse_unresolved_qualifier_level(t, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003912 if (t1 == t || t1 == last || db.Names.size() < 2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003913 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003914 auto s = db.Names.back();
3915 db.Names.pop_back();
3916 db.Names.back() =
3917 db.make<QualifiedName>(db.Names.back(), s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003918 t = t1;
3919 }
3920 ++t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003921 t1 = parse_base_unresolved_name(t, last, db);
3922 if (t1 == t)
3923 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003924 if (!db.Names.empty())
3925 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003926 return first;
3927 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003928 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003929 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003930 auto s = db.Names.back();
3931 db.Names.pop_back();
3932 db.Names.back() =
3933 db.make<QualifiedName>(db.Names.back(), s);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003934 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003935 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003936 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003937 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003938 t += 2;
3939 const char* t1 = parse_unresolved_type(t, last, db);
3940 if (t1 != t)
3941 {
3942 t = t1;
3943 t1 = parse_template_args(t, last, db);
3944 if (t1 != t)
3945 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003946 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003947 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003948 auto args = db.Names.back();
3949 db.Names.pop_back();
3950 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00003951 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003952 db.Names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003953 t = t1;
3954 }
3955 t1 = parse_base_unresolved_name(t, last, db);
3956 if (t1 == t)
3957 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003958 if (!db.Names.empty())
3959 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003960 return first;
3961 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003962 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003963 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003964 auto s = db.Names.back();
3965 db.Names.pop_back();
3966 db.Names.back() =
3967 db.make<QualifiedName>(db.Names.back(), s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003968 first = t1;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003969 }
3970 else
3971 {
3972 t1 = parse_unresolved_qualifier_level(t, last, db);
3973 if (t1 == t || t1 == last)
3974 return first;
3975 t = t1;
3976 if (global)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003977 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003978 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003979 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003980 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00003981 db.make<GlobalQualifiedName>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003982 db.Names.back());
Howard Hinnant753a30d2013-12-11 19:44:25 +00003983 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003984 while (*t != 'E')
3985 {
3986 t1 = parse_unresolved_qualifier_level(t, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003987 if (t1 == t || t1 == last || db.Names.size() < 2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003988 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003989 auto s = db.Names.back();
3990 db.Names.pop_back();
3991 db.Names.back() = db.make<QualifiedName>(
3992 db.Names.back(), s);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003993 t = t1;
3994 }
3995 ++t;
3996 t1 = parse_base_unresolved_name(t, last, db);
3997 if (t1 == t)
3998 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003999 if (!db.Names.empty())
4000 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004001 return first;
4002 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004003 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00004004 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004005 auto s = db.Names.back();
4006 db.Names.pop_back();
4007 db.Names.back() =
4008 db.make<QualifiedName>(db.Names.back(), s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004009 first = t1;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004010 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004011 }
4012 }
4013 }
4014 return first;
4015}
4016
Howard Hinnant6c33e762013-06-17 18:10:34 +00004017// <operator-name>
4018// ::= aa # &&
4019// ::= ad # & (unary)
4020// ::= an # &
4021// ::= aN # &=
4022// ::= aS # =
4023// ::= cl # ()
4024// ::= cm # ,
4025// ::= co # ~
4026// ::= cv <type> # (cast)
4027// ::= da # delete[]
4028// ::= de # * (unary)
4029// ::= dl # delete
4030// ::= dv # /
4031// ::= dV # /=
4032// ::= eo # ^
4033// ::= eO # ^=
4034// ::= eq # ==
4035// ::= ge # >=
4036// ::= gt # >
4037// ::= ix # []
4038// ::= le # <=
Howard Hinnantf29757a2014-01-06 23:05:04 +00004039// ::= li <source-name> # operator ""
Howard Hinnant6c33e762013-06-17 18:10:34 +00004040// ::= ls # <<
4041// ::= lS # <<=
4042// ::= lt # <
4043// ::= mi # -
4044// ::= mI # -=
4045// ::= ml # *
4046// ::= mL # *=
4047// ::= mm # -- (postfix in <expression> context)
4048// ::= na # new[]
4049// ::= ne # !=
4050// ::= ng # - (unary)
4051// ::= nt # !
4052// ::= nw # new
4053// ::= oo # ||
4054// ::= or # |
4055// ::= oR # |=
4056// ::= pm # ->*
4057// ::= pl # +
4058// ::= pL # +=
4059// ::= pp # ++ (postfix in <expression> context)
4060// ::= ps # + (unary)
4061// ::= pt # ->
4062// ::= qu # ?
4063// ::= rm # %
4064// ::= rM # %=
4065// ::= rs # >>
4066// ::= rS # >>=
4067// ::= v <digit> <source-name> # vendor extended operator
Erik Pilkington5bff4122017-11-22 20:38:22 +00004068// extension ::= <operator-name> <abi-tag-seq>
Howard Hinnant6c33e762013-06-17 18:10:34 +00004069const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004070parse_operator_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004071{
Erik Pilkington5bff4122017-11-22 20:38:22 +00004072 const char* original_first = first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004073 if (last - first >= 2)
4074 {
4075 switch (first[0])
4076 {
4077 case 'a':
4078 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004079 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004080 case 'a':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004081 db.Names.push_back(db.make<NameType>("operator&&"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004082 first += 2;
4083 break;
4084 case 'd':
4085 case 'n':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004086 db.Names.push_back(db.make<NameType>("operator&"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004087 first += 2;
4088 break;
4089 case 'N':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004090 db.Names.push_back(db.make<NameType>("operator&="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004091 first += 2;
4092 break;
4093 case 'S':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004094 db.Names.push_back(db.make<NameType>("operator="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004095 first += 2;
4096 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004097 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004098 break;
4099 case 'c':
4100 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004101 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004102 case 'l':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004103 db.Names.push_back(db.make<NameType>("operator()"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004104 first += 2;
4105 break;
4106 case 'm':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004107 db.Names.push_back(db.make<NameType>("operator,"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004108 first += 2;
4109 break;
4110 case 'o':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004111 db.Names.push_back(db.make<NameType>("operator~"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004112 first += 2;
4113 break;
4114 case 'v':
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004115 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004116 bool TryToParseTemplateArgs = db.TryToParseTemplateArgs;
4117 db.TryToParseTemplateArgs = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004118 const char* t = parse_type(first+2, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004119 db.TryToParseTemplateArgs = TryToParseTemplateArgs;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004120 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004121 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004122 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004123 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004124 db.Names.back() =
4125 db.make<ConversionOperatorType>(db.Names.back());
4126 db.ParsedCtorDtorCV = true;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004127 first = t;
4128 }
4129 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004130 break;
4131 }
4132 break;
4133 case 'd':
4134 switch (first[1])
4135 {
4136 case 'a':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004137 db.Names.push_back(db.make<NameType>("operator delete[]"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004138 first += 2;
4139 break;
4140 case 'e':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004141 db.Names.push_back(db.make<NameType>("operator*"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004142 first += 2;
4143 break;
4144 case 'l':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004145 db.Names.push_back(db.make<NameType>("operator delete"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004146 first += 2;
4147 break;
4148 case 'v':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004149 db.Names.push_back(db.make<NameType>("operator/"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004150 first += 2;
4151 break;
4152 case 'V':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004153 db.Names.push_back(db.make<NameType>("operator/="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004154 first += 2;
4155 break;
4156 }
4157 break;
4158 case 'e':
4159 switch (first[1])
4160 {
4161 case 'o':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004162 db.Names.push_back(db.make<NameType>("operator^"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004163 first += 2;
4164 break;
4165 case 'O':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004166 db.Names.push_back(db.make<NameType>("operator^="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004167 first += 2;
4168 break;
4169 case 'q':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004170 db.Names.push_back(db.make<NameType>("operator=="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004171 first += 2;
4172 break;
4173 }
4174 break;
4175 case 'g':
4176 switch (first[1])
4177 {
4178 case 'e':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004179 db.Names.push_back(db.make<NameType>("operator>="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004180 first += 2;
4181 break;
4182 case 't':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004183 db.Names.push_back(db.make<NameType>("operator>"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004184 first += 2;
4185 break;
4186 }
4187 break;
4188 case 'i':
4189 if (first[1] == 'x')
4190 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004191 db.Names.push_back(db.make<NameType>("operator[]"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004192 first += 2;
4193 }
4194 break;
4195 case 'l':
4196 switch (first[1])
4197 {
4198 case 'e':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004199 db.Names.push_back(db.make<NameType>("operator<="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004200 first += 2;
4201 break;
Howard Hinnantf29757a2014-01-06 23:05:04 +00004202 case 'i':
4203 {
4204 const char* t = parse_source_name(first+2, last, db);
4205 if (t != first+2)
4206 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004207 if (db.Names.empty())
Howard Hinnantf29757a2014-01-06 23:05:04 +00004208 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004209 db.Names.back() =
4210 db.make<LiteralOperator>(db.Names.back());
Howard Hinnantf29757a2014-01-06 23:05:04 +00004211 first = t;
4212 }
4213 }
4214 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004215 case 's':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004216 db.Names.push_back(db.make<NameType>("operator<<"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004217 first += 2;
4218 break;
4219 case 'S':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004220 db.Names.push_back(db.make<NameType>("operator<<="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004221 first += 2;
4222 break;
4223 case 't':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004224 db.Names.push_back(db.make<NameType>("operator<"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004225 first += 2;
4226 break;
4227 }
4228 break;
4229 case 'm':
4230 switch (first[1])
4231 {
4232 case 'i':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004233 db.Names.push_back(db.make<NameType>("operator-"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004234 first += 2;
4235 break;
4236 case 'I':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004237 db.Names.push_back(db.make<NameType>("operator-="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004238 first += 2;
4239 break;
4240 case 'l':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004241 db.Names.push_back(db.make<NameType>("operator*"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004242 first += 2;
4243 break;
4244 case 'L':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004245 db.Names.push_back(db.make<NameType>("operator*="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004246 first += 2;
4247 break;
4248 case 'm':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004249 db.Names.push_back(db.make<NameType>("operator--"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004250 first += 2;
4251 break;
4252 }
4253 break;
4254 case 'n':
4255 switch (first[1])
4256 {
4257 case 'a':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004258 db.Names.push_back(db.make<NameType>("operator new[]"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004259 first += 2;
4260 break;
4261 case 'e':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004262 db.Names.push_back(db.make<NameType>("operator!="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004263 first += 2;
4264 break;
4265 case 'g':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004266 db.Names.push_back(db.make<NameType>("operator-"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004267 first += 2;
4268 break;
4269 case 't':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004270 db.Names.push_back(db.make<NameType>("operator!"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004271 first += 2;
4272 break;
4273 case 'w':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004274 db.Names.push_back(db.make<NameType>("operator new"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004275 first += 2;
4276 break;
4277 }
4278 break;
4279 case 'o':
4280 switch (first[1])
4281 {
4282 case 'o':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004283 db.Names.push_back(db.make<NameType>("operator||"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004284 first += 2;
4285 break;
4286 case 'r':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004287 db.Names.push_back(db.make<NameType>("operator|"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004288 first += 2;
4289 break;
4290 case 'R':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004291 db.Names.push_back(db.make<NameType>("operator|="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004292 first += 2;
4293 break;
4294 }
4295 break;
4296 case 'p':
4297 switch (first[1])
4298 {
4299 case 'm':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004300 db.Names.push_back(db.make<NameType>("operator->*"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004301 first += 2;
4302 break;
4303 case 'l':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004304 db.Names.push_back(db.make<NameType>("operator+"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004305 first += 2;
4306 break;
4307 case 'L':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004308 db.Names.push_back(db.make<NameType>("operator+="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004309 first += 2;
4310 break;
4311 case 'p':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004312 db.Names.push_back(db.make<NameType>("operator++"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004313 first += 2;
4314 break;
4315 case 's':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004316 db.Names.push_back(db.make<NameType>("operator+"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004317 first += 2;
4318 break;
4319 case 't':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004320 db.Names.push_back(db.make<NameType>("operator->"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004321 first += 2;
4322 break;
4323 }
4324 break;
4325 case 'q':
4326 if (first[1] == 'u')
4327 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004328 db.Names.push_back(db.make<NameType>("operator?"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004329 first += 2;
4330 }
4331 break;
4332 case 'r':
4333 switch (first[1])
4334 {
4335 case 'm':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004336 db.Names.push_back(db.make<NameType>("operator%"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004337 first += 2;
4338 break;
4339 case 'M':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004340 db.Names.push_back(db.make<NameType>("operator%="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004341 first += 2;
4342 break;
4343 case 's':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004344 db.Names.push_back(db.make<NameType>("operator>>"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004345 first += 2;
4346 break;
4347 case 'S':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004348 db.Names.push_back(db.make<NameType>("operator>>="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004349 first += 2;
4350 break;
4351 }
4352 break;
4353 case 'v':
4354 if (std::isdigit(first[1]))
4355 {
4356 const char* t = parse_source_name(first+2, last, db);
4357 if (t != first+2)
4358 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004359 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004360 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004361 db.Names.back() =
4362 db.make<ConversionOperatorType>(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004363 first = t;
4364 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004365 }
4366 break;
4367 }
4368 }
Erik Pilkington5bff4122017-11-22 20:38:22 +00004369
4370 if (original_first != first)
4371 first = parse_abi_tag_seq(first, last, db);
4372
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004373 return first;
4374}
4375
Erik Pilkington0024acd2017-07-28 00:43:49 +00004376Node* maybe_change_special_sub_name(Node* inp, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004377{
Erik Pilkington0024acd2017-07-28 00:43:49 +00004378 if (inp->K != Node::KSpecialSubstitution)
4379 return inp;
4380 auto Kind = static_cast<SpecialSubstitution*>(inp)->SSK;
4381 switch (Kind)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004382 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00004383 case SpecialSubKind::string:
4384 case SpecialSubKind::istream:
4385 case SpecialSubKind::ostream:
4386 case SpecialSubKind::iostream:
4387 return db.make<ExpandedSpecialSubstitution>(Kind);
4388 default:
4389 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004390 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00004391 return inp;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004392}
4393
4394// <ctor-dtor-name> ::= C1 # complete object constructor
4395// ::= C2 # base object constructor
4396// ::= C3 # complete object allocating constructor
4397// extension ::= C5 # ?
4398// ::= D0 # deleting destructor
4399// ::= D1 # complete object destructor
4400// ::= D2 # base object destructor
4401// extension ::= D5 # ?
Erik Pilkington5bff4122017-11-22 20:38:22 +00004402// extension ::= <ctor-dtor-name> <abi-tag-seq>
Howard Hinnant6c33e762013-06-17 18:10:34 +00004403const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004404parse_ctor_dtor_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004405{
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004406 if (last-first >= 2 && !db.Names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00004407 {
4408 switch (first[0])
4409 {
4410 case 'C':
4411 switch (first[1])
4412 {
4413 case '1':
4414 case '2':
4415 case '3':
4416 case '5':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004417 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004418 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004419 db.Names.back() =
4420 maybe_change_special_sub_name(db.Names.back(), db);
4421 db.Names.push_back(
4422 db.make<CtorDtorName>(db.Names.back(), false));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004423 first += 2;
Erik Pilkington5bff4122017-11-22 20:38:22 +00004424 first = parse_abi_tag_seq(first, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004425 db.ParsedCtorDtorCV = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004426 break;
4427 }
4428 break;
4429 case 'D':
4430 switch (first[1])
4431 {
4432 case '0':
4433 case '1':
4434 case '2':
4435 case '5':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004436 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004437 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004438 db.Names.push_back(
4439 db.make<CtorDtorName>(db.Names.back(), true));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004440 first += 2;
Erik Pilkington5bff4122017-11-22 20:38:22 +00004441 first = parse_abi_tag_seq(first, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004442 db.ParsedCtorDtorCV = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004443 break;
4444 }
4445 break;
4446 }
4447 }
4448 return first;
4449}
4450
Erik Pilkington5bff4122017-11-22 20:38:22 +00004451// <unnamed-type-name> ::= Ut [<nonnegative number>] _ [<abi-tag-seq>]
Howard Hinnant6c33e762013-06-17 18:10:34 +00004452// ::= <closure-type-name>
4453//
4454// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
4455//
4456// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
Howard Hinnant6c33e762013-06-17 18:10:34 +00004457const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004458parse_unnamed_type_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004459{
4460 if (last - first > 2 && first[0] == 'U')
4461 {
4462 char type = first[1];
4463 switch (type)
4464 {
4465 case 't':
4466 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004467 const char* t0 = first+2;
4468 if (t0 == last)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004469 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004470 StringView count;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004471 if (std::isdigit(*t0))
4472 {
4473 const char* t1 = t0 + 1;
4474 while (t1 != last && std::isdigit(*t1))
4475 ++t1;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004476 count = StringView(t0, t1);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004477 t0 = t1;
4478 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004479 if (t0 == last || *t0 != '_')
Howard Hinnant6c33e762013-06-17 18:10:34 +00004480 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004481 db.Names.push_back(db.make<UnnamedTypeName>(count));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004482 first = t0 + 1;
Erik Pilkington5bff4122017-11-22 20:38:22 +00004483 first = parse_abi_tag_seq(first, last, db);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004484 }
4485 break;
4486 case 'l':
4487 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004488 size_t begin_pos = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004489 const char* t0 = first+2;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004490 NodeArray lambda_params;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004491 if (first[2] == 'v')
4492 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004493 ++t0;
4494 }
4495 else
4496 {
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004497 while (true)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004498 {
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004499 const char* t1 = parse_type(t0, last, db);
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004500 if (t1 == t0)
4501 break;
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004502 t0 = t1;
4503 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004504 if (db.Names.size() < begin_pos)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004505 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004506 lambda_params = db.popTrailingNodeArray(begin_pos);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004507 }
4508 if (t0 == last || *t0 != 'E')
Erik Pilkington0024acd2017-07-28 00:43:49 +00004509 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004510 ++t0;
4511 if (t0 == last)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004512 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004513 StringView count;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004514 if (std::isdigit(*t0))
4515 {
4516 const char* t1 = t0 + 1;
4517 while (t1 != last && std::isdigit(*t1))
4518 ++t1;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004519 count = StringView(t0, t1);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004520 t0 = t1;
4521 }
4522 if (t0 == last || *t0 != '_')
Howard Hinnant6c33e762013-06-17 18:10:34 +00004523 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004524 db.Names.push_back(db.make<LambdaTypeName>(lambda_params, count));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004525 first = t0 + 1;
4526 }
4527 break;
4528 }
4529 }
4530 return first;
4531}
4532
4533// <unqualified-name> ::= <operator-name>
4534// ::= <ctor-dtor-name>
4535// ::= <source-name>
4536// ::= <unnamed-type-name>
4537
Howard Hinnant6c33e762013-06-17 18:10:34 +00004538const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004539parse_unqualified_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004540{
4541 if (first != last)
4542 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004543 const char* t;
4544 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004545 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004546 case 'C':
4547 case 'D':
4548 t = parse_ctor_dtor_name(first, last, db);
4549 if (t != first)
4550 first = t;
4551 break;
4552 case 'U':
4553 t = parse_unnamed_type_name(first, last, db);
4554 if (t != first)
4555 first = t;
4556 break;
4557 case '1':
4558 case '2':
4559 case '3':
4560 case '4':
4561 case '5':
4562 case '6':
4563 case '7':
4564 case '8':
4565 case '9':
4566 t = parse_source_name(first, last, db);
4567 if (t != first)
4568 first = t;
4569 break;
4570 default:
4571 t = parse_operator_name(first, last, db);
4572 if (t != first)
4573 first = t;
4574 break;
4575 };
4576 }
4577 return first;
4578}
4579
4580// <unscoped-name> ::= <unqualified-name>
4581// ::= St <unqualified-name> # ::std::
4582// extension ::= StL<unqualified-name>
4583
Howard Hinnant6c33e762013-06-17 18:10:34 +00004584const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004585parse_unscoped_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004586{
4587 if (last - first >= 2)
4588 {
4589 const char* t0 = first;
4590 bool St = false;
4591 if (first[0] == 'S' && first[1] == 't')
4592 {
4593 t0 += 2;
4594 St = true;
4595 if (t0 != last && *t0 == 'L')
4596 ++t0;
4597 }
4598 const char* t1 = parse_unqualified_name(t0, last, db);
4599 if (t1 != t0)
4600 {
4601 if (St)
Howard Hinnant753a30d2013-12-11 19:44:25 +00004602 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004603 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004604 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004605 db.Names.back() =
4606 db.make<StdQualifiedName>(db.Names.back());
Howard Hinnant753a30d2013-12-11 19:44:25 +00004607 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004608 first = t1;
4609 }
4610 }
4611 return first;
4612}
4613
Howard Hinnant6c33e762013-06-17 18:10:34 +00004614// <template-arg> ::= <type> # type or template
4615// ::= X <expression> E # expression
4616// ::= <expr-primary> # simple expressions
4617// ::= J <template-arg>* E # argument pack
4618// ::= LZ <encoding> E # extension
Howard Hinnant6c33e762013-06-17 18:10:34 +00004619const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004620parse_template_arg(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004621{
4622 if (first != last)
4623 {
4624 const char* t;
4625 switch (*first)
4626 {
4627 case 'X':
4628 t = parse_expression(first+1, last, db);
4629 if (t != first+1)
4630 {
4631 if (t != last && *t == 'E')
4632 first = t+1;
4633 }
4634 break;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004635 case 'J': {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004636 t = first+1;
4637 if (t == last)
4638 return first;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004639 size_t ArgsBegin = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004640 while (*t != 'E')
4641 {
4642 const char* t1 = parse_template_arg(t, last, db);
4643 if (t1 == t)
4644 return first;
4645 t = t1;
4646 }
Erik Pilkington761e6b02018-01-31 20:17:06 +00004647 NodeArray Args = db.popTrailingNodeArray(ArgsBegin);
4648 db.Names.push_back(db.make<TemplateArgumentPack>(Args));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004649 first = t+1;
4650 break;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004651 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004652 case 'L':
4653 // <expr-primary> or LZ <encoding> E
4654 if (first+1 != last && first[1] == 'Z')
4655 {
4656 t = parse_encoding(first+2, last, db);
4657 if (t != first+2 && t != last && *t == 'E')
4658 first = t+1;
4659 }
4660 else
4661 first = parse_expr_primary(first, last, db);
4662 break;
4663 default:
4664 // <type>
4665 first = parse_type(first, last, db);
4666 break;
4667 }
4668 }
4669 return first;
4670}
4671
4672// <template-args> ::= I <template-arg>* E
4673// extension, the abi says <template-arg>+
Howard Hinnant6c33e762013-06-17 18:10:34 +00004674const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004675parse_template_args(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004676{
4677 if (last - first >= 2 && *first == 'I')
4678 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004679 if (db.TagTemplates)
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004680 db.TemplateParams.clear();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004681 const char* t = first+1;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004682 size_t begin_idx = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004683 while (*t != 'E')
4684 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004685 if (db.TagTemplates)
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004686 {
4687 auto TmpParams = std::move(db.TemplateParams);
4688 size_t k0 = db.Names.size();
4689 const char* t1 = parse_template_arg(t, last, db);
4690 size_t k1 = db.Names.size();
4691 db.TemplateParams = std::move(TmpParams);
Erik Pilkington761e6b02018-01-31 20:17:06 +00004692 if (t1 == t || t1 == last || k0 + 1 != k1)
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004693 return first;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004694 Node *TableEntry = db.Names.back();
4695 if (TableEntry->getKind() == Node::KTemplateArgumentPack)
4696 TableEntry = db.make<ParameterPack>(
4697 static_cast<TemplateArgumentPack*>(TableEntry)
4698 ->getElements());
4699 db.TemplateParams.push_back(TableEntry);
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004700 t = t1;
4701 continue;
4702 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004703 size_t k0 = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004704 const char* t1 = parse_template_arg(t, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004705 size_t k1 = db.Names.size();
Erik Pilkington0024acd2017-07-28 00:43:49 +00004706 if (t1 == t || t1 == last || k0 > k1)
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004707 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004708 t = t1;
4709 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004710 if (begin_idx > db.Names.size())
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004711 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004712 first = t + 1;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004713 auto *tp = db.make<TemplateArgs>(
Erik Pilkington0024acd2017-07-28 00:43:49 +00004714 db.popTrailingNodeArray(begin_idx));
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004715 db.Names.push_back(tp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004716 }
4717 return first;
4718}
4719
Erik Pilkington0024acd2017-07-28 00:43:49 +00004720// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
4721// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
Howard Hinnant6c33e762013-06-17 18:10:34 +00004722//
4723// <prefix> ::= <prefix> <unqualified-name>
4724// ::= <template-prefix> <template-args>
4725// ::= <template-param>
4726// ::= <decltype>
4727// ::= # empty
4728// ::= <substitution>
4729// ::= <prefix> <data-member-prefix>
4730// extension ::= L
4731//
4732// <template-prefix> ::= <prefix> <template unqualified-name>
4733// ::= <template-param>
4734// ::= <substitution>
4735
Howard Hinnant6c33e762013-06-17 18:10:34 +00004736const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004737parse_nested_name(const char* first, const char* last, Db& db,
Richard Smith24ecd092014-05-12 18:44:13 +00004738 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004739{
4740 if (first != last && *first == 'N')
4741 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00004742 Qualifiers cv;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004743 const char* t0 = parse_cv_qualifiers(first+1, last, cv);
4744 if (t0 == last)
4745 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004746 db.RefQuals = FrefQualNone;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004747 if (*t0 == 'R')
4748 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004749 db.RefQuals = FrefQualLValue;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004750 ++t0;
4751 }
4752 else if (*t0 == 'O')
4753 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004754 db.RefQuals = FrefQualRValue;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004755 ++t0;
4756 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004757 db.Names.push_back(db.make<EmptyName>());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004758 if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't')
4759 {
4760 t0 += 2;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004761 db.Names.back() = db.make<NameType>("std");
Howard Hinnant6c33e762013-06-17 18:10:34 +00004762 }
4763 if (t0 == last)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004764 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004765 bool pop_subs = false;
Richard Smith24ecd092014-05-12 18:44:13 +00004766 bool component_ends_with_template_args = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004767 while (*t0 != 'E')
4768 {
Richard Smith24ecd092014-05-12 18:44:13 +00004769 component_ends_with_template_args = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004770 const char* t1;
4771 switch (*t0)
4772 {
4773 case 'S':
4774 if (t0 + 1 != last && t0[1] == 't')
4775 goto do_parse_unqualified_name;
4776 t1 = parse_substitution(t0, last, db);
4777 if (t1 != t0 && t1 != last)
4778 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004779 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004780 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004781 auto name = db.Names.back();
4782 db.Names.pop_back();
4783 if (db.Names.back()->K != Node::KEmptyName)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004784 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004785 db.Names.back() = db.make<QualifiedName>(
4786 db.Names.back(), name);
Erik Pilkington761e6b02018-01-31 20:17:06 +00004787 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004788 }
4789 else
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004790 db.Names.back() = name;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004791 pop_subs = true;
4792 t0 = t1;
4793 }
4794 else
4795 return first;
4796 break;
4797 case 'T':
4798 t1 = parse_template_param(t0, last, db);
4799 if (t1 != t0 && t1 != last)
4800 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004801 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004802 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004803 auto name = db.Names.back();
4804 db.Names.pop_back();
4805 if (db.Names.back()->K != Node::KEmptyName)
4806 db.Names.back() =
4807 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004808 else
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004809 db.Names.back() = name;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004810 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004811 pop_subs = true;
4812 t0 = t1;
4813 }
4814 else
4815 return first;
4816 break;
4817 case 'D':
4818 if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')
4819 goto do_parse_unqualified_name;
4820 t1 = parse_decltype(t0, last, db);
4821 if (t1 != t0 && t1 != last)
4822 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004823 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004824 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004825 auto name = db.Names.back();
4826 db.Names.pop_back();
4827 if (db.Names.back()->K != Node::KEmptyName)
4828 db.Names.back() =
4829 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004830 else
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004831 db.Names.back() = name;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004832 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004833 pop_subs = true;
4834 t0 = t1;
4835 }
4836 else
4837 return first;
4838 break;
4839 case 'I':
4840 t1 = parse_template_args(t0, last, db);
4841 if (t1 != t0 && t1 != last)
4842 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004843 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004844 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004845 auto name = db.Names.back();
4846 db.Names.pop_back();
4847 db.Names.back() = db.make<NameWithTemplateArgs>(
4848 db.Names.back(), name);
Erik Pilkington761e6b02018-01-31 20:17:06 +00004849 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004850 t0 = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00004851 component_ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004852 }
4853 else
4854 return first;
4855 break;
4856 case 'L':
4857 if (++t0 == last)
4858 return first;
4859 break;
4860 default:
4861 do_parse_unqualified_name:
4862 t1 = parse_unqualified_name(t0, last, db);
4863 if (t1 != t0 && t1 != last)
4864 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004865 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004866 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004867 auto name = db.Names.back();
4868 db.Names.pop_back();
4869 if (db.Names.back()->K != Node::KEmptyName)
4870 db.Names.back() =
4871 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004872 else
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004873 db.Names.back() = name;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004874 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004875 pop_subs = true;
4876 t0 = t1;
4877 }
4878 else
4879 return first;
4880 }
4881 }
4882 first = t0 + 1;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004883 db.CV = cv;
4884 if (pop_subs && !db.Subs.empty())
Erik Pilkington761e6b02018-01-31 20:17:06 +00004885 db.Subs.pop_back();
Richard Smith24ecd092014-05-12 18:44:13 +00004886 if (ends_with_template_args)
4887 *ends_with_template_args = component_ends_with_template_args;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004888 }
4889 return first;
4890}
4891
4892// <discriminator> := _ <non-negative number> # when number < 10
4893// := __ <non-negative number> _ # when number >= 10
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00004894// extension := decimal-digit+ # at the end of string
Howard Hinnant6c33e762013-06-17 18:10:34 +00004895
4896const char*
4897parse_discriminator(const char* first, const char* last)
4898{
4899 // parse but ignore discriminator
4900 if (first != last)
4901 {
4902 if (*first == '_')
4903 {
4904 const char* t1 = first+1;
4905 if (t1 != last)
4906 {
4907 if (std::isdigit(*t1))
4908 first = t1+1;
4909 else if (*t1 == '_')
4910 {
4911 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
4912 ;
4913 if (t1 != last && *t1 == '_')
4914 first = t1 + 1;
4915 }
4916 }
4917 }
4918 else if (std::isdigit(*first))
4919 {
4920 const char* t1 = first+1;
4921 for (; t1 != last && std::isdigit(*t1); ++t1)
4922 ;
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00004923 if (t1 == last)
4924 first = last;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004925 }
4926 }
4927 return first;
4928}
4929
4930// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
4931// := Z <function encoding> E s [<discriminator>]
4932// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
4933
Howard Hinnant6c33e762013-06-17 18:10:34 +00004934const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004935parse_local_name(const char* first, const char* last, Db& db,
Richard Smith24ecd092014-05-12 18:44:13 +00004936 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004937{
4938 if (first != last && *first == 'Z')
4939 {
4940 const char* t = parse_encoding(first+1, last, db);
4941 if (t != first+1 && t != last && *t == 'E' && ++t != last)
4942 {
4943 switch (*t)
4944 {
4945 case 's':
4946 first = parse_discriminator(t+1, last);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004947 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004948 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004949 db.Names.back() = db.make<QualifiedName>(
4950 db.Names.back(), db.make<NameType>("string literal"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004951 break;
4952 case 'd':
4953 if (++t != last)
4954 {
4955 const char* t1 = parse_number(t, last);
4956 if (t1 != last && *t1 == '_')
4957 {
4958 t = t1 + 1;
Richard Smith24ecd092014-05-12 18:44:13 +00004959 t1 = parse_name(t, last, db,
4960 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004961 if (t1 != t)
4962 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004963 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00004964 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004965 auto name = db.Names.back();
4966 db.Names.pop_back();
4967 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004968 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004969 db.Names.back() =
4970 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004971 first = t1;
4972 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004973 else if (!db.Names.empty())
4974 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004975 }
4976 }
4977 break;
4978 default:
4979 {
Richard Smith24ecd092014-05-12 18:44:13 +00004980 const char* t1 = parse_name(t, last, db,
4981 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004982 if (t1 != t)
4983 {
4984 // parse but ignore discriminator
4985 first = parse_discriminator(t1, last);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004986 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00004987 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004988 auto name = db.Names.back();
4989 db.Names.pop_back();
4990 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004991 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004992 db.Names.back() =
4993 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004994 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004995 else if (!db.Names.empty())
4996 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004997 }
4998 break;
4999 }
5000 }
5001 }
5002 return first;
5003}
5004
5005// <name> ::= <nested-name> // N
5006// ::= <local-name> # See Scope Encoding below // Z
5007// ::= <unscoped-template-name> <template-args>
5008// ::= <unscoped-name>
5009
5010// <unscoped-template-name> ::= <unscoped-name>
5011// ::= <substitution>
5012
Howard Hinnant6c33e762013-06-17 18:10:34 +00005013const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005014parse_name(const char* first, const char* last, Db& db,
Richard Smith24ecd092014-05-12 18:44:13 +00005015 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005016{
5017 if (last - first >= 2)
5018 {
5019 const char* t0 = first;
5020 // extension: ignore L here
5021 if (*t0 == 'L')
5022 ++t0;
5023 switch (*t0)
5024 {
5025 case 'N':
5026 {
Richard Smith24ecd092014-05-12 18:44:13 +00005027 const char* t1 = parse_nested_name(t0, last, db,
5028 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005029 if (t1 != t0)
5030 first = t1;
5031 break;
5032 }
5033 case 'Z':
5034 {
Richard Smith24ecd092014-05-12 18:44:13 +00005035 const char* t1 = parse_local_name(t0, last, db,
5036 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005037 if (t1 != t0)
5038 first = t1;
5039 break;
5040 }
5041 default:
5042 {
5043 const char* t1 = parse_unscoped_name(t0, last, db);
5044 if (t1 != t0)
5045 {
5046 if (t1 != last && *t1 == 'I') // <unscoped-template-name> <template-args>
5047 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005048 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005049 return first;
Erik Pilkington761e6b02018-01-31 20:17:06 +00005050 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005051 t0 = t1;
5052 t1 = parse_template_args(t0, last, db);
5053 if (t1 != t0)
5054 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005055 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00005056 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005057 auto tmp = db.Names.back();
5058 db.Names.pop_back();
5059 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005060 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005061 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005062 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005063 db.Names.back(), tmp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005064 first = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00005065 if (ends_with_template_args)
5066 *ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005067 }
5068 }
5069 else // <unscoped-name>
5070 first = t1;
5071 }
5072 else
5073 { // try <substitution> <template-args>
5074 t1 = parse_substitution(t0, last, db);
Howard Hinnantb4033ff2013-06-20 01:55:07 +00005075 if (t1 != t0 && t1 != last && *t1 == 'I')
Howard Hinnant6c33e762013-06-17 18:10:34 +00005076 {
5077 t0 = t1;
5078 t1 = parse_template_args(t0, last, db);
5079 if (t1 != t0)
5080 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005081 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00005082 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005083 auto tmp = db.Names.back();
5084 db.Names.pop_back();
5085 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005086 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005087 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005088 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005089 db.Names.back(), tmp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005090 first = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00005091 if (ends_with_template_args)
5092 *ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005093 }
5094 }
5095 }
5096 break;
5097 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005098 }
5099 }
5100 return first;
5101}
5102
5103// <call-offset> ::= h <nv-offset> _
5104// ::= v <v-offset> _
5105//
5106// <nv-offset> ::= <offset number>
5107// # non-virtual base override
5108//
5109// <v-offset> ::= <offset number> _ <virtual offset number>
5110// # virtual base override, with vcall offset
5111
5112const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00005113parse_call_offset(const char* first, const char* last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005114{
5115 if (first != last)
5116 {
5117 switch (*first)
5118 {
5119 case 'h':
5120 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005121 const char* t = parse_number(first + 1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005122 if (t != first + 1 && t != last && *t == '_')
5123 first = t + 1;
5124 }
5125 break;
5126 case 'v':
5127 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005128 const char* t = parse_number(first + 1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005129 if (t != first + 1 && t != last && *t == '_')
5130 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005131 const char* t2 = parse_number(++t, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005132 if (t2 != t && t2 != last && *t2 == '_')
5133 first = t2 + 1;
5134 }
5135 }
5136 break;
5137 }
5138 }
5139 return first;
5140}
5141
5142// <special-name> ::= TV <type> # virtual table
5143// ::= TT <type> # VTT structure (construction vtable index)
5144// ::= TI <type> # typeinfo structure
5145// ::= TS <type> # typeinfo name (null-terminated byte string)
5146// ::= Tc <call-offset> <call-offset> <base encoding>
5147// # base is the nominal target function of thunk
5148// # first call-offset is 'this' adjustment
5149// # second call-offset is result adjustment
5150// ::= T <call-offset> <base encoding>
5151// # base is the nominal target function of thunk
5152// ::= GV <object name> # Guard variable for one-time initialization
5153// # No <type>
David Bozierc2fa8f12017-01-31 15:18:56 +00005154// ::= TW <object name> # Thread-local wrapper
5155// ::= TH <object name> # Thread-local initialization
Howard Hinnantf2700352011-12-09 20:07:56 +00005156// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
5157// extension ::= GR <object name> # reference temporary for object
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005158
5159const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005160parse_special_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005161{
5162 if (last - first > 2)
5163 {
5164 const char* t;
5165 switch (*first)
5166 {
5167 case 'T':
5168 switch (first[1])
5169 {
5170 case 'V':
5171 // TV <type> # virtual table
Howard Hinnant6c33e762013-06-17 18:10:34 +00005172 t = parse_type(first+2, last, db);
5173 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005174 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005175 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005176 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005177 db.Names.back() =
5178 db.make<SpecialName>("vtable for ", db.Names.back());
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005179 first = t;
5180 }
5181 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005182 case 'T':
5183 // TT <type> # VTT structure (construction vtable index)
5184 t = parse_type(first+2, last, db);
Howard Hinnantf2700352011-12-09 20:07:56 +00005185 if (t != first+2)
5186 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005187 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005188 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005189 db.Names.back() =
5190 db.make<SpecialName>("VTT for ", db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005191 first = t;
5192 }
5193 break;
5194 case 'I':
5195 // TI <type> # typeinfo structure
5196 t = parse_type(first+2, last, db);
5197 if (t != first+2)
5198 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005199 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005200 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005201 db.Names.back() =
5202 db.make<SpecialName>("typeinfo for ", db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005203 first = t;
5204 }
5205 break;
5206 case 'S':
5207 // TS <type> # typeinfo name (null-terminated byte string)
5208 t = parse_type(first+2, last, db);
5209 if (t != first+2)
5210 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005211 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005212 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005213 db.Names.back() =
5214 db.make<SpecialName>("typeinfo name for ", db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005215 first = t;
5216 }
5217 break;
5218 case 'c':
5219 // Tc <call-offset> <call-offset> <base encoding>
5220 {
5221 const char* t0 = parse_call_offset(first+2, last);
5222 if (t0 == first+2)
5223 break;
5224 const char* t1 = parse_call_offset(t0, last);
5225 if (t1 == t0)
5226 break;
5227 t = parse_encoding(t1, last, db);
5228 if (t != t1)
5229 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005230 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005231 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005232 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005233 db.make<SpecialName>("covariant return thunk to ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005234 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005235 first = t;
5236 }
5237 }
5238 break;
5239 case 'C':
5240 // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
5241 t = parse_type(first+2, last, db);
5242 if (t != first+2)
5243 {
5244 const char* t0 = parse_number(t, last);
Howard Hinnantf2700352011-12-09 20:07:56 +00005245 if (t0 != t && t0 != last && *t0 == '_')
5246 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005247 const char* t1 = parse_type(++t0, last, db);
Howard Hinnantf2700352011-12-09 20:07:56 +00005248 if (t1 != t0)
5249 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005250 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00005251 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005252 auto left = db.Names.back();
5253 db.Names.pop_back();
5254 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005255 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005256 db.Names.back() = db.make<CtorVtableSpecialName>(
5257 left, db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005258 first = t1;
Howard Hinnantf2700352011-12-09 20:07:56 +00005259 }
5260 }
5261 }
5262 break;
David Bozierc2fa8f12017-01-31 15:18:56 +00005263 case 'W':
5264 // TW <object name> # Thread-local wrapper
5265 t = parse_name(first + 2, last, db);
5266 if (t != first + 2)
5267 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005268 if (db.Names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005269 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005270 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005271 db.make<SpecialName>("thread-local wrapper routine for ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005272 db.Names.back());
David Bozierc2fa8f12017-01-31 15:18:56 +00005273 first = t;
5274 }
5275 break;
5276 case 'H':
5277 //TH <object name> # Thread-local initialization
5278 t = parse_name(first + 2, last, db);
5279 if (t != first + 2)
5280 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005281 if (db.Names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005282 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005283 db.Names.back() = db.make<SpecialName>(
5284 "thread-local initialization routine for ", db.Names.back());
David Bozierc2fa8f12017-01-31 15:18:56 +00005285 first = t;
5286 }
5287 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005288 default:
5289 // T <call-offset> <base encoding>
5290 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005291 const char* t0 = parse_call_offset(first+1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005292 if (t0 == first+1)
5293 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005294 t = parse_encoding(t0, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005295 if (t != t0)
5296 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005297 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005298 return first;
Marshall Clowfdccce62015-10-12 20:45:05 +00005299 if (first[1] == 'v')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005300 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005301 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005302 db.make<SpecialName>("virtual thunk to ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005303 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005304 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005305 }
5306 else
5307 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005308 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005309 db.make<SpecialName>("non-virtual thunk to ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005310 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005311 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005312 }
5313 }
5314 }
5315 break;
5316 }
5317 break;
5318 case 'G':
Howard Hinnantf2700352011-12-09 20:07:56 +00005319 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005320 {
Howard Hinnantf2700352011-12-09 20:07:56 +00005321 case 'V':
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005322 // GV <object name> # Guard variable for one-time initialization
Howard Hinnant6c33e762013-06-17 18:10:34 +00005323 t = parse_name(first+2, last, db);
5324 if (t != first+2)
5325 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005326 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005327 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005328 db.Names.back() =
5329 db.make<SpecialName>("guard variable for ", db.Names.back());
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005330 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005331 }
Howard Hinnantf2700352011-12-09 20:07:56 +00005332 break;
5333 case 'R':
5334 // extension ::= GR <object name> # reference temporary for object
Howard Hinnant6c33e762013-06-17 18:10:34 +00005335 t = parse_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005336 if (t != first+2)
5337 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005338 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005339 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005340 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005341 db.make<SpecialName>("reference temporary for ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005342 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005343 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005344 }
5345 break;
5346 }
5347 break;
5348 }
5349 }
5350 return first;
5351}
5352
Howard Hinnant753a30d2013-12-11 19:44:25 +00005353template <class T>
5354class save_value
5355{
5356 T& restore_;
5357 T original_value_;
5358public:
5359 save_value(T& restore)
5360 : restore_(restore),
5361 original_value_(restore)
5362 {}
5363
5364 ~save_value()
5365 {
5366 restore_ = std::move(original_value_);
5367 }
5368
5369 save_value(const save_value&) = delete;
5370 save_value& operator=(const save_value&) = delete;
5371};
5372
Howard Hinnant6c33e762013-06-17 18:10:34 +00005373// <encoding> ::= <function name> <bare-function-type>
5374// ::= <data name>
5375// ::= <special-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005376
5377const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005378parse_encoding(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005379{
5380 if (first != last)
5381 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005382 save_value<decltype(db.EncodingDepth)> su(db.EncodingDepth);
5383 ++db.EncodingDepth;
5384 save_value<decltype(db.TagTemplates)> sb(db.TagTemplates);
5385 if (db.EncodingDepth > 1)
5386 db.TagTemplates = true;
5387 save_value<decltype(db.ParsedCtorDtorCV)> sp(db.ParsedCtorDtorCV);
5388 db.ParsedCtorDtorCV = false;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005389 switch (*first)
5390 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005391 case 'G':
5392 case 'T':
5393 first = parse_special_name(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005394 break;
5395 default:
Howard Hinnant6c33e762013-06-17 18:10:34 +00005396 {
Richard Smith24ecd092014-05-12 18:44:13 +00005397 bool ends_with_template_args = false;
5398 const char* t = parse_name(first, last, db,
5399 &ends_with_template_args);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005400 if (db.Names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005401 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005402 Qualifiers cv = db.CV;
5403 FunctionRefQual ref = db.RefQuals;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005404 if (t != first)
Howard Hinnantab87dcf2011-12-15 20:02:15 +00005405 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005406 if (t != last && *t != 'E' && *t != '.')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005407 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005408 save_value<bool> sb2(db.TagTemplates);
5409 db.TagTemplates = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005410 const char* t2;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005411 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005412 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005413 if (!db.Names.back())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005414 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005415 Node* return_type = nullptr;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005416 if (!db.ParsedCtorDtorCV && ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005417 {
5418 t2 = parse_type(t, last, db);
5419 if (t2 == t)
5420 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005421 if (db.Names.size() < 1)
Howard Hinnant753a30d2013-12-11 19:44:25 +00005422 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005423 return_type = db.Names.back();
5424 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005425 t = t2;
5426 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005427
5428 Node* result = nullptr;
5429
Howard Hinnant6c33e762013-06-17 18:10:34 +00005430 if (t != last && *t == 'v')
5431 {
5432 ++t;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005433 if (db.Names.empty())
Erik Pilkingtonb9008222017-08-01 02:38:41 +00005434 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005435 Node* name = db.Names.back();
5436 db.Names.pop_back();
Erik Pilkington761e6b02018-01-31 20:17:06 +00005437 result = db.make<FunctionEncoding>(
Erik Pilkington0024acd2017-07-28 00:43:49 +00005438 return_type, name, NodeArray());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005439 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005440 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005441 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005442 size_t params_begin = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005443 while (true)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005444 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005445 t2 = parse_type(t, last, db);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005446 if (t2 == t)
5447 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005448 t = t2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005449 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005450 if (db.Names.size() < params_begin)
Erik Pilkington0024acd2017-07-28 00:43:49 +00005451 return first;
5452 NodeArray params =
5453 db.popTrailingNodeArray(params_begin);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005454 if (db.Names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005455 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005456 Node* name = db.Names.back();
5457 db.Names.pop_back();
Erik Pilkington761e6b02018-01-31 20:17:06 +00005458 result = db.make<FunctionEncoding>(
Erik Pilkington0024acd2017-07-28 00:43:49 +00005459 return_type, name, params);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005460 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005461 if (ref != FrefQualNone)
5462 result = db.make<FunctionRefQualType>(result, ref);
5463 if (cv != QualNone)
5464 result = db.make<FunctionQualType>(result, cv);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005465 db.Names.push_back(result);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005466 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005467 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005468 else
5469 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005470 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005471 break;
5472 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005473 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005474 }
5475 return first;
5476}
5477
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005478// _block_invoke
5479// _block_invoke<decimal-digit>+
5480// _block_invoke_<decimal-digit>+
5481
5482const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005483parse_block_invoke(const char* first, const char* last, Db& db)
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005484{
5485 if (last - first >= 13)
5486 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005487 // FIXME: strcmp?
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005488 const char test[] = "_block_invoke";
5489 const char* t = first;
5490 for (int i = 0; i < 13; ++i, ++t)
5491 {
5492 if (*t != test[i])
5493 return first;
5494 }
5495 if (t != last)
5496 {
5497 if (*t == '_')
5498 {
5499 // must have at least 1 decimal digit
Howard Hinnant6c33e762013-06-17 18:10:34 +00005500 if (++t == last || !std::isdigit(*t))
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005501 return first;
5502 ++t;
5503 }
5504 // parse zero or more digits
5505 while (t != last && isdigit(*t))
5506 ++t;
5507 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005508 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005509 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005510 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005511 db.make<SpecialName>("invocation function for block in ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005512 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005513 first = t;
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005514 }
5515 return first;
5516}
5517
Howard Hinnant6c33e762013-06-17 18:10:34 +00005518// extension
5519// <dot-suffix> := .<anything and everything>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005520
5521const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005522parse_dot_suffix(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005523{
Howard Hinnant6c33e762013-06-17 18:10:34 +00005524 if (first != last && *first == '.')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005525 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005526 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005527 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005528 db.Names.back() =
5529 db.make<DotSuffix>(db.Names.back(), StringView(first, last));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005530 first = last;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005531 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005532 return first;
5533}
5534
Erik Pilkington761e6b02018-01-31 20:17:06 +00005535enum {
5536 unknown_error = -4,
5537 invalid_args = -3,
5538 invalid_mangled_name,
5539 memory_alloc_failure,
5540 success
5541};
5542
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005543// <block-involcaton-function> ___Z<encoding>_block_invoke
5544// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+
5545// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005546// <mangled-name> ::= _Z<encoding>
5547// ::= <type>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005548void
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005549demangle(const char* first, const char* last, Db& db, int& status)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005550{
Howard Hinnanteb8d46c2013-06-23 17:14:35 +00005551 if (first >= last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005552 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005553 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005554 return;
5555 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005556 if (*first == '_')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005557 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005558 if (last - first >= 4)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005559 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005560 if (first[1] == 'Z')
5561 {
5562 const char* t = parse_encoding(first+2, last, db);
5563 if (t != first+2 && t != last && *t == '.')
5564 t = parse_dot_suffix(t, last, db);
5565 if (t != last)
5566 status = invalid_mangled_name;
5567 }
5568 else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z')
5569 {
5570 const char* t = parse_encoding(first+4, last, db);
5571 if (t != first+4 && t != last)
5572 {
5573 const char* t1 = parse_block_invoke(t, last, db);
5574 if (t1 != last)
5575 status = invalid_mangled_name;
5576 }
5577 else
5578 status = invalid_mangled_name;
5579 }
5580 else
5581 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005582 }
5583 else
Howard Hinnant6c33e762013-06-17 18:10:34 +00005584 status = invalid_mangled_name;
5585 }
5586 else
5587 {
5588 const char* t = parse_type(first, last, db);
5589 if (t != last)
5590 status = invalid_mangled_name;
5591 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005592 if (status == success && db.Names.empty())
Howard Hinnanteb8d46c2013-06-23 17:14:35 +00005593 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005594}
5595
Howard Hinnant6c33e762013-06-17 18:10:34 +00005596} // unnamed namespace
5597
Erik Pilkington761e6b02018-01-31 20:17:06 +00005598
5599namespace __cxxabiv1 {
Saleem Abdulrasoolb4ec5792015-12-04 02:14:58 +00005600extern "C" _LIBCXXABI_FUNC_VIS char *
Saleem Abdulrasool77a304b2015-12-04 02:14:41 +00005601__cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status) {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005602 if (mangled_name == nullptr || (buf != nullptr && n == nullptr))
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005603 {
5604 if (status)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005605 *status = invalid_args;
5606 return nullptr;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005607 }
Saleem Abdulrasool8cfa5a32016-11-14 01:55:54 +00005608
Howard Hinnant8ad6a222013-07-26 22:14:53 +00005609 size_t internal_size = buf != nullptr ? *n : 0;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00005610 Db db;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005611 int internal_status = success;
Jonathan Roelofs0cbb1da2017-01-18 18:12:39 +00005612 size_t len = std::strlen(mangled_name);
Howard Hinnantb2d1f942013-06-23 19:52:45 +00005613 demangle(mangled_name, mangled_name + len, db,
Howard Hinnant6c33e762013-06-17 18:10:34 +00005614 internal_status);
Erik Pilkington0024acd2017-07-28 00:43:49 +00005615
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005616 if (internal_status == success && db.FixForwardReferences &&
Erik Pilkingtonba34a242017-08-09 21:30:57 +00005617 !db.TemplateParams.empty())
Howard Hinnantb2d1f942013-06-23 19:52:45 +00005618 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005619 db.FixForwardReferences = false;
5620 db.TagTemplates = false;
5621 db.Names.clear();
5622 db.Subs.clear();
Howard Hinnantb2d1f942013-06-23 19:52:45 +00005623 demangle(mangled_name, mangled_name + len, db, internal_status);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005624 if (db.FixForwardReferences)
Howard Hinnantb2d1f942013-06-23 19:52:45 +00005625 internal_status = invalid_mangled_name;
5626 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005627
Erik Pilkington761e6b02018-01-31 20:17:06 +00005628 if (internal_status == success &&
5629 db.Names.back()->containsUnexpandedParameterPack())
5630 internal_status = invalid_mangled_name;
5631
Howard Hinnant6c33e762013-06-17 18:10:34 +00005632 if (internal_status == success)
5633 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005634 if (!buf)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005635 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005636 internal_size = 1024;
5637 buf = static_cast<char*>(std::malloc(internal_size));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005638 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005639
5640 if (buf)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005641 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005642 OutputStream s(buf, internal_size);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005643 db.Names.back()->print(s);
Erik Pilkington0024acd2017-07-28 00:43:49 +00005644 s += '\0';
5645 if (n) *n = s.getCurrentPosition();
5646 buf = s.getBuffer();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005647 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005648 else
5649 internal_status = memory_alloc_failure;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005650 }
5651 else
5652 buf = nullptr;
5653 if (status)
5654 *status = internal_status;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005655 return buf;
5656}
Howard Hinnant6c33e762013-06-17 18:10:34 +00005657} // __cxxabiv1