blob: 01724ccb347056014019b180cb7a95fb763df188 [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,
168 KNameType,
Erik Pilkington5bff4122017-11-22 20:38:22 +0000169 KAbiTagAttr,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000170 KObjCProtoName,
171 KPointerType,
172 KLValueReferenceType,
173 KRValueReferenceType,
174 KPointerToMemberType,
175 KArrayType,
176 KFunctionType,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000177 KFunctionEncoding,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000178 KFunctionQualType,
179 KFunctionRefQualType,
180 KLiteralOperator,
181 KSpecialName,
182 KCtorVtableSpecialName,
183 KQualifiedName,
184 KEmptyName,
185 KVectorType,
Erik Pilkington761e6b02018-01-31 20:17:06 +0000186 KParameterPack,
187 KTemplateArgumentPack,
188 KParameterPackExpansion,
189 KTemplateArgs,
Erik Pilkington0024acd2017-07-28 00:43:49 +0000190 KNameWithTemplateArgs,
191 KGlobalQualifiedName,
192 KStdQualifiedName,
193 KExpandedSpecialSubstitution,
194 KSpecialSubstitution,
195 KCtorDtorName,
196 KDtorName,
197 KUnnamedTypeName,
198 KLambdaTypeName,
199 KExpr,
200 };
201
Erik Pilkington761e6b02018-01-31 20:17:06 +0000202 static constexpr unsigned NoParameterPack =
203 std::numeric_limits<unsigned>::max();
204 unsigned ParameterPackSize = NoParameterPack;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000205
Erik Pilkington761e6b02018-01-31 20:17:06 +0000206 Kind K;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000207
Erik Pilkington761e6b02018-01-31 20:17:06 +0000208 /// Three-way bool to track a cached value. Unknown is possible if this node
209 /// has an unexpanded parameter pack below it that may affect this cache.
210 enum class Cache : unsigned char { Yes, No, Unknown, };
Erik Pilkington0024acd2017-07-28 00:43:49 +0000211
Erik Pilkington761e6b02018-01-31 20:17:06 +0000212 /// Tracks if this node has a component on its right side, in which case we
213 /// need to call printRight.
214 Cache RHSComponentCache;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000215
Erik Pilkington761e6b02018-01-31 20:17:06 +0000216 /// Track if this node is a (possibly qualified) array type. This can affect
217 /// how we format the output string.
218 Cache ArrayCache;
219
220 /// Track if this node is a (possibly qualified) function type. This can
221 /// affect how we format the output string.
222 Cache FunctionCache;
223
224 Node(Kind K_, unsigned ParameterPackSize_ = NoParameterPack,
225 Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No,
226 Cache FunctionCache_ = Cache::No)
227 : ParameterPackSize(ParameterPackSize_), K(K_),
228 RHSComponentCache(RHSComponentCache_), ArrayCache(ArrayCache_),
229 FunctionCache(FunctionCache_) {}
230
231 bool containsUnexpandedParameterPack() const {
232 return ParameterPackSize != NoParameterPack;
233 }
234
235 bool hasRHSComponent(OutputStream &S) const {
236 if (RHSComponentCache != Cache::Unknown)
237 return RHSComponentCache == Cache::Yes;
238 return hasRHSComponentSlow(S);
239 }
240
241 bool hasArray(OutputStream &S) const {
242 if (ArrayCache != Cache::Unknown)
243 return ArrayCache == Cache::Yes;
244 return hasArraySlow(S);
245 }
246
247 bool hasFunction(OutputStream &S) const {
248 if (FunctionCache != Cache::Unknown)
249 return FunctionCache == Cache::Yes;
250 return hasFunctionSlow(S);
251 }
252
253 Kind getKind() const { return K; }
254
255 virtual bool hasRHSComponentSlow(OutputStream &) const { return false; }
256 virtual bool hasArraySlow(OutputStream &) const { return false; }
257 virtual bool hasFunctionSlow(OutputStream &) const { return false; }
258
259 /// If this node is a pack expansion that expands to 0 elements. This can have
260 /// an effect on how we should format the output.
261 bool isEmptyPackExpansion() const;
262
263 void print(OutputStream &S) const {
264 printLeft(S);
265 if (RHSComponentCache != Cache::No)
266 printRight(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000267 }
268
269 // Print the "left" side of this Node into OutputStream.
270 virtual void printLeft(OutputStream &) const = 0;
271
272 // Print the "right". This distinction is necessary to represent C++ types
273 // that appear on the RHS of their subtype, such as arrays or functions.
274 // Since most types don't have such a component, provide a default
275 // implemenation.
276 virtual void printRight(OutputStream &) const {}
277
278 virtual StringView getBaseName() const { return StringView(); }
279
280 // Silence compiler warnings, this dtor will never be called.
281 virtual ~Node() = default;
Erik Pilkington761e6b02018-01-31 20:17:06 +0000282
283#ifndef NDEBUG
284 DUMP_METHOD void dump() const {
285 char *Buffer = static_cast<char*>(std::malloc(1024));
286 OutputStream S(Buffer, 1024);
287 print(S);
288 S += '\0';
289 printf("Symbol dump for %p: %s\n", (const void*)this, S.getBuffer());
290 std::free(S.getBuffer());
291 }
292#endif
Erik Pilkington0024acd2017-07-28 00:43:49 +0000293};
294
295class NodeArray {
296 Node **Elements;
297 size_t NumElements;
298
299public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000300 NodeArray() : Elements(nullptr), NumElements(0) {}
Erik Pilkington414f1a52017-08-09 22:45:35 +0000301 NodeArray(Node **Elements_, size_t NumElements_)
302 : Elements(Elements_), NumElements(NumElements_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000303
304 bool empty() const { return NumElements == 0; }
305 size_t size() const { return NumElements; }
306
Erik Pilkington761e6b02018-01-31 20:17:06 +0000307 Node **begin() const { return Elements; }
308 Node **end() const { return Elements + NumElements; }
309
310 Node *operator[](size_t Idx) const { return Elements[Idx]; }
311
312 void printWithComma(OutputStream &S) const {
313 bool FirstElement = true;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000314 for (size_t Idx = 0; Idx != NumElements; ++Idx) {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000315 if (Elements[Idx]->isEmptyPackExpansion())
316 continue;
317 if (!FirstElement)
318 S += ", ";
319 FirstElement = false;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000320 Elements[Idx]->print(S);
321 }
322 }
323};
324
325class DotSuffix final : public Node {
326 const Node *Prefix;
327 const StringView Suffix;
328
329public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000330 DotSuffix(Node *Prefix_, StringView Suffix_)
331 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000332
333 void printLeft(OutputStream &s) const override {
334 Prefix->print(s);
335 s += " (";
336 s += Suffix;
337 s += ")";
338 }
339};
340
341class VendorExtQualType final : public Node {
Erik Pilkington0024acd2017-07-28 00:43:49 +0000342 const Node *Ty;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000343 StringView Ext;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000344
345public:
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000346 VendorExtQualType(Node *Ty_, StringView Ext_)
347 : Node(KVendorExtQualType, Ty_->ParameterPackSize),
Erik Pilkington761e6b02018-01-31 20:17:06 +0000348 Ty(Ty_), Ext(Ext_) {}
349
Erik Pilkington0024acd2017-07-28 00:43:49 +0000350 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000351 Ty->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000352 S += " ";
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000353 S += Ext;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000354 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000355};
356
357enum Qualifiers {
358 QualNone = 0,
359 QualConst = 0x1,
360 QualVolatile = 0x2,
361 QualRestrict = 0x4,
362};
363
364void addQualifiers(Qualifiers &Q1, Qualifiers Q2) {
365 Q1 = static_cast<Qualifiers>(Q1 | Q2);
366}
367
368class QualType : public Node {
369protected:
370 const Qualifiers Quals;
371 const Node *Child;
372
373 void printQuals(OutputStream &S) const {
374 if (Quals & QualConst)
375 S += " const";
376 if (Quals & QualVolatile)
377 S += " volatile";
378 if (Quals & QualRestrict)
379 S += " restrict";
380 }
381
382public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000383 QualType(Node *Child_, Qualifiers Quals_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000384 : Node(KQualType, Child_->ParameterPackSize, Child_->RHSComponentCache,
385 Child_->ArrayCache, Child_->FunctionCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000386 Quals(Quals_), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000387
Erik Pilkington761e6b02018-01-31 20:17:06 +0000388 bool hasRHSComponentSlow(OutputStream &S) const override {
389 return Child->hasRHSComponent(S);
390 }
391 bool hasArraySlow(OutputStream &S) const override {
392 return Child->hasArray(S);
393 }
394 bool hasFunctionSlow(OutputStream &S) const override {
395 return Child->hasFunction(S);
396 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000397
398 void printLeft(OutputStream &S) const override {
399 Child->printLeft(S);
400 printQuals(S);
401 }
402
403 void printRight(OutputStream &S) const override { Child->printRight(S); }
404};
405
406class ConversionOperatorType final : public Node {
407 const Node *Ty;
408
409public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000410 ConversionOperatorType(Node *Ty_)
411 : Node(KConversionOperatorType, Ty_->ParameterPackSize), Ty(Ty_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000412
413 void printLeft(OutputStream &S) const override {
414 S += "operator ";
415 Ty->print(S);
416 }
417};
418
419class PostfixQualifiedType final : public Node {
420 const Node *Ty;
421 const StringView Postfix;
422
423public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000424 PostfixQualifiedType(Node *Ty_, StringView Postfix_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000425 : Node(KPostfixQualifiedType, Ty_->ParameterPackSize),
426 Ty(Ty_), Postfix(Postfix_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000427
428 void printLeft(OutputStream &s) const override {
429 Ty->printLeft(s);
430 s += Postfix;
431 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000432};
433
434class NameType final : public Node {
435 const StringView Name;
436
437public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000438 NameType(StringView Name_) : Node(KNameType), Name(Name_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000439
440 StringView getName() const { return Name; }
441 StringView getBaseName() const override { return Name; }
442
443 void printLeft(OutputStream &s) const override { s += Name; }
444};
445
Erik Pilkington5bff4122017-11-22 20:38:22 +0000446class AbiTagAttr final : public Node {
447 const Node* Base;
448 StringView Tag;
449public:
450 AbiTagAttr(const Node* Base_, StringView Tag_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000451 : Node(KAbiTagAttr, Base_->ParameterPackSize, Base_->RHSComponentCache,
452 Base_->ArrayCache, Base_->FunctionCache),
453 Base(Base_), Tag(Tag_) {}
Erik Pilkington5bff4122017-11-22 20:38:22 +0000454
455 void printLeft(OutputStream &S) const override {
456 Base->printLeft(S);
457 S += "[abi:";
458 S += Tag;
459 S += "]";
460 }
461};
462
Erik Pilkington0024acd2017-07-28 00:43:49 +0000463class ObjCProtoName : public Node {
464 Node *Ty;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000465 StringView Protocol;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000466
467 friend class PointerType;
468
469public:
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000470 ObjCProtoName(Node *Ty_, StringView Protocol_)
Erik Pilkington414f1a52017-08-09 22:45:35 +0000471 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000472
473 bool isObjCObject() const {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000474 return Ty->getKind() == KNameType &&
Erik Pilkington0024acd2017-07-28 00:43:49 +0000475 static_cast<NameType *>(Ty)->getName() == "objc_object";
476 }
477
478 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000479 Ty->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000480 S += "<";
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000481 S += Protocol;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000482 S += ">";
483 }
484};
485
486class PointerType final : public Node {
487 const Node *Pointee;
488
489public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000490 PointerType(Node *Pointee_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000491 : Node(KPointerType, Pointee_->ParameterPackSize,
492 Pointee_->RHSComponentCache),
493 Pointee(Pointee_) {}
494
495 bool hasRHSComponentSlow(OutputStream &S) const override {
496 return Pointee->hasRHSComponent(S);
497 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000498
499 void printLeft(OutputStream &s) const override {
500 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
Erik Pilkington761e6b02018-01-31 20:17:06 +0000501 if (Pointee->getKind() != KObjCProtoName ||
Erik Pilkington0024acd2017-07-28 00:43:49 +0000502 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
503 Pointee->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000504 if (Pointee->hasArray(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000505 s += " ";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000506 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000507 s += "(";
508 s += "*";
509 } else {
510 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
511 s += "id<";
Erik Pilkingtonf23deca2018-02-05 22:41:20 +0000512 s += objcProto->Protocol;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000513 s += ">";
514 }
515 }
516
517 void printRight(OutputStream &s) const override {
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()) {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000520 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000521 s += ")";
522 Pointee->printRight(s);
523 }
524 }
525};
526
527class LValueReferenceType final : public Node {
528 const Node *Pointee;
529
530public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000531 LValueReferenceType(Node *Pointee_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000532 : Node(KLValueReferenceType, Pointee_->ParameterPackSize,
533 Pointee_->RHSComponentCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000534 Pointee(Pointee_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000535
Erik Pilkington761e6b02018-01-31 20:17:06 +0000536 bool hasRHSComponentSlow(OutputStream &S) const override {
537 return Pointee->hasRHSComponent(S);
538 }
539
Erik Pilkington0024acd2017-07-28 00:43:49 +0000540 void printLeft(OutputStream &s) const override {
541 Pointee->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000542 if (Pointee->hasArray(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000543 s += " ";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000544 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000545 s += "(&";
546 else
547 s += "&";
548 }
549 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000550 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000551 s += ")";
552 Pointee->printRight(s);
553 }
554};
555
556class RValueReferenceType final : public Node {
557 const Node *Pointee;
558
559public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000560 RValueReferenceType(Node *Pointee_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000561 : Node(KRValueReferenceType, Pointee_->ParameterPackSize,
562 Pointee_->RHSComponentCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000563 Pointee(Pointee_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000564
Erik Pilkington761e6b02018-01-31 20:17:06 +0000565 bool hasRHSComponentSlow(OutputStream &S) const override {
566 return Pointee->hasRHSComponent(S);
567 }
568
Erik Pilkington0024acd2017-07-28 00:43:49 +0000569 void printLeft(OutputStream &s) const override {
570 Pointee->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000571 if (Pointee->hasArray(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000572 s += " ";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000573 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000574 s += "(&&";
575 else
576 s += "&&";
577 }
578
579 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000580 if (Pointee->hasArray(s) || Pointee->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000581 s += ")";
582 Pointee->printRight(s);
583 }
584};
585
586class PointerToMemberType final : public Node {
587 const Node *ClassType;
588 const Node *MemberType;
589
590public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000591 PointerToMemberType(Node *ClassType_, Node *MemberType_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000592 : Node(KPointerToMemberType,
593 std::min(MemberType_->ParameterPackSize,
594 ClassType_->ParameterPackSize),
595 MemberType_->RHSComponentCache),
Erik Pilkington414f1a52017-08-09 22:45:35 +0000596 ClassType(ClassType_), MemberType(MemberType_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000597
Erik Pilkington761e6b02018-01-31 20:17:06 +0000598 bool hasRHSComponentSlow(OutputStream &S) const override {
599 return MemberType->hasRHSComponent(S);
600 }
601
Erik Pilkington0024acd2017-07-28 00:43:49 +0000602 void printLeft(OutputStream &s) const override {
603 MemberType->printLeft(s);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000604 if (MemberType->hasArray(s) || MemberType->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000605 s += "(";
606 else
607 s += " ";
608 ClassType->print(s);
609 s += "::*";
610 }
611
612 void printRight(OutputStream &s) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000613 if (MemberType->hasArray(s) || MemberType->hasFunction(s))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000614 s += ")";
615 MemberType->printRight(s);
616 }
617};
618
619class NodeOrString {
620 const void *First;
621 const void *Second;
622
623public:
624 /* implicit */ NodeOrString(StringView Str) {
625 const char *FirstChar = Str.begin();
626 const char *SecondChar = Str.end();
627 if (SecondChar == nullptr) {
628 assert(FirstChar == SecondChar);
629 ++FirstChar, ++SecondChar;
630 }
631 First = static_cast<const void *>(FirstChar);
632 Second = static_cast<const void *>(SecondChar);
633 }
634
635 /* implicit */ NodeOrString(Node *N)
636 : First(static_cast<const void *>(N)), Second(nullptr) {}
637 NodeOrString() : First(nullptr), Second(nullptr) {}
638
639 bool isString() const { return Second && First; }
640 bool isNode() const { return First && !Second; }
641 bool isEmpty() const { return !First && !Second; }
642
643 StringView asString() const {
644 assert(isString());
645 return StringView(static_cast<const char *>(First),
646 static_cast<const char *>(Second));
647 }
648
649 const Node *asNode() const {
650 assert(isNode());
651 return static_cast<const Node *>(First);
652 }
653};
654
655class ArrayType final : public Node {
656 Node *Base;
657 NodeOrString Dimension;
658
659public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000660 ArrayType(Node *Base_, NodeOrString Dimension_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000661 : Node(KArrayType, Base_->ParameterPackSize,
662 /*RHSComponentCache=*/Cache::Yes,
663 /*ArrayCache=*/Cache::Yes),
664 Base(Base_), Dimension(Dimension_) {
665 if (Dimension.isNode())
666 ParameterPackSize =
667 std::min(ParameterPackSize, Dimension.asNode()->ParameterPackSize);
668 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000669
670 // Incomplete array type.
Erik Pilkington761e6b02018-01-31 20:17:06 +0000671 ArrayType(Node *Base_)
672 : Node(KArrayType, Base_->ParameterPackSize,
673 /*RHSComponentCache=*/Cache::Yes,
674 /*ArrayCache=*/Cache::Yes),
675 Base(Base_) {}
676
677 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
678 bool hasArraySlow(OutputStream &) const override { return true; }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000679
680 void printLeft(OutputStream &S) const override { Base->printLeft(S); }
681
682 void printRight(OutputStream &S) const override {
683 if (S.back() != ']')
684 S += " ";
685 S += "[";
686 if (Dimension.isString())
687 S += Dimension.asString();
688 else if (Dimension.isNode())
689 Dimension.asNode()->print(S);
690 S += "]";
691 Base->printRight(S);
692 }
693};
694
695class FunctionType final : public Node {
696 Node *Ret;
697 NodeArray Params;
698
699public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000700 FunctionType(Node *Ret_, NodeArray Params_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000701 : Node(KFunctionType, Ret_->ParameterPackSize,
702 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
703 /*FunctionCache=*/Cache::Yes),
704 Ret(Ret_), Params(Params_) {
705 for (Node *P : Params)
706 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
707 }
708
709 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
710 bool hasFunctionSlow(OutputStream &) const override { return true; }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000711
712 // Handle C++'s ... quirky decl grammer by using the left & right
713 // distinction. Consider:
714 // int (*f(float))(char) {}
715 // f is a function that takes a float and returns a pointer to a function
716 // that takes a char and returns an int. If we're trying to print f, start
717 // by printing out the return types's left, then print our parameters, then
718 // finally print right of the return type.
719 void printLeft(OutputStream &S) const override {
720 Ret->printLeft(S);
721 S += " ";
722 }
723
724 void printRight(OutputStream &S) const override {
725 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000726 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000727 S += ")";
728 Ret->printRight(S);
729 }
730};
731
Erik Pilkington761e6b02018-01-31 20:17:06 +0000732class FunctionEncoding final : public Node {
Erik Pilkington0024acd2017-07-28 00:43:49 +0000733 const Node *Ret;
734 const Node *Name;
735 NodeArray Params;
736
737public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000738 FunctionEncoding(Node *Ret_, Node *Name_, NodeArray Params_)
739 : Node(KFunctionEncoding, NoParameterPack,
740 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
741 /*FunctionCache=*/Cache::Yes),
742 Ret(Ret_), Name(Name_), Params(Params_) {
743 for (Node *P : Params)
744 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
745 if (Ret)
746 ParameterPackSize = std::min(ParameterPackSize, Ret->ParameterPackSize);
747 }
748
749 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
750 bool hasFunctionSlow(OutputStream &) const override { return true; }
751
752 Node *getName() { return const_cast<Node *>(Name); }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000753
754 void printLeft(OutputStream &S) const override {
755 if (Ret) {
756 Ret->printLeft(S);
Erik Pilkington761e6b02018-01-31 20:17:06 +0000757 if (!Ret->hasRHSComponent(S))
Erik Pilkington0024acd2017-07-28 00:43:49 +0000758 S += " ";
759 }
760 Name->print(S);
761 }
762
763 void printRight(OutputStream &S) const override {
764 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +0000765 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000766 S += ")";
767 if (Ret)
768 Ret->printRight(S);
769 }
770};
771
772enum FunctionRefQual : unsigned char {
773 FrefQualNone,
774 FrefQualLValue,
775 FrefQualRValue,
776};
777
778class FunctionRefQualType : public Node {
779 Node *Fn;
780 FunctionRefQual Quals;
781
782 friend class FunctionQualType;
783
784public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000785 FunctionRefQualType(Node *Fn_, FunctionRefQual Quals_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000786 : Node(KFunctionRefQualType, Fn_->ParameterPackSize,
787 /*RHSComponentCache=*/Cache::Yes, /*ArrayCache=*/Cache::No,
788 /*FunctionCache=*/Cache::Yes),
789 Fn(Fn_), Quals(Quals_) {}
790
791 bool hasFunctionSlow(OutputStream &) const override { return true; }
792 bool hasRHSComponentSlow(OutputStream &) const override { return true; }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000793
794 void printQuals(OutputStream &S) const {
795 if (Quals == FrefQualLValue)
796 S += " &";
797 else
798 S += " &&";
799 }
800
801 void printLeft(OutputStream &S) const override { Fn->printLeft(S); }
802
803 void printRight(OutputStream &S) const override {
804 Fn->printRight(S);
805 printQuals(S);
806 }
807};
808
809class FunctionQualType final : public QualType {
810public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000811 FunctionQualType(Node *Child_, Qualifiers Quals_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000812 : QualType(Child_, Quals_) {
813 K = KFunctionQualType;
814 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000815
816 void printLeft(OutputStream &S) const override { Child->printLeft(S); }
817
818 void printRight(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000819 if (Child->getKind() == KFunctionRefQualType) {
Erik Pilkington0024acd2017-07-28 00:43:49 +0000820 auto *RefQuals = static_cast<const FunctionRefQualType *>(Child);
821 RefQuals->Fn->printRight(S);
822 printQuals(S);
823 RefQuals->printQuals(S);
824 } else {
825 Child->printRight(S);
826 printQuals(S);
827 }
828 }
829};
830
831class LiteralOperator : public Node {
832 const Node *OpName;
833
834public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000835 LiteralOperator(Node *OpName_)
836 : Node(KLiteralOperator, OpName_->ParameterPackSize), OpName(OpName_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000837
838 void printLeft(OutputStream &S) const override {
839 S += "operator\"\" ";
840 OpName->print(S);
841 }
842};
843
844class SpecialName final : public Node {
845 const StringView Special;
846 const Node *Child;
847
848public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000849 SpecialName(StringView Special_, Node* Child_)
850 : Node(KSpecialName, Child_->ParameterPackSize), Special(Special_),
851 Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000852
853 void printLeft(OutputStream &S) const override {
854 S += Special;
855 Child->print(S);
856 }
857};
858
859class CtorVtableSpecialName final : public Node {
860 const Node *FirstType;
861 const Node *SecondType;
862
863public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000864 CtorVtableSpecialName(Node *FirstType_, Node *SecondType_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000865 : Node(KCtorVtableSpecialName, std::min(FirstType_->ParameterPackSize,
866 SecondType_->ParameterPackSize)),
867 FirstType(FirstType_), SecondType(SecondType_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000868
869 void printLeft(OutputStream &S) const override {
870 S += "construction vtable for ";
871 FirstType->print(S);
872 S += "-in-";
873 SecondType->print(S);
874 }
875};
876
877class QualifiedName final : public Node {
878 // qualifier::name
879 const Node *Qualifier;
880 const Node *Name;
881
Erik Pilkington0024acd2017-07-28 00:43:49 +0000882public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000883 QualifiedName(Node* Qualifier_, Node* Name_)
884 : Node(KQualifiedName,
885 std::min(Qualifier_->ParameterPackSize, Name_->ParameterPackSize)),
886 Qualifier(Qualifier_), Name(Name_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +0000887
888 StringView getBaseName() const override { return Name->getBaseName(); }
889
890 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000891 Qualifier->print(S);
892 S += "::";
Erik Pilkington0024acd2017-07-28 00:43:49 +0000893 Name->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +0000894 }
895};
896
897class EmptyName : public Node {
898public:
899 EmptyName() : Node(KEmptyName) {}
900 void printLeft(OutputStream &) const override {}
901};
902
903class VectorType final : public Node {
904 const Node *BaseType;
905 const NodeOrString Dimension;
906 const bool IsPixel;
907
908public:
Erik Pilkington414f1a52017-08-09 22:45:35 +0000909 VectorType(NodeOrString Dimension_)
910 : Node(KVectorType), BaseType(nullptr), Dimension(Dimension_),
Erik Pilkington761e6b02018-01-31 20:17:06 +0000911 IsPixel(true) {
912 if (Dimension.isNode())
913 ParameterPackSize = Dimension.asNode()->ParameterPackSize;
914 }
Erik Pilkington414f1a52017-08-09 22:45:35 +0000915 VectorType(Node *BaseType_, NodeOrString Dimension_)
Erik Pilkington761e6b02018-01-31 20:17:06 +0000916 : Node(KVectorType, BaseType_->ParameterPackSize), BaseType(BaseType_),
917 Dimension(Dimension_), IsPixel(false) {
918 if (Dimension.isNode())
919 ParameterPackSize =
920 std::min(ParameterPackSize, Dimension.asNode()->ParameterPackSize);
921 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000922
923 void printLeft(OutputStream &S) const override {
924 if (IsPixel) {
925 S += "pixel vector[";
926 S += Dimension.asString();
927 S += "]";
928 } else {
929 BaseType->print(S);
930 S += " vector[";
931 if (Dimension.isNode())
932 Dimension.asNode()->print(S);
933 else if (Dimension.isString())
934 S += Dimension.asString();
935 S += "]";
936 }
937 }
938};
939
Erik Pilkington761e6b02018-01-31 20:17:06 +0000940/// An unexpanded parameter pack (either in the expression or type context). If
941/// this AST is correct, this node will have a ParameterPackExpansion node above
942/// it.
943///
944/// This node is created when some <template-args> are found that apply to an
945/// <encoding>, and is stored in the TemplateParams table. In order for this to
946/// appear in the final AST, it has to referenced via a <template-param> (ie,
947/// T_).
948class ParameterPack final : public Node {
949 NodeArray Data;
Erik Pilkington0024acd2017-07-28 00:43:49 +0000950public:
Erik Pilkington761e6b02018-01-31 20:17:06 +0000951 ParameterPack(NodeArray Data_)
952 : Node(KParameterPack, static_cast<unsigned>(Data_.size())), Data(Data_) {
953 ArrayCache = FunctionCache = RHSComponentCache = Cache::Unknown;
954 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
955 return P->ArrayCache == Cache::No;
956 }))
957 ArrayCache = Cache::No;
958 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
959 return P->FunctionCache == Cache::No;
960 }))
961 FunctionCache = Cache::No;
962 if (std::all_of(Data.begin(), Data.end(), [](Node* P) {
963 return P->RHSComponentCache == Cache::No;
964 }))
965 RHSComponentCache = Cache::No;
966 }
967
968 bool hasRHSComponentSlow(OutputStream &S) const override {
969 size_t Idx = S.CurrentPackIndex;
970 return Idx < Data.size() && Data[Idx]->hasRHSComponent(S);
971 }
972 bool hasArraySlow(OutputStream &S) const override {
973 size_t Idx = S.CurrentPackIndex;
974 return Idx < Data.size() && Data[Idx]->hasArray(S);
975 }
976 bool hasFunctionSlow(OutputStream &S) const override {
977 size_t Idx = S.CurrentPackIndex;
978 return Idx < Data.size() && Data[Idx]->hasFunction(S);
979 }
Erik Pilkington0024acd2017-07-28 00:43:49 +0000980
981 void printLeft(OutputStream &S) const override {
Erik Pilkington761e6b02018-01-31 20:17:06 +0000982 size_t Idx = S.CurrentPackIndex;
983 if (Idx < Data.size())
984 Data[Idx]->printLeft(S);
985 }
986 void printRight(OutputStream &S) const override {
987 size_t Idx = S.CurrentPackIndex;
988 if (Idx < Data.size())
989 Data[Idx]->printRight(S);
990 }
991};
992
993/// A variadic template argument. This node represents an occurance of
994/// J<something>E in some <template-args>. It isn't itself unexpanded, unless
995/// one of it's Elements is. The parser inserts a ParameterPack into the
996/// TemplateParams table if the <template-args> this pack belongs to apply to an
997/// <encoding>.
998class TemplateArgumentPack final : public Node {
999 NodeArray Elements;
1000public:
1001 TemplateArgumentPack(NodeArray Elements_)
1002 : Node(KTemplateArgumentPack), Elements(Elements_) {
1003 for (Node *E : Elements)
1004 ParameterPackSize = std::min(E->ParameterPackSize, ParameterPackSize);
1005 }
1006
1007 NodeArray getElements() const { return Elements; }
1008
1009 void printLeft(OutputStream &S) const override {
1010 Elements.printWithComma(S);
1011 }
1012};
1013
1014/// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1015/// which each have Child->ParameterPackSize elements.
1016class ParameterPackExpansion final : public Node {
1017 const Node *Child;
1018
1019public:
1020 ParameterPackExpansion(Node* Child_)
1021 : Node(KParameterPackExpansion), Child(Child_) {}
1022
1023 const Node *getChild() const { return Child; }
1024
1025 void printLeft(OutputStream &S) const override {
1026 unsigned PackSize = Child->ParameterPackSize;
1027 if (PackSize == NoParameterPack) {
1028 Child->print(S);
1029 S += "...";
Erik Pilkington0024acd2017-07-28 00:43:49 +00001030 return;
1031 }
1032
Erik Pilkington761e6b02018-01-31 20:17:06 +00001033 SwapAndRestore<unsigned> SavePackIndex(S.CurrentPackIndex, 0);
1034 for (unsigned I = 0; I != PackSize; ++I) {
1035 if (I != 0)
1036 S += ", ";
1037 S.CurrentPackIndex = I;
1038 Child->print(S);
1039 }
1040 }
1041};
Erik Pilkington0024acd2017-07-28 00:43:49 +00001042
Erik Pilkington761e6b02018-01-31 20:17:06 +00001043inline bool Node::isEmptyPackExpansion() const {
1044 if (getKind() == KParameterPackExpansion) {
1045 auto *AsPack = static_cast<const ParameterPackExpansion *>(this);
1046 return AsPack->getChild()->isEmptyPackExpansion();
1047 }
1048 if (getKind() == KTemplateArgumentPack) {
1049 auto *AsTemplateArg = static_cast<const TemplateArgumentPack *>(this);
1050 for (Node *E : AsTemplateArg->getElements())
1051 if (!E->isEmptyPackExpansion())
1052 return false;
1053 return true;
1054 }
1055 return ParameterPackSize == 0;
1056}
1057
1058class TemplateArgs final : public Node {
1059 NodeArray Params;
1060
1061public:
1062 TemplateArgs(NodeArray Params_) : Node(KTemplateArgs), Params(Params_) {
1063 for (Node *P : Params)
1064 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
1065 }
1066
1067 NodeArray getParams() { return Params; }
1068
1069 void printLeft(OutputStream &S) const override {
Erik Pilkington0024acd2017-07-28 00:43:49 +00001070 S += "<";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001071 bool FirstElement = true;
1072 for (size_t Idx = 0, E = Params.size(); Idx != E; ++Idx) {
1073 if (Params[Idx]->isEmptyPackExpansion())
1074 continue;
1075 if (!FirstElement)
1076 S += ", ";
1077 FirstElement = false;
1078 Params[Idx]->print(S);
1079 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001080 if (S.back() == '>')
1081 S += " ";
1082 S += ">";
Erik Pilkington0024acd2017-07-28 00:43:49 +00001083 }
1084};
1085
1086class NameWithTemplateArgs final : public Node {
1087 // name<template_args>
1088 Node *Name;
1089 Node *TemplateArgs;
1090
1091public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001092 NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001093 : Node(KNameWithTemplateArgs, std::min(Name_->ParameterPackSize,
1094 TemplateArgs_->ParameterPackSize)),
1095 Name(Name_), TemplateArgs(TemplateArgs_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001096
1097 StringView getBaseName() const override { return Name->getBaseName(); }
1098
1099 void printLeft(OutputStream &S) const override {
1100 Name->print(S);
1101 TemplateArgs->print(S);
1102 }
1103};
1104
1105class GlobalQualifiedName final : public Node {
1106 Node *Child;
1107
1108public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001109 GlobalQualifiedName(Node* Child_)
1110 : Node(KGlobalQualifiedName, Child_->ParameterPackSize), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001111
1112 StringView getBaseName() const override { return Child->getBaseName(); }
1113
1114 void printLeft(OutputStream &S) const override {
1115 S += "::";
1116 Child->print(S);
1117 }
1118};
1119
1120class StdQualifiedName final : public Node {
1121 Node *Child;
1122
1123public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001124 StdQualifiedName(Node *Child_)
1125 : Node(KStdQualifiedName, Child_->ParameterPackSize), Child(Child_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001126
1127 StringView getBaseName() const override { return Child->getBaseName(); }
1128
1129 void printLeft(OutputStream &S) const override {
1130 S += "std::";
1131 Child->print(S);
1132 }
1133};
1134
1135enum class SpecialSubKind {
1136 allocator,
1137 basic_string,
1138 string,
1139 istream,
1140 ostream,
1141 iostream,
1142};
1143
1144class ExpandedSpecialSubstitution final : public Node {
1145 SpecialSubKind SSK;
1146
1147public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001148 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1149 : Node(KExpandedSpecialSubstitution), SSK(SSK_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001150
1151 StringView getBaseName() const override {
1152 switch (SSK) {
1153 case SpecialSubKind::allocator:
1154 return StringView("allocator");
1155 case SpecialSubKind::basic_string:
1156 return StringView("basic_string");
1157 case SpecialSubKind::string:
1158 return StringView("basic_string");
1159 case SpecialSubKind::istream:
1160 return StringView("basic_istream");
1161 case SpecialSubKind::ostream:
1162 return StringView("basic_ostream");
1163 case SpecialSubKind::iostream:
1164 return StringView("basic_iostream");
1165 }
Erik Pilkingtond25d9012017-08-01 02:38:40 +00001166 _LIBCPP_UNREACHABLE();
Erik Pilkington0024acd2017-07-28 00:43:49 +00001167 }
1168
1169 void printLeft(OutputStream &S) const override {
1170 switch (SSK) {
1171 case SpecialSubKind::allocator:
1172 S += "std::basic_string<char, std::char_traits<char>, "
1173 "std::allocator<char> >";
1174 break;
1175 case SpecialSubKind::basic_string:
1176 case SpecialSubKind::string:
1177 S += "std::basic_string<char, std::char_traits<char>, "
1178 "std::allocator<char> >";
1179 break;
1180 case SpecialSubKind::istream:
1181 S += "std::basic_istream<char, std::char_traits<char> >";
1182 break;
1183 case SpecialSubKind::ostream:
1184 S += "std::basic_ostream<char, std::char_traits<char> >";
1185 break;
1186 case SpecialSubKind::iostream:
1187 S += "std::basic_iostream<char, std::char_traits<char> >";
1188 break;
1189 }
1190 }
1191};
1192
1193class SpecialSubstitution final : public Node {
1194public:
1195 SpecialSubKind SSK;
1196
Erik Pilkington414f1a52017-08-09 22:45:35 +00001197 SpecialSubstitution(SpecialSubKind SSK_)
1198 : Node(KSpecialSubstitution), SSK(SSK_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001199
1200 StringView getBaseName() const override {
1201 switch (SSK) {
1202 case SpecialSubKind::allocator:
1203 return StringView("allocator");
1204 case SpecialSubKind::basic_string:
1205 return StringView("basic_string");
1206 case SpecialSubKind::string:
1207 return StringView("string");
1208 case SpecialSubKind::istream:
1209 return StringView("istream");
1210 case SpecialSubKind::ostream:
1211 return StringView("ostream");
1212 case SpecialSubKind::iostream:
1213 return StringView("iostream");
1214 }
Erik Pilkingtond25d9012017-08-01 02:38:40 +00001215 _LIBCPP_UNREACHABLE();
Erik Pilkington0024acd2017-07-28 00:43:49 +00001216 }
1217
1218 void printLeft(OutputStream &S) const override {
1219 switch (SSK) {
1220 case SpecialSubKind::allocator:
1221 S += "std::allocator";
1222 break;
1223 case SpecialSubKind::basic_string:
1224 S += "std::basic_string";
1225 break;
1226 case SpecialSubKind::string:
1227 S += "std::string";
1228 break;
1229 case SpecialSubKind::istream:
1230 S += "std::istream";
1231 break;
1232 case SpecialSubKind::ostream:
1233 S += "std::ostream";
1234 break;
1235 case SpecialSubKind::iostream:
1236 S += "std::iostream";
1237 break;
1238 }
1239 }
1240};
1241
1242class CtorDtorName final : public Node {
1243 const Node *Basename;
1244 const bool IsDtor;
1245
1246public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001247 CtorDtorName(Node *Basename_, bool IsDtor_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001248 : Node(KCtorDtorName, Basename_->ParameterPackSize),
1249 Basename(Basename_), IsDtor(IsDtor_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001250
1251 void printLeft(OutputStream &S) const override {
1252 if (IsDtor)
1253 S += "~";
1254 S += Basename->getBaseName();
1255 }
1256};
1257
1258class DtorName : public Node {
1259 const Node *Base;
1260
1261public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001262 DtorName(Node *Base_) : Node(KDtorName), Base(Base_) {
1263 ParameterPackSize = Base->ParameterPackSize;
1264 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001265
1266 void printLeft(OutputStream &S) const override {
1267 S += "~";
1268 Base->printLeft(S);
1269 }
1270};
1271
1272class UnnamedTypeName : public Node {
1273 const StringView Count;
1274
1275public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001276 UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001277
1278 void printLeft(OutputStream &S) const override {
1279 S += "'unnamed";
1280 S += Count;
1281 S += "\'";
1282 }
1283};
1284
1285class LambdaTypeName : public Node {
1286 NodeArray Params;
1287 StringView Count;
1288
1289public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001290 LambdaTypeName(NodeArray Params_, StringView Count_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001291 : Node(KLambdaTypeName), Params(Params_), Count(Count_) {
1292 for (Node *P : Params)
1293 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
1294 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001295
1296 void printLeft(OutputStream &S) const override {
1297 S += "\'lambda";
1298 S += Count;
1299 S += "\'(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001300 Params.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001301 S += ")";
1302 }
1303};
1304
1305// -- Expression Nodes --
1306
1307struct Expr : public Node {
1308 Expr() : Node(KExpr) {}
1309};
1310
1311class BinaryExpr : public Expr {
1312 const Node *LHS;
1313 const StringView InfixOperator;
1314 const Node *RHS;
1315
1316public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001317 BinaryExpr(Node *LHS_, StringView InfixOperator_, Node *RHS_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001318 : LHS(LHS_), InfixOperator(InfixOperator_), RHS(RHS_) {
1319 ParameterPackSize =
1320 std::min(LHS->ParameterPackSize, RHS->ParameterPackSize);
1321 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001322
1323 void printLeft(OutputStream &S) const override {
1324 // might be a template argument expression, then we need to disambiguate
1325 // with parens.
1326 if (InfixOperator == ">")
1327 S += "(";
1328
1329 S += "(";
1330 LHS->print(S);
1331 S += ") ";
1332 S += InfixOperator;
1333 S += " (";
1334 RHS->print(S);
1335 S += ")";
1336
1337 if (InfixOperator == ">")
1338 S += ")";
1339 }
1340};
1341
1342class ArraySubscriptExpr : public Expr {
1343 const Node *Op1;
1344 const Node *Op2;
1345
1346public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001347 ArraySubscriptExpr(Node *Op1_, Node *Op2_) : Op1(Op1_), Op2(Op2_) {
1348 ParameterPackSize =
1349 std::min(Op1->ParameterPackSize, Op2->ParameterPackSize);
1350 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001351
1352 void printLeft(OutputStream &S) const override {
1353 S += "(";
1354 Op1->print(S);
1355 S += ")[";
1356 Op2->print(S);
1357 S += "]";
1358 }
1359};
1360
1361class PostfixExpr : public Expr {
1362 const Node *Child;
1363 const StringView Operand;
1364
1365public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001366 PostfixExpr(Node *Child_, StringView Operand_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001367 : Child(Child_), Operand(Operand_) {
1368 ParameterPackSize = Child->ParameterPackSize;
1369 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001370
1371 void printLeft(OutputStream &S) const override {
1372 S += "(";
1373 Child->print(S);
1374 S += ")";
1375 S += Operand;
1376 }
1377};
1378
1379class ConditionalExpr : public Expr {
1380 const Node *Cond;
1381 const Node *Then;
1382 const Node *Else;
1383
1384public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001385 ConditionalExpr(Node *Cond_, Node *Then_, Node *Else_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001386 : Cond(Cond_), Then(Then_), Else(Else_) {
1387 ParameterPackSize =
1388 std::min(Cond->ParameterPackSize,
1389 std::min(Then->ParameterPackSize, Else->ParameterPackSize));
1390 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001391
1392 void printLeft(OutputStream &S) const override {
1393 S += "(";
1394 Cond->print(S);
1395 S += ") ? (";
1396 Then->print(S);
1397 S += ") : (";
1398 Else->print(S);
1399 S += ")";
1400 }
1401};
1402
1403class MemberExpr : public Expr {
1404 const Node *LHS;
1405 const StringView Kind;
1406 const Node *RHS;
1407
1408public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001409 MemberExpr(Node *LHS_, StringView Kind_, Node *RHS_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001410 : LHS(LHS_), Kind(Kind_), RHS(RHS_) {
1411 ParameterPackSize =
1412 std::min(LHS->ParameterPackSize, RHS->ParameterPackSize);
1413 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001414
1415 void printLeft(OutputStream &S) const override {
1416 LHS->print(S);
1417 S += Kind;
1418 RHS->print(S);
1419 }
1420};
1421
1422class EnclosingExpr : public Expr {
1423 const StringView Prefix;
1424 const Node *Infix;
1425 const StringView Postfix;
1426
1427public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001428 EnclosingExpr(StringView Prefix_, Node *Infix_, StringView Postfix_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001429 : Prefix(Prefix_), Infix(Infix_), Postfix(Postfix_) {
1430 ParameterPackSize = Infix->ParameterPackSize;
1431 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001432
1433 void printLeft(OutputStream &S) const override {
1434 S += Prefix;
1435 Infix->print(S);
1436 S += Postfix;
1437 }
1438};
1439
1440class CastExpr : public Expr {
1441 // cast_kind<to>(from)
1442 const StringView CastKind;
1443 const Node *To;
1444 const Node *From;
1445
1446public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001447 CastExpr(StringView CastKind_, Node *To_, Node *From_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001448 : CastKind(CastKind_), To(To_), From(From_) {
1449 ParameterPackSize =
1450 std::min(To->ParameterPackSize, From->ParameterPackSize);
1451 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001452
1453 void printLeft(OutputStream &S) const override {
1454 S += CastKind;
1455 S += "<";
1456 To->printLeft(S);
1457 S += ">(";
1458 From->printLeft(S);
1459 S += ")";
1460 }
1461};
1462
1463class SizeofParamPackExpr : public Expr {
Erik Pilkington761e6b02018-01-31 20:17:06 +00001464 Node *Pack;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001465
1466public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001467 SizeofParamPackExpr(Node *Pack_) : Pack(Pack_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001468
1469 void printLeft(OutputStream &S) const override {
1470 S += "sizeof...(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001471 ParameterPackExpansion PPE(Pack);
1472 PPE.printLeft(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001473 S += ")";
1474 }
1475};
1476
1477class CallExpr : public Expr {
1478 const Node *Callee;
1479 NodeArray Args;
1480
1481public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001482 CallExpr(Node *Callee_, NodeArray Args_) : Callee(Callee_), Args(Args_) {
1483 for (Node *P : Args)
1484 ParameterPackSize = std::min(ParameterPackSize, P->ParameterPackSize);
1485 ParameterPackSize = std::min(ParameterPackSize, Callee->ParameterPackSize);
1486 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001487
1488 void printLeft(OutputStream &S) const override {
1489 Callee->print(S);
1490 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001491 Args.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001492 S += ")";
1493 }
1494};
1495
1496class NewExpr : public Expr {
1497 // new (expr_list) type(init_list)
1498 NodeArray ExprList;
1499 Node *Type;
1500 NodeArray InitList;
1501 bool IsGlobal; // ::operator new ?
1502 bool IsArray; // new[] ?
1503public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001504 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
1505 bool IsArray_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001506 : ExprList(ExprList_), Type(Type_), InitList(InitList_),
1507 IsGlobal(IsGlobal_), IsArray(IsArray_) {
1508 for (Node *E : ExprList)
1509 ParameterPackSize = std::min(ParameterPackSize, E->ParameterPackSize);
1510 for (Node *I : InitList)
1511 ParameterPackSize = std::min(ParameterPackSize, I->ParameterPackSize);
1512 if (Type)
1513 ParameterPackSize = std::min(ParameterPackSize, Type->ParameterPackSize);
1514 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001515
1516 void printLeft(OutputStream &S) const override {
1517 if (IsGlobal)
1518 S += "::operator ";
1519 S += "new";
1520 if (IsArray)
1521 S += "[]";
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001522 S += ' ';
Erik Pilkington0024acd2017-07-28 00:43:49 +00001523 if (!ExprList.empty()) {
1524 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001525 ExprList.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001526 S += ")";
1527 }
1528 Type->print(S);
1529 if (!InitList.empty()) {
1530 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001531 InitList.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001532 S += ")";
1533 }
Erik Pilkington761e6b02018-01-31 20:17:06 +00001534
Erik Pilkington0024acd2017-07-28 00:43:49 +00001535 }
1536};
1537
1538class DeleteExpr : public Expr {
1539 Node *Op;
1540 bool IsGlobal;
1541 bool IsArray;
1542
1543public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001544 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_)
Erik Pilkington761e6b02018-01-31 20:17:06 +00001545 : Op(Op_), IsGlobal(IsGlobal_), IsArray(IsArray_) {
1546 ParameterPackSize = Op->ParameterPackSize;
1547 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001548
1549 void printLeft(OutputStream &S) const override {
1550 if (IsGlobal)
1551 S += "::";
1552 S += "delete";
1553 if (IsArray)
1554 S += "[] ";
1555 Op->print(S);
1556 }
1557};
1558
1559class PrefixExpr : public Expr {
1560 StringView Prefix;
1561 Node *Child;
1562
1563public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001564 PrefixExpr(StringView Prefix_, Node *Child_) : Prefix(Prefix_), Child(Child_) {
1565 ParameterPackSize = Child->ParameterPackSize;
1566 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001567
1568 void printLeft(OutputStream &S) const override {
1569 S += Prefix;
1570 S += "(";
1571 Child->print(S);
1572 S += ")";
1573 }
1574};
1575
1576class FunctionParam : public Expr {
1577 StringView Number;
1578
1579public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001580 FunctionParam(StringView Number_) : Number(Number_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001581
1582 void printLeft(OutputStream &S) const override {
1583 S += "fp";
1584 S += Number;
1585 }
1586};
1587
Erik Pilkington0024acd2017-07-28 00:43:49 +00001588class ConversionExpr : public Expr {
Erik Pilkington761e6b02018-01-31 20:17:06 +00001589 const Node *Type;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001590 NodeArray Expressions;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001591
1592public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001593 ConversionExpr(const Node *Type_, NodeArray Expressions_)
1594 : Type(Type_), Expressions(Expressions_) {
1595 for (Node *E : Expressions)
1596 ParameterPackSize = std::min(ParameterPackSize, E->ParameterPackSize);
1597 ParameterPackSize = std::min(ParameterPackSize, Type->ParameterPackSize);
1598 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001599
1600 void printLeft(OutputStream &S) const override {
1601 S += "(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001602 Type->print(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001603 S += ")(";
Erik Pilkington761e6b02018-01-31 20:17:06 +00001604 Expressions.printWithComma(S);
Erik Pilkington0024acd2017-07-28 00:43:49 +00001605 S += ")";
1606 }
1607};
1608
1609class ThrowExpr : public Expr {
1610 const Node *Op;
1611
1612public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001613 ThrowExpr(Node *Op_) : Op(Op_) {
1614 ParameterPackSize = Op->ParameterPackSize;
1615 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001616
1617 void printLeft(OutputStream &S) const override {
1618 S += "throw ";
1619 Op->print(S);
1620 }
1621};
1622
1623class BoolExpr : public Expr {
1624 bool Value;
1625
1626public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001627 BoolExpr(bool Value_) : Value(Value_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001628
1629 void printLeft(OutputStream &S) const override {
1630 S += Value ? StringView("true") : StringView("false");
1631 }
1632};
1633
1634class IntegerCastExpr : public Expr {
1635 // ty(integer)
1636 Node *Ty;
1637 StringView Integer;
1638
1639public:
Erik Pilkington761e6b02018-01-31 20:17:06 +00001640 IntegerCastExpr(Node *Ty_, StringView Integer_) : Ty(Ty_), Integer(Integer_) {
1641 ParameterPackSize = Ty->ParameterPackSize;
1642 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001643
1644 void printLeft(OutputStream &S) const override {
1645 S += "(";
1646 Ty->print(S);
1647 S += ")";
1648 S += Integer;
1649 }
1650};
1651
1652class IntegerExpr : public Expr {
1653 StringView Type;
1654 StringView Value;
1655
1656public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001657 IntegerExpr(StringView Type_, StringView Value_) : Type(Type_), Value(Value_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001658
1659 void printLeft(OutputStream &S) const override {
1660 if (Type.size() > 3) {
1661 S += "(";
1662 S += Type;
1663 S += ")";
1664 }
1665
1666 if (Value[0] == 'n') {
1667 S += "-";
1668 S += Value.dropFront(1);
1669 } else
1670 S += Value;
1671
1672 if (Type.size() <= 3)
1673 S += Type;
1674 }
1675};
1676
1677template <class Float> struct FloatData;
1678
1679template <class Float> class FloatExpr : public Expr {
1680 const StringView Contents;
1681
1682public:
Erik Pilkington414f1a52017-08-09 22:45:35 +00001683 FloatExpr(StringView Contents_) : Contents(Contents_) {}
Erik Pilkington0024acd2017-07-28 00:43:49 +00001684
1685 void printLeft(OutputStream &s) const override {
1686 const char *first = Contents.begin();
1687 const char *last = Contents.end() + 1;
1688
1689 const size_t N = FloatData<Float>::mangled_size;
1690 if (static_cast<std::size_t>(last - first) > N) {
1691 last = first + N;
1692 union {
1693 Float value;
1694 char buf[sizeof(Float)];
1695 };
1696 const char *t = first;
1697 char *e = buf;
1698 for (; t != last; ++t, ++e) {
1699 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1700 : static_cast<unsigned>(*t - 'a' + 10);
1701 ++t;
1702 unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
1703 : static_cast<unsigned>(*t - 'a' + 10);
1704 *e = static_cast<char>((d1 << 4) + d0);
1705 }
1706#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1707 std::reverse(buf, e);
1708#endif
1709 char num[FloatData<Float>::max_demangled_size] = {0};
1710 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
1711 s += StringView(num, num + n);
1712 }
1713 }
1714};
1715
Erik Pilkington0024acd2017-07-28 00:43:49 +00001716class BumpPointerAllocator {
1717 struct BlockMeta {
1718 BlockMeta* Next;
1719 size_t Current;
1720 };
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001721
Erik Pilkington0024acd2017-07-28 00:43:49 +00001722 static constexpr size_t AllocSize = 4096;
1723 static constexpr size_t UsableAllocSize = AllocSize - sizeof(BlockMeta);
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001724
Erik Pilkington0024acd2017-07-28 00:43:49 +00001725 alignas(16) char InitialBuffer[AllocSize];
1726 BlockMeta* BlockList = nullptr;
1727
1728 void grow() {
1729 char* NewMeta = new char[AllocSize];
1730 BlockList = new (NewMeta) BlockMeta{BlockList, 0};
1731 }
1732
1733 void* allocateMassive(size_t NBytes) {
1734 NBytes += sizeof(BlockMeta);
1735 BlockMeta* NewMeta = reinterpret_cast<BlockMeta*>(new char[NBytes]);
1736 BlockList->Next = new (NewMeta) BlockMeta{BlockList->Next, 0};
1737 return static_cast<void*>(NewMeta + 1);
1738 }
1739
1740public:
1741 BumpPointerAllocator()
1742 : BlockList(new (InitialBuffer) BlockMeta{nullptr, 0}) {}
1743
1744 void* allocate(size_t N) {
1745 N = (N + 15u) & ~15u;
1746 if (N + BlockList->Current >= UsableAllocSize) {
1747 if (N > UsableAllocSize)
1748 return allocateMassive(N);
1749 grow();
1750 }
1751 BlockList->Current += N;
1752 return static_cast<void*>(reinterpret_cast<char*>(BlockList + 1) +
1753 BlockList->Current - N);
1754 }
1755
1756 ~BumpPointerAllocator() {
1757 while (BlockList) {
1758 BlockMeta* Tmp = BlockList;
1759 BlockList = BlockList->Next;
1760 if (reinterpret_cast<char*>(Tmp) != InitialBuffer)
1761 delete[] reinterpret_cast<char*>(Tmp);
1762 }
1763 }
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001764};
1765
Erik Pilkingtonba34a242017-08-09 21:30:57 +00001766template <class T, size_t N>
1767class PODSmallVector {
1768 static_assert(std::is_pod<T>::value,
1769 "T is required to be a plain old data type");
1770
1771 T* First;
1772 T* Last;
1773 T* Cap;
1774 T Inline[N];
1775
1776 bool isInline() const { return First == Inline; }
1777
1778 void clearInline() {
1779 First = Inline;
1780 Last = Inline;
1781 Cap = Inline + N;
1782 }
1783
1784 void reserve(size_t NewCap) {
1785 size_t S = size();
1786 if (isInline()) {
1787 auto* Tmp = static_cast<T*>(std::malloc(NewCap * sizeof(T)));
1788 std::copy(First, Last, Tmp);
1789 First = Tmp;
1790 } else
1791 First = static_cast<T*>(std::realloc(First, NewCap * sizeof(T)));
1792 Last = First + S;
1793 Cap = First + NewCap;
1794 }
1795
1796public:
1797 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
1798
1799 PODSmallVector(const PODSmallVector&) = delete;
1800 PODSmallVector& operator=(const PODSmallVector&) = delete;
1801
1802 PODSmallVector(PODSmallVector&& Other) : PODSmallVector() {
1803 if (Other.isInline()) {
1804 std::copy(Other.begin(), Other.end(), First);
1805 Last = First + Other.size();
1806 Other.clear();
1807 return;
1808 }
1809
1810 First = Other.First;
1811 Last = Other.Last;
1812 Cap = Other.Cap;
1813 Other.clearInline();
1814 }
1815
1816 PODSmallVector& operator=(PODSmallVector&& Other) {
1817 if (Other.isInline()) {
1818 if (!isInline()) {
1819 std::free(First);
1820 clearInline();
1821 }
1822 std::copy(Other.begin(), Other.end(), First);
1823 Last = First + Other.size();
1824 Other.clear();
1825 return *this;
1826 }
1827
1828 if (isInline()) {
1829 First = Other.First;
1830 Last = Other.Last;
1831 Cap = Other.Cap;
1832 Other.clearInline();
1833 return *this;
1834 }
1835
1836 std::swap(First, Other.First);
1837 std::swap(Last, Other.Last);
1838 std::swap(Cap, Other.Cap);
1839 Other.clear();
1840 return *this;
1841 }
1842
1843 void push_back(const T& Elem) {
1844 if (Last == Cap)
1845 reserve(size() * 2);
1846 *Last++ = Elem;
1847 }
1848
1849 void pop_back() {
1850 assert(Last != First && "Popping empty vector!");
1851 --Last;
1852 }
1853
1854 void dropBack(size_t Index) {
1855 assert(Index <= size() && "dropBack() can't expand!");
1856 Last = First + Index;
1857 }
1858
1859 T* begin() { return First; }
1860 T* end() { return Last; }
1861
1862 bool empty() const { return First == Last; }
1863 size_t size() const { return static_cast<size_t>(Last - First); }
1864 T& back() {
1865 assert(Last != First && "Calling back() on empty vector!");
1866 return *(Last - 1);
1867 }
1868 T& operator[](size_t Index) {
1869 assert(Index < size() && "Invalid access!");
1870 return *(begin() + Index);
1871 }
1872 void clear() { Last = First; }
1873
1874 ~PODSmallVector() {
1875 if (!isInline())
1876 std::free(First);
1877 }
1878};
1879
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001880struct Db {
1881 const char *First;
1882 const char *Last;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00001883
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001884 // Name stack, this is used by the parser to hold temporary names that were
1885 // parsed. The parser colapses multiple names into new nodes to construct
1886 // the AST. Once the parser is finished, names.size() == 1.
1887 PODSmallVector<Node *, 32> Names;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00001888
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001889 // Substitution table. Itanium supports name substitutions as a means of
1890 // compression. The string "S42_" refers to the 44nd entry (base-36) in this
1891 // table.
1892 PODSmallVector<Node *, 32> Subs;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00001893
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001894 // Template parameter table. Like the above, but referenced like "T42_".
1895 // This has a smaller size compared to Subs and Names because it can be
1896 // stored on the stack.
1897 PODSmallVector<Node *, 8> TemplateParams;
Erik Pilkington9dd63d22017-07-08 18:54:07 +00001898
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001899 Qualifiers CV = QualNone;
1900 FunctionRefQual RefQuals = FrefQualNone;
1901 unsigned EncodingDepth = 0;
1902 bool ParsedCtorDtorCV = false;
1903 bool TagTemplates = true;
1904 bool FixForwardReferences = false;
1905 bool TryToParseTemplateArgs = true;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001906
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001907 BumpPointerAllocator ASTAllocator;
1908
1909 template <class T, class... Args> T *make(Args &&... args) {
1910 return new (ASTAllocator.allocate(sizeof(T)))
1911 T(std::forward<Args>(args)...);
1912 }
1913
1914 template <class It> NodeArray makeNodeArray(It begin, It end) {
1915 size_t sz = static_cast<size_t>(end - begin);
1916 void *mem = ASTAllocator.allocate(sizeof(Node *) * sz);
1917 Node **data = new (mem) Node *[sz];
1918 std::copy(begin, end, data);
1919 return NodeArray(data, sz);
1920 }
1921
1922 NodeArray popTrailingNodeArray(size_t FromPosition) {
1923 assert(FromPosition <= Names.size());
1924 NodeArray res =
1925 makeNodeArray(Names.begin() + (long)FromPosition, Names.end());
1926 Names.dropBack(FromPosition);
1927 return res;
1928 }
1929
1930 bool consumeIf(StringView S) {
1931 if (StringView(First, Last).startsWith(S)) {
1932 First += S.size();
1933 return true;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001934 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001935 return false;
1936 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001937
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001938 bool consumeIf(char C) {
1939 if (First != Last && *First == C) {
1940 ++First;
1941 return true;
Erik Pilkington0024acd2017-07-28 00:43:49 +00001942 }
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001943 return false;
1944 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00001945
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001946 char consume() { return First != Last ? *First++ : '\0'; }
1947
1948 char look(unsigned Lookahead = 0) {
1949 if (static_cast<size_t>(Last - First) <= Lookahead)
1950 return '\0';
1951 return First[Lookahead];
1952 }
1953
1954 size_t numLeft() const { return static_cast<size_t>(Last - First); }
1955
1956 StringView parseNumber(bool AllowNegative = false);
1957 Qualifiers parseCVQualifiers();
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00001958 bool parsePositiveInteger(size_t *Out);
1959 StringView parseBareSourceName();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001960
1961 /// Parse the <expr> production.
1962 Node *parseExpr();
1963 Node *parsePrefixExpr(StringView Kind);
1964 Node *parseBinaryExpr(StringView Kind);
1965 Node *parseIntegerLiteral(StringView Lit);
1966 Node *parseExprPrimary();
1967 template <class Float> Node *parseFloatingLiteral();
1968 Node *parseFunctionParam();
1969 Node *parseNewExpr();
1970 Node *parseConversionExpr();
1971
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00001972 /// Parse the <type> production.
1973 Node *parseType();
1974 Node *parseFunctionType();
1975 Node *parseVectorType();
1976 Node *parseDecltype();
1977 Node *parseArrayType();
1978 Node *parsePointerToMemberType();
1979 Node *parseClassEnumType();
1980
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00001981 // FIXME: remove this when all the parse_* functions have been rewritten.
1982 template <const char *(*parse_fn)(const char *, const char *, Db &)>
1983 Node *legacyParse() {
1984 size_t BeforeType = Names.size();
1985 const char *OrigFirst = First;
1986 const char *T = parse_fn(First, Last, *this);
1987 if (T == OrigFirst || BeforeType + 1 != Names.size())
1988 return nullptr;
1989 First = T;
1990 Node *R = Names.back();
1991 Names.pop_back();
1992 return R;
1993 }
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00001994 template <const char *(*parse_fn)(const char *, const char *, Db &, bool *)>
1995 Node *legacyParse() {
1996 size_t BeforeType = Names.size();
1997 const char *OrigFirst = First;
1998 const char *T = parse_fn(First, Last, *this, nullptr);
1999 if (T == OrigFirst || BeforeType + 1 != Names.size())
2000 return nullptr;
2001 First = T;
2002 Node *R = Names.back();
2003 Names.pop_back();
2004 return R;
2005 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00002006};
Erik Pilkingtonc3926622017-07-08 18:54:08 +00002007
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002008const char *parse_expression(const char *first, const char *last, Db &db) {
2009 db.First = first;
2010 db.Last = last;
2011 Node *R = db.parseExpr();
2012 if (R == nullptr)
2013 return first;
2014 db.Names.push_back(R);
2015 return db.First;
2016}
2017
2018const char *parse_expr_primary(const char *first, const char *last, Db &db) {
2019 db.First = first;
2020 db.Last = last;
2021 Node *R = db.parseExprPrimary();
2022 if (R == nullptr)
2023 return first;
2024 db.Names.push_back(R);
2025 return db.First;
2026}
2027
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002028const char *parse_type(const char *first, const char *last, Db &db) {
2029 db.First = first;
2030 db.Last = last;
2031 Node *R = db.parseType();
2032 if (R == nullptr)
2033 return first;
2034 db.Names.push_back(R);
2035 return db.First;
2036}
2037
2038const char *parse_decltype(const char *first, const char *last, Db &db) {
2039 db.First = first;
2040 db.Last = last;
2041 Node *R = db.parseDecltype();
2042 if (R == nullptr)
2043 return first;
2044 db.Names.push_back(R);
2045 return db.First;
2046}
2047
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002048const char *parse_type(const char *first, const char *last, Db &db);
2049const char *parse_encoding(const char *first, const char *last, Db &db);
2050const char *parse_name(const char *first, const char *last, Db &db,
2051 bool *ends_with_template_args = 0);
2052const char *parse_template_args(const char *first, const char *last, Db &db);
2053const char *parse_template_param(const char *, const char *, Db &);
2054const char *parse_operator_name(const char *first, const char *last, Db &db);
2055const char *parse_unqualified_name(const char *first, const char *last, Db &db);
2056const char *parse_decltype(const char *first, const char *last, Db &db);
2057const char *parse_unresolved_name(const char *, const char *, Db &);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002058const char *parse_substitution(const char *, const char *, Db &);
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002059
2060// <number> ::= [n] <non-negative decimal integer>
2061StringView Db::parseNumber(bool AllowNegative) {
2062 const char *Tmp = First;
2063 if (AllowNegative)
2064 consumeIf('n');
2065 if (numLeft() == 0 || !std::isdigit(*First))
2066 return StringView();
2067 while (numLeft() != 0 && std::isdigit(*First))
2068 ++First;
2069 return StringView(Tmp, First);
2070}
2071
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002072// <positive length number> ::= [0-9]*
2073bool Db::parsePositiveInteger(size_t *Out) {
2074 *Out = 0;
2075 if (look() < '0' || look() > '9')
2076 return true;
2077 while (look() >= '0' && look() <= '9') {
2078 *Out *= 10;
2079 *Out += static_cast<size_t>(consume() - '0');
2080 }
2081 return false;
2082}
2083
2084StringView Db::parseBareSourceName() {
2085 size_t Int = 0;
2086 if (parsePositiveInteger(&Int) || numLeft() < Int)
2087 return StringView();
2088 StringView R(First, First + Int);
2089 First += Int;
2090 return R;
2091}
2092
2093// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
2094//
2095// <ref-qualifier> ::= R # & ref-qualifier
2096// <ref-qualifier> ::= O # && ref-qualifier
2097Node *Db::parseFunctionType() {
2098 if (!consumeIf('F'))
2099 return nullptr;
2100 consumeIf('Y'); // extern "C"
2101 Node *ReturnType = parseType();
2102 if (ReturnType == nullptr)
2103 return nullptr;
2104
2105 FunctionRefQual ReferenceQualifier = FrefQualNone;
2106 size_t ParamsBegin = Names.size();
2107 while (true) {
2108 if (consumeIf('E'))
2109 break;
2110 if (consumeIf('v'))
2111 continue;
2112 if (consumeIf("RE")) {
2113 ReferenceQualifier = FrefQualLValue;
2114 break;
2115 }
2116 if (consumeIf("OE")) {
2117 ReferenceQualifier = FrefQualRValue;
2118 break;
2119 }
2120 Node *T = parseType();
2121 if (T == nullptr)
2122 return nullptr;
2123 Names.push_back(T);
2124 }
2125
2126 NodeArray Params = popTrailingNodeArray(ParamsBegin);
2127 Node *Fn = make<FunctionType>(ReturnType, Params);
2128 if (ReferenceQualifier != FrefQualNone)
2129 Fn = make<FunctionRefQualType>(Fn, ReferenceQualifier);
2130 return Fn;
2131}
2132
2133// extension:
2134// <vector-type> ::= Dv <positive dimension number> _ <extended element type>
2135// ::= Dv [<dimension expression>] _ <element type>
2136// <extended element type> ::= <element type>
2137// ::= p # AltiVec vector pixel
2138Node *Db::parseVectorType() {
2139 if (!consumeIf("Dv"))
2140 return nullptr;
2141 if (look() >= '1' && look() <= '9') {
2142 StringView DimensionNumber = parseNumber();
2143 if (!consumeIf('_'))
2144 return nullptr;
2145 if (consumeIf('p'))
2146 return make<VectorType>(DimensionNumber);
2147 Node *ElemType = parseType();
2148 if (ElemType == nullptr)
2149 return nullptr;
2150 return make<VectorType>(ElemType, DimensionNumber);
2151 }
2152
2153 if (!consumeIf('_')) {
2154 Node *DimExpr = parseExpr();
2155 if (!DimExpr)
2156 return nullptr;
2157 if (!consumeIf('_'))
2158 return nullptr;
2159 Node *ElemType = parseType();
2160 if (!ElemType)
2161 return nullptr;
2162 return make<VectorType>(ElemType, DimExpr);
2163 }
2164 Node *ElemType = parseType();
2165 if (!ElemType)
2166 return nullptr;
2167 return make<VectorType>(ElemType, StringView());
2168}
2169
2170// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
2171// ::= DT <expression> E # decltype of an expression (C++0x)
2172Node *Db::parseDecltype() {
2173 if (!consumeIf('D'))
2174 return nullptr;
2175 if (!consumeIf('t') && !consumeIf('T'))
2176 return nullptr;
2177 Node *E = parseExpr();
2178 if (E == nullptr)
2179 return nullptr;
2180 if (!consumeIf('E'))
2181 return nullptr;
2182 return make<EnclosingExpr>("decltype(", E, ")");
2183}
2184
2185// <array-type> ::= A <positive dimension number> _ <element type>
2186// ::= A [<dimension expression>] _ <element type>
2187Node *Db::parseArrayType() {
2188 if (!consumeIf('A'))
2189 return nullptr;
2190
2191 if (std::isdigit(look())) {
2192 StringView Dimension = parseNumber();
2193 if (!consumeIf('_'))
2194 return nullptr;
2195 Node *Ty = parseType();
2196 if (Ty == nullptr)
2197 return nullptr;
2198 return make<ArrayType>(Ty, Dimension);
2199 }
2200
2201 if (!consumeIf('_')) {
2202 Node *DimExpr = parseExpr();
2203 if (DimExpr == nullptr)
2204 return nullptr;
2205 if (!consumeIf('_'))
2206 return nullptr;
2207 Node *ElementType = parseType();
2208 if (ElementType == nullptr)
2209 return nullptr;
2210 return make<ArrayType>(ElementType, DimExpr);
2211 }
2212
2213 Node *Ty = parseType();
2214 if (Ty == nullptr)
2215 return nullptr;
2216 return make<ArrayType>(Ty);
2217}
2218
2219// <pointer-to-member-type> ::= M <class type> <member type>
2220Node *Db::parsePointerToMemberType() {
2221 if (!consumeIf('M'))
2222 return nullptr;
2223 Node *ClassType = parseType();
2224 if (ClassType == nullptr)
2225 return nullptr;
2226 Node *MemberType = parseType();
2227 if (MemberType == nullptr)
2228 return nullptr;
2229 return make<PointerToMemberType>(ClassType, MemberType);
2230}
2231
2232// <class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
2233// ::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
2234// ::= Tu <name> # dependent elaborated type specifier using 'union'
2235// ::= Te <name> # dependent elaborated type specifier using 'enum'
2236Node *Db::parseClassEnumType() {
2237 // FIXME: try to parse the elaborated type specifiers here!
2238 return legacyParse<parse_name>();
2239}
2240
2241// <type> ::= <builtin-type>
2242// ::= <qualified-type>
2243// ::= <function-type>
2244// ::= <class-enum-type>
2245// ::= <array-type>
2246// ::= <pointer-to-member-type>
2247// ::= <template-param>
2248// ::= <template-template-param> <template-args>
2249// ::= <decltype>
2250// ::= P <type> # pointer
2251// ::= R <type> # l-value reference
2252// ::= O <type> # r-value reference (C++11)
2253// ::= C <type> # complex pair (C99)
2254// ::= G <type> # imaginary (C99)
2255// ::= <substitution> # See Compression below
2256// extension ::= U <objc-name> <objc-type> # objc-type<identifier>
2257// extension ::= <vector-type> # <vector-type> starts with Dv
2258//
2259// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
2260// <objc-type> ::= <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
2261Node *Db::parseType() {
2262 Node *Result = nullptr;
2263
2264 switch (look()) {
2265 // ::= <qualified-type>
2266 case 'r':
2267 case 'V':
2268 case 'K': {
2269 Qualifiers Q = parseCVQualifiers();
2270 bool AppliesToFunction = look() == 'F';
2271
2272 Node *Child = parseType();
2273 if (Child == nullptr)
2274 return nullptr;
2275
2276 if (AppliesToFunction)
2277 Result = make<FunctionQualType>(Child, Q);
2278 else
2279 Result = make<QualType>(Child, Q);
2280
2281 // Itanium C++ ABI 5.1.5.3:
2282 // For the purposes of substitution, the CV-qualifiers and ref-qualifier
2283 // of a function type are an indivisible part of the type.
2284 if (AppliesToFunction)
2285 return Result;
2286 break;
2287 }
2288 // <extended-qualifier> ::= U <source-name> [<template-args>] # vendor extended type qualifier
2289 case 'U': {
2290 // FIXME: We should fold this into the cvr qualifier parsing above. This
2291 // currently adds too many entries into the substitution table if multiple
2292 // qualifiers are present on the same type, as all the qualifiers on a type
2293 // should just get one entry in the substitution table.
2294 ++First;
2295 StringView Qual = parseBareSourceName();
2296 if (Qual.empty())
2297 return nullptr;
2298
2299 // FIXME parse the optional <template-args> here!
2300
2301 Result = parseType();
2302 if (Result == nullptr)
2303 return nullptr;
2304
2305 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
2306 if (Qual.startsWith("objcproto")) {
2307 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto"));
2308 StringView Proto;
2309 {
2310 SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()),
2311 SaveLast(Last, ProtoSourceName.end());
2312 Proto = parseBareSourceName();
2313 }
2314 if (Proto.empty())
2315 return nullptr;
2316 Result = make<ObjCProtoName>(Result, Proto);
2317 } else
2318 Result = make<VendorExtQualType>(Result, Qual);
2319 break;
2320 }
2321 // <builtin-type> ::= v # void
2322 case 'v':
2323 ++First;
2324 return make<NameType>("void");
2325 // ::= w # wchar_t
2326 case 'w':
2327 ++First;
2328 return make<NameType>("wchar_t");
2329 // ::= b # bool
2330 case 'b':
2331 ++First;
2332 return make<NameType>("bool");
2333 // ::= c # char
2334 case 'c':
2335 ++First;
2336 return make<NameType>("char");
2337 // ::= a # signed char
2338 case 'a':
2339 ++First;
2340 return make<NameType>("signed char");
2341 // ::= h # unsigned char
2342 case 'h':
2343 ++First;
2344 return make<NameType>("unsigned char");
2345 // ::= s # short
2346 case 's':
2347 ++First;
2348 return make<NameType>("short");
2349 // ::= t # unsigned short
2350 case 't':
2351 ++First;
2352 return make<NameType>("unsigned short");
2353 // ::= i # int
2354 case 'i':
2355 ++First;
2356 return make<NameType>("int");
2357 // ::= j # unsigned int
2358 case 'j':
2359 ++First;
2360 return make<NameType>("unsigned int");
2361 // ::= l # long
2362 case 'l':
2363 ++First;
2364 return make<NameType>("long");
2365 // ::= m # unsigned long
2366 case 'm':
2367 ++First;
2368 return make<NameType>("unsigned long");
2369 // ::= x # long long, __int64
2370 case 'x':
2371 ++First;
2372 return make<NameType>("long long");
2373 // ::= y # unsigned long long, __int64
2374 case 'y':
2375 ++First;
2376 return make<NameType>("unsigned long long");
2377 // ::= n # __int128
2378 case 'n':
2379 ++First;
2380 return make<NameType>("__int128");
2381 // ::= o # unsigned __int128
2382 case 'o':
2383 ++First;
2384 return make<NameType>("unsigned __int128");
2385 // ::= f # float
2386 case 'f':
2387 ++First;
2388 return make<NameType>("float");
2389 // ::= d # double
2390 case 'd':
2391 ++First;
2392 return make<NameType>("double");
2393 // ::= e # long double, __float80
2394 case 'e':
2395 ++First;
2396 return make<NameType>("long double");
2397 // ::= g # __float128
2398 case 'g':
2399 ++First;
2400 return make<NameType>("__float128");
2401 // ::= z # ellipsis
2402 case 'z':
2403 ++First;
2404 return make<NameType>("...");
2405
2406 // <builtin-type> ::= u <source-name> # vendor extended type
2407 case 'u': {
2408 ++First;
2409 StringView Res = parseBareSourceName();
2410 if (Res.empty())
2411 return nullptr;
2412 return make<NameType>(Res);
2413 }
2414 case 'D':
2415 switch (look(1)) {
2416 // ::= Dd # IEEE 754r decimal floating point (64 bits)
2417 case 'd':
2418 First += 2;
2419 return make<NameType>("decimal64");
2420 // ::= De # IEEE 754r decimal floating point (128 bits)
2421 case 'e':
2422 First += 2;
2423 return make<NameType>("decimal128");
2424 // ::= Df # IEEE 754r decimal floating point (32 bits)
2425 case 'f':
2426 First += 2;
2427 return make<NameType>("decimal32");
2428 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
2429 case 'h':
2430 First += 2;
2431 return make<NameType>("decimal16");
2432 // ::= Di # char32_t
2433 case 'i':
2434 First += 2;
2435 return make<NameType>("char32_t");
2436 // ::= Ds # char16_t
2437 case 's':
2438 First += 2;
2439 return make<NameType>("char16_t");
2440 // ::= Da # auto (in dependent new-expressions)
2441 case 'a':
2442 First += 2;
2443 return make<NameType>("auto");
2444 // ::= Dc # decltype(auto)
2445 case 'c':
2446 First += 2;
2447 return make<NameType>("decltype(auto)");
2448 // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
2449 case 'n':
2450 First += 2;
2451 return make<NameType>("std::nullptr_t");
2452
2453 // ::= <decltype>
2454 case 't':
2455 case 'T': {
2456 Result = parseDecltype();
2457 break;
2458 }
2459 // extension ::= <vector-type> # <vector-type> starts with Dv
2460 case 'v': {
2461 Result = parseVectorType();
2462 break;
2463 }
2464 // ::= Dp <type> # pack expansion (C++0x)
2465 case 'p': {
2466 First += 2;
2467 Node *Child = parseType();
2468 if (!Child)
2469 return nullptr;
2470 Result = make<ParameterPackExpansion>(Child);
2471 break;
2472 }
2473 }
2474 break;
2475 // ::= <function-type>
2476 case 'F': {
2477 Result = parseFunctionType();
2478 break;
2479 }
2480 // ::= <array-type>
2481 case 'A': {
2482 Result = parseArrayType();
2483 break;
2484 }
2485 // ::= <pointer-to-member-type>
2486 case 'M': {
2487 Result = parsePointerToMemberType();
2488 break;
2489 }
2490 // ::= <template-param>
2491 case 'T': {
2492 Result = legacyParse<parse_template_param>();
2493 if (Result == nullptr)
2494 return nullptr;
2495
2496 // Result could be either of:
2497 // <type> ::= <template-param>
2498 // <type> ::= <template-template-param> <template-args>
2499 //
2500 // <template-template-param> ::= <template-param>
2501 // ::= <substitution>
2502 //
2503 // If this is followed by some <template-args>, and we're permitted to
2504 // parse them, take the second production.
2505
2506 if (TryToParseTemplateArgs && look() == 'I') {
2507 Node *TA = legacyParse<parse_template_args>();
2508 if (TA == nullptr)
2509 return nullptr;
2510 Result = make<NameWithTemplateArgs>(Result, TA);
2511 }
2512 break;
2513 }
2514 // ::= P <type> # pointer
2515 case 'P': {
2516 ++First;
2517 Node *Ptr = parseType();
2518 if (Ptr == nullptr)
2519 return nullptr;
2520 Result = make<PointerType>(Ptr);
2521 break;
2522 }
2523 // ::= R <type> # l-value reference
2524 case 'R': {
2525 ++First;
2526 Node *Ref = parseType();
2527 if (Ref == nullptr)
2528 return nullptr;
2529 Result = make<LValueReferenceType>(Ref);
2530 break;
2531 }
2532 // ::= O <type> # r-value reference (C++11)
2533 case 'O': {
2534 ++First;
2535 Node *Ref = parseType();
2536 if (Ref == nullptr)
2537 return nullptr;
2538 Result = make<RValueReferenceType>(Ref);
2539 break;
2540 }
2541 // ::= C <type> # complex pair (C99)
2542 case 'C': {
2543 ++First;
2544 Node *P = parseType();
2545 if (P == nullptr)
2546 return nullptr;
2547 Result = make<PostfixQualifiedType>(P, " complex");
2548 break;
2549 }
2550 // ::= G <type> # imaginary (C99)
2551 case 'G': {
2552 ++First;
2553 Node *P = parseType();
2554 if (P == nullptr)
2555 return P;
2556 Result = make<PostfixQualifiedType>(P, " imaginary");
2557 break;
2558 }
2559 // ::= <substitution> # See Compression below
2560 case 'S': {
2561 if (look(1) && look(1) != 't') {
2562 Node *Sub = legacyParse<parse_substitution>();
2563 if (Sub == nullptr)
2564 return nullptr;
2565
2566 // Sub could be either of:
2567 // <type> ::= <substitution>
2568 // <type> ::= <template-template-param> <template-args>
2569 //
2570 // <template-template-param> ::= <template-param>
2571 // ::= <substitution>
2572 //
2573 // If this is followed by some <template-args>, and we're permitted to
2574 // parse them, take the second production.
2575
2576 if (TryToParseTemplateArgs && look() == 'I') {
2577 Node *TA = legacyParse<parse_template_args>();
2578 if (TA == nullptr)
2579 return nullptr;
2580 Result = make<NameWithTemplateArgs>(Sub, TA);
2581 break;
2582 }
2583
2584 // If all we parsed was a substitution, don't re-insert into the
2585 // substitution table.
2586 return Sub;
2587 }
2588 _LIBCPP_FALLTHROUGH();
2589 }
2590 // ::= <class-enum-type>
2591 default: {
2592 Result = parseClassEnumType();
2593 break;
2594 }
2595 }
2596
2597 // If we parsed a type, insert it into the substitution table. Note that all
2598 // <builtin-type>s and <substitution>s have already bailed out, because they
2599 // don't get substitutions.
2600 if (Result != nullptr)
2601 Subs.push_back(Result);
2602 return Result;
2603}
2604
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002605Node *Db::parsePrefixExpr(StringView Kind) {
2606 Node *E = parseExpr();
2607 if (E == nullptr)
2608 return nullptr;
2609 return make<PrefixExpr>(Kind, E);
2610}
2611
2612Node *Db::parseBinaryExpr(StringView Kind) {
2613 Node *LHS = parseExpr();
2614 if (LHS == nullptr)
2615 return nullptr;
2616 Node *RHS = parseExpr();
2617 if (RHS == nullptr)
2618 return nullptr;
2619 return make<BinaryExpr>(LHS, Kind, RHS);
2620}
2621
2622Node *Db::parseIntegerLiteral(StringView Lit) {
2623 StringView Tmp = parseNumber(true);
2624 if (!Tmp.empty() && consumeIf('E'))
2625 return make<IntegerExpr>(Lit, Tmp);
2626 return nullptr;
2627}
2628
2629Qualifiers Db::parseCVQualifiers() {
2630 Qualifiers CVR = QualNone;
2631 if (consumeIf('r'))
2632 addQualifiers(CVR, QualRestrict);
2633 if (consumeIf('V'))
2634 addQualifiers(CVR, QualVolatile);
2635 if (consumeIf('K'))
2636 addQualifiers(CVR, QualConst);
2637 return CVR;
2638}
2639
2640// <function-param> ::= fp <top-level CV-Qualifiers> _ # L == 0, first parameter
2641// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
2642// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
2643// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
2644Node *Db::parseFunctionParam() {
2645 if (consumeIf("fp")) {
2646 parseCVQualifiers();
2647 StringView Num = parseNumber();
2648 if (!consumeIf('_'))
2649 return nullptr;
2650 return make<FunctionParam>(Num);
2651 }
2652 if (consumeIf("fL")) {
2653 if (parseNumber().empty())
2654 return nullptr;
2655 if (!consumeIf('p'))
2656 return nullptr;
2657 parseCVQualifiers();
2658 StringView Num = parseNumber();
2659 if (!consumeIf('_'))
2660 return nullptr;
2661 return make<FunctionParam>(Num);
2662 }
2663 return nullptr;
2664}
2665
2666// [gs] nw <expression>* _ <type> E # new (expr-list) type
2667// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
2668// [gs] na <expression>* _ <type> E # new[] (expr-list) type
2669// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
2670// <initializer> ::= pi <expression>* E # parenthesized initialization
2671Node *Db::parseNewExpr() {
2672 bool Global = consumeIf("gs");
2673 bool IsArray = look(1) == 'a';
2674 if (!consumeIf("nw") && !consumeIf("na"))
2675 return nullptr;
2676 size_t Exprs = Names.size();
2677 while (!consumeIf('_')) {
2678 Node *Ex = parseExpr();
2679 if (Ex == nullptr)
2680 return nullptr;
2681 Names.push_back(Ex);
2682 }
2683 NodeArray ExprList = popTrailingNodeArray(Exprs);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002684 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002685 if (Ty == nullptr)
2686 return Ty;
2687 if (consumeIf("pi")) {
2688 size_t InitsBegin = Names.size();
2689 while (!consumeIf('E')) {
2690 Node *Init = parseExpr();
2691 if (Init == nullptr)
2692 return Init;
2693 Names.push_back(Init);
2694 }
2695 NodeArray Inits = popTrailingNodeArray(InitsBegin);
2696 return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray);
2697 } else if (!consumeIf('E'))
2698 return nullptr;
2699 return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray);
2700}
2701
2702// cv <type> <expression> # conversion with one argument
2703// cv <type> _ <expression>* E # conversion with a different number of arguments
2704Node *Db::parseConversionExpr() {
2705 if (!consumeIf("cv"))
2706 return nullptr;
2707 Node *Ty;
2708 {
2709 SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false);
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002710 Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002711 }
2712
2713 if (Ty == nullptr)
2714 return nullptr;
2715
2716 if (consumeIf('_')) {
2717 size_t ExprsBegin = Names.size();
2718 while (!consumeIf('E')) {
2719 Node *E = parseExpr();
2720 if (E == nullptr)
2721 return E;
2722 Names.push_back(E);
2723 }
2724 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
2725 return make<ConversionExpr>(Ty, Exprs);
2726 }
2727
2728 Node *E[1] = {parseExpr()};
2729 if (E[0] == nullptr)
2730 return nullptr;
2731 return make<ConversionExpr>(Ty, makeNodeArray(E, E + 1));
2732}
2733
2734// <expr-primary> ::= L <type> <value number> E # integer literal
2735// ::= L <type> <value float> E # floating literal
2736// ::= L <string type> E # string literal
2737// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
2738// FIXME: ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
2739// ::= L <mangled-name> E # external name
2740Node *Db::parseExprPrimary() {
2741 if (!consumeIf('L'))
2742 return nullptr;
2743 switch (look()) {
2744 case 'w':
2745 ++First;
2746 return parseIntegerLiteral("wchar_t");
2747 case 'b':
2748 if (consumeIf("b0E"))
2749 return make<BoolExpr>(0);
2750 if (consumeIf("b1E"))
2751 return make<BoolExpr>(1);
2752 return nullptr;
2753 case 'c':
2754 ++First;
2755 return parseIntegerLiteral("char");
2756 case 'a':
2757 ++First;
2758 return parseIntegerLiteral("signed char");
2759 case 'h':
2760 ++First;
2761 return parseIntegerLiteral("unsigned char");
2762 case 's':
2763 ++First;
2764 return parseIntegerLiteral("short");
2765 case 't':
2766 ++First;
2767 return parseIntegerLiteral("unsigned short");
2768 case 'i':
2769 ++First;
2770 return parseIntegerLiteral("");
2771 case 'j':
2772 ++First;
2773 return parseIntegerLiteral("u");
2774 case 'l':
2775 ++First;
2776 return parseIntegerLiteral("l");
2777 case 'm':
2778 ++First;
2779 return parseIntegerLiteral("ul");
2780 case 'x':
2781 ++First;
2782 return parseIntegerLiteral("ll");
2783 case 'y':
2784 ++First;
2785 return parseIntegerLiteral("ull");
2786 case 'n':
2787 ++First;
2788 return parseIntegerLiteral("__int128");
2789 case 'o':
2790 ++First;
2791 return parseIntegerLiteral("unsigned __int128");
2792 case 'f':
2793 ++First;
2794 return parseFloatingLiteral<float>();
2795 case 'd':
2796 ++First;
2797 return parseFloatingLiteral<double>();
2798 case 'e':
2799 ++First;
2800 return parseFloatingLiteral<long double>();
2801 case '_':
2802 if (consumeIf("_Z")) {
2803 Node *R = legacyParse<parse_encoding>();
2804 if (R != nullptr && consumeIf('E'))
2805 return R;
2806 }
2807 return nullptr;
2808 case 'T':
2809 // Invalid mangled name per
2810 // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
2811 return nullptr;
2812 default: {
2813 // might be named type
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002814 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002815 if (T == nullptr)
2816 return nullptr;
2817 StringView N = parseNumber();
2818 if (!N.empty()) {
2819 if (!consumeIf('E'))
2820 return nullptr;
2821 return make<IntegerCastExpr>(T, N);
2822 }
2823 if (consumeIf('E'))
2824 return T;
2825 return nullptr;
2826 }
2827 }
2828}
2829
2830// <expression> ::= <unary operator-name> <expression>
2831// ::= <binary operator-name> <expression> <expression>
2832// ::= <ternary operator-name> <expression> <expression> <expression>
2833// ::= cl <expression>+ E # call
2834// ::= cv <type> <expression> # conversion with one argument
2835// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
2836// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
2837// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
2838// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
2839// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
2840// ::= [gs] dl <expression> # delete expression
2841// ::= [gs] da <expression> # delete[] expression
2842// ::= pp_ <expression> # prefix ++
2843// ::= mm_ <expression> # prefix --
2844// ::= ti <type> # typeid (type)
2845// ::= te <expression> # typeid (expression)
2846// ::= dc <type> <expression> # dynamic_cast<type> (expression)
2847// ::= sc <type> <expression> # static_cast<type> (expression)
2848// ::= cc <type> <expression> # const_cast<type> (expression)
2849// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
2850// ::= st <type> # sizeof (a type)
2851// ::= sz <expression> # sizeof (an expression)
2852// ::= at <type> # alignof (a type)
2853// ::= az <expression> # alignof (an expression)
2854// ::= nx <expression> # noexcept (expression)
2855// ::= <template-param>
2856// ::= <function-param>
2857// ::= dt <expression> <unresolved-name> # expr.name
2858// ::= pt <expression> <unresolved-name> # expr->name
2859// ::= ds <expression> <expression> # expr.*expr
2860// ::= sZ <template-param> # size of a parameter pack
2861// ::= sZ <function-param> # size of a function parameter pack
2862// ::= sp <expression> # pack expansion
2863// ::= tw <expression> # throw expression
2864// ::= tr # throw with no operand (rethrow)
2865// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
2866// # freestanding dependent name (e.g., T::x),
2867// # objectless nonstatic member reference
2868// ::= fL <binary-operator-name> <expression> <expression>
2869// ::= fR <binary-operator-name> <expression> <expression>
2870// ::= fl <binary-operator-name> <expression>
2871// ::= fr <binary-operator-name> <expression>
2872// ::= <expr-primary>
2873Node *Db::parseExpr() {
2874 bool Global = consumeIf("gs");
2875 if (numLeft() < 2)
2876 return nullptr;
2877
2878 switch (*First) {
2879 case 'L':
2880 return parseExprPrimary();
2881 case 'T':
2882 return legacyParse<parse_template_param>();
2883 case 'f':
2884 return parseFunctionParam();
2885 case 'a':
2886 switch (First[1]) {
2887 case 'a':
2888 First += 2;
2889 return parseBinaryExpr("&&");
2890 case 'd':
2891 First += 2;
2892 return parsePrefixExpr("&");
2893 case 'n':
2894 First += 2;
2895 return parseBinaryExpr("&");
2896 case 'N':
2897 First += 2;
2898 return parseBinaryExpr("&=");
2899 case 'S':
2900 First += 2;
2901 return parseBinaryExpr("=");
2902 case 't': {
2903 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002904 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002905 if (Ty == nullptr)
2906 return nullptr;
2907 return make<EnclosingExpr>("alignof (", Ty, ")");
2908 }
2909 case 'z': {
2910 First += 2;
2911 Node *Ty = parseExpr();
2912 if (Ty == nullptr)
2913 return nullptr;
2914 return make<EnclosingExpr>("alignof (", Ty, ")");
2915 }
2916 }
2917 return nullptr;
2918 case 'c':
2919 switch (First[1]) {
2920 // cc <type> <expression> # const_cast<type>(expression)
2921 case 'c': {
2922 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002923 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002924 if (Ty == nullptr)
2925 return Ty;
2926 Node *Ex = parseExpr();
2927 if (Ex == nullptr)
2928 return Ex;
2929 return make<CastExpr>("const_cast", Ty, Ex);
2930 }
2931 // cl <expression>+ E # call
2932 case 'l': {
2933 First += 2;
2934 Node *Callee = parseExpr();
2935 if (Callee == nullptr)
2936 return Callee;
2937 size_t ExprsBegin = Names.size();
2938 while (!consumeIf('E')) {
2939 Node *E = parseExpr();
2940 if (E == nullptr)
2941 return E;
2942 Names.push_back(E);
2943 }
2944 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin));
2945 }
2946 case 'm':
2947 First += 2;
2948 return parseBinaryExpr(",");
2949 case 'o':
2950 First += 2;
2951 return parsePrefixExpr("~");
2952 case 'v':
2953 return parseConversionExpr();
2954 }
2955 return nullptr;
2956 case 'd':
2957 switch (First[1]) {
2958 case 'a': {
2959 First += 2;
2960 Node *Ex = parseExpr();
2961 if (Ex == nullptr)
2962 return Ex;
2963 return make<DeleteExpr>(Ex, Global, /*is_array=*/true);
2964 }
2965 case 'c': {
2966 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00002967 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00002968 if (T == nullptr)
2969 return T;
2970 Node *Ex = parseExpr();
2971 if (Ex == nullptr)
2972 return Ex;
2973 return make<CastExpr>("dynamic_cast", T, Ex);
2974 }
2975 case 'e':
2976 First += 2;
2977 return parsePrefixExpr("*");
2978 case 'l': {
2979 First += 2;
2980 Node *E = parseExpr();
2981 if (E == nullptr)
2982 return E;
2983 return make<DeleteExpr>(E, Global, /*is_array=*/false);
2984 }
2985 case 'n':
2986 return legacyParse<parse_unresolved_name>();
2987 case 's': {
2988 First += 2;
2989 Node *LHS = parseExpr();
2990 if (LHS == nullptr)
2991 return nullptr;
2992 Node *RHS = parseExpr();
2993 if (RHS == nullptr)
2994 return nullptr;
2995 return make<MemberExpr>(LHS, ".*", RHS);
2996 }
2997 case 't': {
2998 First += 2;
2999 Node *LHS = parseExpr();
3000 if (LHS == nullptr)
3001 return LHS;
3002 Node *RHS = parseExpr();
3003 if (RHS == nullptr)
3004 return nullptr;
3005 return make<MemberExpr>(LHS, ".", RHS);
3006 }
3007 case 'v':
3008 First += 2;
3009 return parseBinaryExpr("/");
3010 case 'V':
3011 First += 2;
3012 return parseBinaryExpr("/=");
3013 }
3014 return nullptr;
3015 case 'e':
3016 switch (First[1]) {
3017 case 'o':
3018 First += 2;
3019 return parseBinaryExpr("^");
3020 case 'O':
3021 First += 2;
3022 return parseBinaryExpr("^=");
3023 case 'q':
3024 First += 2;
3025 return parseBinaryExpr("==");
3026 }
3027 return nullptr;
3028 case 'g':
3029 switch (First[1]) {
3030 case 'e':
3031 First += 2;
3032 return parseBinaryExpr(">=");
3033 case 't':
3034 First += 2;
3035 return parseBinaryExpr(">");
3036 }
3037 return nullptr;
3038 case 'i':
3039 if (First[1] == 'x') {
3040 First += 2;
3041 Node *Base = parseExpr();
3042 if (Base == nullptr)
3043 return nullptr;
3044 Node *Index = parseExpr();
3045 if (Index == nullptr)
3046 return Index;
3047 return make<ArraySubscriptExpr>(Base, Index);
3048 }
3049 return nullptr;
3050 case 'l':
3051 switch (First[1]) {
3052 case 'e':
3053 First += 2;
3054 return parseBinaryExpr("<=");
3055 case 's':
3056 First += 2;
3057 return parseBinaryExpr("<<");
3058 case 'S':
3059 First += 2;
3060 return parseBinaryExpr("<<=");
3061 case 't':
3062 First += 2;
3063 return parseBinaryExpr("<");
3064 }
3065 return nullptr;
3066 case 'm':
3067 switch (First[1]) {
3068 case 'i':
3069 First += 2;
3070 return parseBinaryExpr("-");
3071 case 'I':
3072 First += 2;
3073 return parseBinaryExpr("-=");
3074 case 'l':
3075 First += 2;
3076 return parseBinaryExpr("*");
3077 case 'L':
3078 First += 2;
3079 return parseBinaryExpr("*=");
3080 case 'm':
3081 First += 2;
3082 if (consumeIf('_'))
3083 return parsePrefixExpr("--");
3084 Node *Ex = parseExpr();
3085 if (Ex == nullptr)
3086 return nullptr;
3087 return make<PostfixExpr>(Ex, "--");
3088 }
3089 return nullptr;
3090 case 'n':
3091 switch (First[1]) {
3092 case 'a':
3093 case 'w':
3094 return parseNewExpr();
3095 case 'e':
3096 First += 2;
3097 return parseBinaryExpr("!=");
3098 case 'g':
3099 First += 2;
3100 return parsePrefixExpr("-");
3101 case 't':
3102 First += 2;
3103 return parsePrefixExpr("!");
3104 case 'x':
3105 First += 2;
3106 Node *Ex = parseExpr();
3107 if (Ex == nullptr)
3108 return Ex;
3109 return make<EnclosingExpr>("noexcept (", Ex, ")");
3110 }
3111 return nullptr;
3112 case 'o':
3113 switch (First[1]) {
3114 case 'n':
3115 return legacyParse<parse_unresolved_name>();
3116 case 'o':
3117 First += 2;
3118 return parseBinaryExpr("||");
3119 case 'r':
3120 First += 2;
3121 return parseBinaryExpr("|");
3122 case 'R':
3123 First += 2;
3124 return parseBinaryExpr("|=");
3125 }
3126 return nullptr;
3127 case 'p':
3128 switch (First[1]) {
3129 case 'm':
3130 First += 2;
3131 return parseBinaryExpr("->*");
3132 case 'l':
3133 First += 2;
3134 return parseBinaryExpr("+");
3135 case 'L':
3136 First += 2;
3137 return parseBinaryExpr("+=");
3138 case 'p': {
3139 First += 2;
3140 if (consumeIf('_'))
3141 return parsePrefixExpr("++");
3142 Node *Ex = parseExpr();
3143 if (Ex == nullptr)
3144 return Ex;
3145 return make<PostfixExpr>(Ex, "++");
3146 }
3147 case 's':
3148 First += 2;
3149 return parsePrefixExpr("+");
3150 case 't': {
3151 First += 2;
3152 Node *L = parseExpr();
3153 if (L == nullptr)
3154 return nullptr;
3155 Node *R = parseExpr();
3156 if (R == nullptr)
3157 return nullptr;
3158 return make<MemberExpr>(L, "->", R);
3159 }
3160 }
3161 return nullptr;
3162 case 'q':
3163 if (First[1] == 'u') {
3164 First += 2;
3165 Node *Cond = parseExpr();
Erik Pilkington24e8b732018-02-05 02:34:41 +00003166 if (Cond == nullptr)
3167 return nullptr;
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003168 Node *LHS = parseExpr();
Erik Pilkington24e8b732018-02-05 02:34:41 +00003169 if (LHS == nullptr)
3170 return nullptr;
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003171 Node *RHS = parseExpr();
Erik Pilkington24e8b732018-02-05 02:34:41 +00003172 if (RHS == nullptr)
3173 return nullptr;
3174 return make<ConditionalExpr>(Cond, LHS, RHS);
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003175 }
3176 return nullptr;
3177 case 'r':
3178 switch (First[1]) {
3179 case 'c': {
3180 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003181 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003182 if (T == nullptr)
3183 return T;
3184 Node *Ex = parseExpr();
3185 if (Ex == nullptr)
3186 return Ex;
3187 return make<CastExpr>("reinterpret_cast", T, Ex);
3188 }
3189 case 'm':
3190 First += 2;
3191 return parseBinaryExpr("%");
3192 case 'M':
3193 First += 2;
3194 return parseBinaryExpr("%=");
3195 case 's':
3196 First += 2;
3197 return parseBinaryExpr(">>");
3198 case 'S':
3199 First += 2;
3200 return parseBinaryExpr(">>=");
3201 }
3202 return nullptr;
3203 case 's':
3204 switch (First[1]) {
3205 case 'c': {
3206 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003207 Node *T = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003208 if (T == nullptr)
3209 return T;
3210 Node *Ex = parseExpr();
3211 if (Ex == nullptr)
3212 return Ex;
3213 return make<CastExpr>("static_cast", T, Ex);
3214 }
3215 case 'p': {
3216 First += 2;
3217 Node *Child = parseExpr();
3218 if (Child == nullptr)
3219 return nullptr;
3220 return make<ParameterPackExpansion>(Child);
3221 }
3222 case 'r':
3223 return legacyParse<parse_unresolved_name>();
3224 case 't': {
3225 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003226 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003227 if (Ty == nullptr)
3228 return Ty;
3229 return make<EnclosingExpr>("sizeof (", Ty, ")");
3230 }
3231 case 'z': {
3232 First += 2;
3233 Node *Ex = parseExpr();
3234 if (Ex == nullptr)
3235 return Ex;
3236 return make<EnclosingExpr>("sizeof (", Ex, ")");
3237 }
3238 case 'Z':
3239 First += 2;
3240 if (look() == 'T') {
3241 Node *R = legacyParse<parse_template_param>();
3242 if (R == nullptr)
3243 return nullptr;
3244 return make<SizeofParamPackExpr>(R);
3245 } else if (look() == 'f') {
3246 Node *FP = parseFunctionParam();
3247 if (FP == nullptr)
3248 return nullptr;
3249 return make<EnclosingExpr>("sizeof...", FP, ")");
3250 }
3251 return nullptr;
3252 }
3253 return nullptr;
3254 case 't':
3255 switch (First[1]) {
3256 case 'e': {
3257 First += 2;
3258 Node *Ex = parseExpr();
3259 if (Ex == nullptr)
3260 return Ex;
3261 return make<EnclosingExpr>("typeid (", Ex, ")");
3262 }
3263 case 'i': {
3264 First += 2;
Erik Pilkingtonf23deca2018-02-05 22:41:20 +00003265 Node *Ty = parseType();
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003266 if (Ty == nullptr)
3267 return Ty;
3268 return make<EnclosingExpr>("typeid (", Ty, ")");
3269 }
3270 case 'r':
3271 First += 2;
3272 return make<NameType>("throw");
3273 case 'w': {
3274 First += 2;
3275 Node *Ex = parseExpr();
3276 if (Ex == nullptr)
3277 return nullptr;
3278 return make<ThrowExpr>(Ex);
3279 }
3280 }
3281 return nullptr;
3282 case '1':
3283 case '2':
3284 case '3':
3285 case '4':
3286 case '5':
3287 case '6':
3288 case '7':
3289 case '8':
3290 case '9':
3291 return legacyParse<parse_unresolved_name>();
3292 }
3293 return nullptr;
3294}
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003295
Howard Hinnant6c33e762013-06-17 18:10:34 +00003296// <number> ::= [n] <non-negative decimal integer>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003297
3298const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00003299parse_number(const char* first, const char* last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003300{
Howard Hinnant6c33e762013-06-17 18:10:34 +00003301 if (first != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003302 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003303 const char* t = first;
3304 if (*t == 'n')
3305 ++t;
3306 if (t != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003307 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003308 if (*t == '0')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003309 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003310 first = t+1;
3311 }
3312 else if ('1' <= *t && *t <= '9')
3313 {
3314 first = t+1;
3315 while (first != last && std::isdigit(*first))
3316 ++first;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003317 }
3318 }
3319 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003320 return first;
3321}
3322
3323template <class Float>
Erik Pilkington0024acd2017-07-28 00:43:49 +00003324struct FloatData;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003325
3326template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00003327struct FloatData<float>
Howard Hinnant6c33e762013-06-17 18:10:34 +00003328{
3329 static const size_t mangled_size = 8;
3330 static const size_t max_demangled_size = 24;
Howard Hinnantc62cbea2013-06-17 20:25:21 +00003331 static constexpr const char* spec = "%af";
Howard Hinnant6c33e762013-06-17 18:10:34 +00003332};
3333
Erik Pilkington0024acd2017-07-28 00:43:49 +00003334constexpr const char* FloatData<float>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003335
3336template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00003337struct FloatData<double>
Howard Hinnant6c33e762013-06-17 18:10:34 +00003338{
3339 static const size_t mangled_size = 16;
3340 static const size_t max_demangled_size = 32;
3341 static constexpr const char* spec = "%a";
Howard Hinnant6c33e762013-06-17 18:10:34 +00003342};
3343
Erik Pilkington0024acd2017-07-28 00:43:49 +00003344constexpr const char* FloatData<double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003345
3346template <>
Erik Pilkington0024acd2017-07-28 00:43:49 +00003347struct FloatData<long double>
Howard Hinnant6c33e762013-06-17 18:10:34 +00003348{
Dan Gohmand04ecd02016-01-13 16:39:30 +00003349#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
3350 defined(__wasm__)
Daniel Sanders52cf98b2015-07-30 16:11:04 +00003351 static const size_t mangled_size = 32;
Ben Craig9ef2c6e2016-01-20 14:10:23 +00003352#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
Logan Chien05d51bc2014-05-10 00:42:10 +00003353 static const size_t mangled_size = 16;
3354#else
Howard Hinnant6c33e762013-06-17 18:10:34 +00003355 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 +00003356#endif
Howard Hinnant6c33e762013-06-17 18:10:34 +00003357 static const size_t max_demangled_size = 40;
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003358 static constexpr const char *spec = "%LaL";
Howard Hinnant6c33e762013-06-17 18:10:34 +00003359};
3360
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003361constexpr const char *FloatData<long double>::spec;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003362
Erik Pilkingtonb679cfd2018-02-02 18:04:32 +00003363template <class Float> Node *Db::parseFloatingLiteral() {
3364 const size_t N = FloatData<Float>::mangled_size;
3365 if (numLeft() <= N)
3366 return nullptr;
3367 StringView Data(First, First + N);
3368 for (char C : Data)
3369 if (!std::isxdigit(C))
3370 return nullptr;
3371 First += N;
3372 if (!consumeIf('E'))
3373 return nullptr;
3374 return make<FloatExpr<Float>>(Data);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003375}
3376
Erik Pilkington5bff4122017-11-22 20:38:22 +00003377// <positive length number> ::= [0-9]*
Howard Hinnant6c33e762013-06-17 18:10:34 +00003378const char*
Erik Pilkington5bff4122017-11-22 20:38:22 +00003379parse_positive_integer(const char* first, const char* last, size_t* out)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003380{
3381 if (first != last)
3382 {
3383 char c = *first;
3384 if (isdigit(c) && first+1 != last)
3385 {
3386 const char* t = first+1;
3387 size_t n = static_cast<size_t>(c - '0');
3388 for (c = *t; isdigit(c); c = *t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003389 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003390 n = n * 10 + static_cast<size_t>(c - '0');
3391 if (++t == last)
3392 return first;
3393 }
Erik Pilkington5bff4122017-11-22 20:38:22 +00003394 *out = n;
3395 first = t;
3396 }
3397 }
3398 return first;
3399}
3400
3401// extension
3402// <abi-tag-seq> ::= <abi-tag>*
3403// <abi-tag> ::= B <positive length number> <identifier>
3404const char*
3405parse_abi_tag_seq(const char* first, const char* last, Db& db)
3406{
3407 while (first != last && *first == 'B' && first+1 != last)
3408 {
3409 size_t length;
3410 const char* t = parse_positive_integer(first+1, last, &length);
3411 if (t == first+1)
3412 return first;
3413 if (static_cast<size_t>(last - t) < length || db.Names.empty())
3414 return first;
3415 db.Names.back() = db.make<AbiTagAttr>(
3416 db.Names.back(), StringView(t, t + length));
3417 first = t + length;
3418 }
3419 return first;
3420}
3421
3422// <source-name> ::= <positive length number> <identifier> [<abi-tag-seq>]
3423const char*
3424parse_source_name(const char* first, const char* last, Db& db)
3425{
3426 if (first != last)
3427 {
3428 size_t length;
3429 const char* t = parse_positive_integer(first, last, &length);
3430 if (t == first)
3431 return first;
3432 if (static_cast<size_t>(last - t) >= length)
3433 {
3434 StringView r(t, t + length);
3435 if (r.substr(0, 10) == "_GLOBAL__N")
3436 db.Names.push_back(db.make<NameType>("(anonymous namespace)"));
3437 else
3438 db.Names.push_back(db.make<NameType>(r));
3439 first = t + length;
3440 first = parse_abi_tag_seq(first, last, db);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003441 }
3442 }
3443 return first;
3444}
3445
3446// <substitution> ::= S <seq-id> _
3447// ::= S_
3448// <substitution> ::= Sa # ::std::allocator
3449// <substitution> ::= Sb # ::std::basic_string
3450// <substitution> ::= Ss # ::std::basic_string < char,
3451// ::std::char_traits<char>,
3452// ::std::allocator<char> >
3453// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
3454// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
3455// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
3456
Howard Hinnant6c33e762013-06-17 18:10:34 +00003457const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003458parse_substitution(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003459{
3460 if (last - first >= 2)
3461 {
3462 if (*first == 'S')
3463 {
3464 switch (first[1])
3465 {
3466 case 'a':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003467 db.Names.push_back(
Erik Pilkington0024acd2017-07-28 00:43:49 +00003468 db.make<SpecialSubstitution>(
3469 SpecialSubKind::allocator));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003470 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003471 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003472 case 'b':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003473 db.Names.push_back(
Erik Pilkington0024acd2017-07-28 00:43:49 +00003474 db.make<SpecialSubstitution>(SpecialSubKind::basic_string));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003475 first += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003476 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003477 case 's':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003478 db.Names.push_back(
Erik Pilkington0024acd2017-07-28 00:43:49 +00003479 db.make<SpecialSubstitution>(
3480 SpecialSubKind::string));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003481 first += 2;
3482 break;
3483 case 'i':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003484 db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::istream));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003485 first += 2;
3486 break;
3487 case 'o':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003488 db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::ostream));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003489 first += 2;
3490 break;
3491 case 'd':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003492 db.Names.push_back(db.make<SpecialSubstitution>(SpecialSubKind::iostream));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003493 first += 2;
3494 break;
3495 case '_':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003496 if (!db.Subs.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003497 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003498 db.Names.push_back(db.Subs[0]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003499 first += 2;
3500 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003501 break;
3502 default:
Howard Hinnant6c33e762013-06-17 18:10:34 +00003503 if (std::isdigit(first[1]) || std::isupper(first[1]))
3504 {
3505 size_t sub = 0;
3506 const char* t = first+1;
3507 if (std::isdigit(*t))
3508 sub = static_cast<size_t>(*t - '0');
3509 else
3510 sub = static_cast<size_t>(*t - 'A') + 10;
3511 for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t)
3512 {
3513 sub *= 36;
3514 if (std::isdigit(*t))
3515 sub += static_cast<size_t>(*t - '0');
3516 else
3517 sub += static_cast<size_t>(*t - 'A') + 10;
3518 }
3519 if (t == last || *t != '_')
3520 return first;
3521 ++sub;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003522 if (sub < db.Subs.size())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003523 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003524 db.Names.push_back(db.Subs[sub]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003525 first = t+1;
3526 }
3527 }
3528 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003529 }
3530 }
3531 }
3532 return first;
3533}
3534
Erik Pilkington0024acd2017-07-28 00:43:49 +00003535// <CV-Qualifiers> ::= [r] [V] [K]
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003536
3537const char*
Erik Pilkington0024acd2017-07-28 00:43:49 +00003538parse_cv_qualifiers(const char* first, const char* last, Qualifiers& cv)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003539{
Erik Pilkington0024acd2017-07-28 00:43:49 +00003540 cv = QualNone;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003541 if (first != last)
3542 {
3543 if (*first == 'r')
3544 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003545 addQualifiers(cv, QualRestrict);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003546 ++first;
3547 }
3548 if (*first == 'V')
3549 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003550 addQualifiers(cv, QualVolatile);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003551 ++first;
3552 }
3553 if (*first == 'K')
3554 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00003555 addQualifiers(cv, QualConst);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003556 ++first;
3557 }
3558 }
3559 return first;
3560}
3561
3562// <template-param> ::= T_ # first template parameter
3563// ::= T <parameter-2 non-negative number> _
3564
Howard Hinnant6c33e762013-06-17 18:10:34 +00003565const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003566parse_template_param(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003567{
3568 if (last - first >= 2)
3569 {
3570 if (*first == 'T')
3571 {
3572 if (first[1] == '_')
3573 {
Erik Pilkingtonba34a242017-08-09 21:30:57 +00003574 if (!db.TemplateParams.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003575 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003576 db.Names.push_back(db.TemplateParams[0]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003577 first += 2;
3578 }
3579 else
3580 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003581 db.Names.push_back(db.make<NameType>("T_"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003582 first += 2;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003583 db.FixForwardReferences = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003584 }
3585 }
3586 else if (isdigit(first[1]))
3587 {
3588 const char* t = first+1;
3589 size_t sub = static_cast<size_t>(*t - '0');
3590 for (++t; t != last && isdigit(*t); ++t)
3591 {
3592 sub *= 10;
3593 sub += static_cast<size_t>(*t - '0');
3594 }
Erik Pilkingtonba34a242017-08-09 21:30:57 +00003595 if (t == last || *t != '_')
Howard Hinnant6c33e762013-06-17 18:10:34 +00003596 return first;
3597 ++sub;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00003598 if (sub < db.TemplateParams.size())
Howard Hinnant6c33e762013-06-17 18:10:34 +00003599 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003600 db.Names.push_back(db.TemplateParams[sub]);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003601 first = t+1;
3602 }
3603 else
3604 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003605 db.Names.push_back(
Erik Pilkington0024acd2017-07-28 00:43:49 +00003606 db.make<NameType>(StringView(first, t + 1)));
Howard Hinnant6c33e762013-06-17 18:10:34 +00003607 first = t+1;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003608 db.FixForwardReferences = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003609 }
3610 }
3611 }
3612 }
3613 return first;
3614}
3615
Howard Hinnant6c33e762013-06-17 18:10:34 +00003616// <simple-id> ::= <source-name> [ <template-args> ]
3617
Howard Hinnant6c33e762013-06-17 18:10:34 +00003618const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003619parse_simple_id(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003620{
3621 if (first != last)
3622 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003623 const char* t = parse_source_name(first, last, db);
3624 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003625 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003626 const char* t1 = parse_template_args(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003627 if (t1 != t)
3628 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003629 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003630 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003631 auto args = db.Names.back();
3632 db.Names.pop_back();
3633 db.Names.back() =
3634 db.make<NameWithTemplateArgs>(db.Names.back(), args);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003635 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003636 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003637 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003638 else
Howard Hinnant6c33e762013-06-17 18:10:34 +00003639 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003640 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003641 return first;
3642}
3643
Howard Hinnant6c33e762013-06-17 18:10:34 +00003644// <unresolved-type> ::= <template-param>
3645// ::= <decltype>
3646// ::= <substitution>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003647
3648const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003649parse_unresolved_type(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003650{
Howard Hinnant6c33e762013-06-17 18:10:34 +00003651 if (first != last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003652 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003653 const char* t = first;
3654 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003655 {
Howard Hinnant86ccacd2012-09-13 23:49:59 +00003656 case 'T':
Howard Hinnant6c33e762013-06-17 18:10:34 +00003657 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003658 size_t k0 = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003659 t = parse_template_param(first, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003660 size_t k1 = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003661 if (t != first && k1 == k0 + 1)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003662 {
Erik Pilkington761e6b02018-01-31 20:17:06 +00003663 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003664 first = t;
Howard Hinnantab039992012-08-01 18:56:46 +00003665 }
3666 else
Howard Hinnant342f2f92012-11-30 18:43:50 +00003667 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003668 for (; k1 != k0; --k1)
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003669 db.Names.pop_back();
Howard Hinnant342f2f92012-11-30 18:43:50 +00003670 }
Howard Hinnantab87dcf2011-12-15 20:02:15 +00003671 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003672 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003673 case 'D':
Howard Hinnant6c33e762013-06-17 18:10:34 +00003674 t = parse_decltype(first, last, db);
3675 if (t != first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003676 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003677 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003678 return first;
Erik Pilkington761e6b02018-01-31 20:17:06 +00003679 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003680 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003681 }
3682 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003683 case 'S':
3684 t = parse_substitution(first, last, db);
3685 if (t != first)
3686 first = t;
3687 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003688 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003689 if (last - first > 2 && first[1] == 't')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003690 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003691 t = parse_unqualified_name(first+2, last, db);
3692 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003693 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003694 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003695 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003696 db.Names.back() =
3697 db.make<StdQualifiedName>(db.Names.back());
Erik Pilkington761e6b02018-01-31 20:17:06 +00003698 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00003699 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003700 }
3701 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003702 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003703 break;
3704 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003705 }
3706 return first;
3707}
3708
3709// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
3710// ::= <simple-id> # e.g., ~A<2*N>
3711
3712const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003713parse_destructor_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003714{
3715 if (first != last)
3716 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003717 const char* t = parse_unresolved_type(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003718 if (t == first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003719 t = parse_simple_id(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003720 if (t != first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003721 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003722 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003723 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003724 db.Names.back() = db.make<DtorName>(db.Names.back());
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003725 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003726 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003727 }
3728 return first;
3729}
3730
3731// <base-unresolved-name> ::= <simple-id> # unresolved name
3732// extension ::= <operator-name> # unresolved operator-function-id
3733// extension ::= <operator-name> <template-args> # unresolved operator template-id
3734// ::= on <operator-name> # unresolved operator-function-id
3735// ::= on <operator-name> <template-args> # unresolved operator template-id
3736// ::= dn <destructor-name> # destructor or pseudo-destructor;
3737// # e.g. ~X or ~X<N-1>
3738
3739const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003740parse_base_unresolved_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003741{
3742 if (last - first >= 2)
3743 {
3744 if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n')
3745 {
3746 if (first[0] == 'o')
3747 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003748 const char* t = parse_operator_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003749 if (t != first+2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003750 {
3751 first = parse_template_args(t, last, db);
3752 if (first != t)
3753 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003754 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003755 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003756 auto args = db.Names.back();
3757 db.Names.pop_back();
3758 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00003759 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003760 db.Names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003761 }
3762 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003763 }
3764 else
3765 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003766 const char* t = parse_destructor_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003767 if (t != first+2)
3768 first = t;
3769 }
3770 }
3771 else
3772 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003773 const char* t = parse_simple_id(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003774 if (t == first)
3775 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003776 t = parse_operator_name(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003777 if (t != first)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003778 {
3779 first = parse_template_args(t, last, db);
3780 if (first != t)
3781 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003782 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003783 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003784 auto args = db.Names.back();
3785 db.Names.pop_back();
3786 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00003787 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003788 db.Names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003789 }
3790 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003791 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003792 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003793 first = t;
3794 }
3795 }
3796 return first;
3797}
3798
Howard Hinnant6c33e762013-06-17 18:10:34 +00003799// <unresolved-qualifier-level> ::= <simple-id>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003800
3801const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003802parse_unresolved_qualifier_level(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003803{
Howard Hinnant6c33e762013-06-17 18:10:34 +00003804 return parse_simple_id(first, last, db);
Howard Hinnant889b02d2011-06-22 19:27:39 +00003805}
3806
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003807// <unresolved-name>
Howard Hinnant889b02d2011-06-22 19:27:39 +00003808// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003809// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3810// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3811// # A::x, N::y, A<T>::z; "gs" means leading "::"
Howard Hinnant889b02d2011-06-22 19:27:39 +00003812// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
Howard Hinnant6c33e762013-06-17 18:10:34 +00003813// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
Howard Hinnant889b02d2011-06-22 19:27:39 +00003814// # T::N::x /decltype(p)::N::x
3815// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003816
3817const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00003818parse_unresolved_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003819{
3820 if (last - first > 2)
3821 {
Howard Hinnant889b02d2011-06-22 19:27:39 +00003822 const char* t = first;
3823 bool global = false;
3824 if (t[0] == 'g' && t[1] == 's')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003825 {
Howard Hinnant889b02d2011-06-22 19:27:39 +00003826 global = true;
3827 t += 2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003828 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003829 const char* t2 = parse_base_unresolved_name(t, last, db);
Howard Hinnant889b02d2011-06-22 19:27:39 +00003830 if (t2 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003831 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003832 if (global)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003833 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003834 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003835 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003836 db.Names.back() =
3837 db.make<GlobalQualifiedName>(db.Names.back());
Howard Hinnant753a30d2013-12-11 19:44:25 +00003838 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003839 first = t2;
Howard Hinnant889b02d2011-06-22 19:27:39 +00003840 }
3841 else if (last - t > 2 && t[0] == 's' && t[1] == 'r')
3842 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003843 if (t[2] == 'N')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003844 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003845 t += 3;
3846 const char* t1 = parse_unresolved_type(t, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003847 if (t1 == t || t1 == last)
3848 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003849 t = t1;
3850 t1 = parse_template_args(t, last, db);
3851 if (t1 != t)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003852 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003853 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003854 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003855 auto args = db.Names.back();
3856 db.Names.pop_back();
3857 db.Names.back() = db.make<NameWithTemplateArgs>(
3858 db.Names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003859 t = t1;
3860 if (t == last)
3861 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003862 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003863 return first;
3864 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003865 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003866 while (*t != 'E')
3867 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003868 t1 = parse_unresolved_qualifier_level(t, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003869 if (t1 == t || t1 == last || db.Names.size() < 2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003870 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003871 auto s = db.Names.back();
3872 db.Names.pop_back();
3873 db.Names.back() =
3874 db.make<QualifiedName>(db.Names.back(), s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003875 t = t1;
3876 }
3877 ++t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003878 t1 = parse_base_unresolved_name(t, last, db);
3879 if (t1 == t)
3880 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003881 if (!db.Names.empty())
3882 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003883 return first;
3884 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003885 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003886 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003887 auto s = db.Names.back();
3888 db.Names.pop_back();
3889 db.Names.back() =
3890 db.make<QualifiedName>(db.Names.back(), s);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003891 first = t1;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003892 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003893 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003894 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00003895 t += 2;
3896 const char* t1 = parse_unresolved_type(t, last, db);
3897 if (t1 != t)
3898 {
3899 t = t1;
3900 t1 = parse_template_args(t, last, db);
3901 if (t1 != t)
3902 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003903 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003904 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003905 auto args = db.Names.back();
3906 db.Names.pop_back();
3907 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00003908 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003909 db.Names.back(), args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003910 t = t1;
3911 }
3912 t1 = parse_base_unresolved_name(t, last, db);
3913 if (t1 == t)
3914 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003915 if (!db.Names.empty())
3916 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003917 return first;
3918 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003919 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003920 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003921 auto s = db.Names.back();
3922 db.Names.pop_back();
3923 db.Names.back() =
3924 db.make<QualifiedName>(db.Names.back(), s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003925 first = t1;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003926 }
3927 else
3928 {
3929 t1 = parse_unresolved_qualifier_level(t, last, db);
3930 if (t1 == t || t1 == last)
3931 return first;
3932 t = t1;
3933 if (global)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003934 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003935 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00003936 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003937 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00003938 db.make<GlobalQualifiedName>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003939 db.Names.back());
Howard Hinnant753a30d2013-12-11 19:44:25 +00003940 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00003941 while (*t != 'E')
3942 {
3943 t1 = parse_unresolved_qualifier_level(t, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003944 if (t1 == t || t1 == last || db.Names.size() < 2)
Howard Hinnant6c33e762013-06-17 18:10:34 +00003945 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003946 auto s = db.Names.back();
3947 db.Names.pop_back();
3948 db.Names.back() = db.make<QualifiedName>(
3949 db.Names.back(), s);
Howard Hinnant6c33e762013-06-17 18:10:34 +00003950 t = t1;
3951 }
3952 ++t;
3953 t1 = parse_base_unresolved_name(t, last, db);
3954 if (t1 == t)
3955 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003956 if (!db.Names.empty())
3957 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00003958 return first;
3959 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003960 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00003961 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00003962 auto s = db.Names.back();
3963 db.Names.pop_back();
3964 db.Names.back() =
3965 db.make<QualifiedName>(db.Names.back(), s);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003966 first = t1;
Howard Hinnant6c33e762013-06-17 18:10:34 +00003967 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00003968 }
3969 }
3970 }
3971 return first;
3972}
3973
Howard Hinnant6c33e762013-06-17 18:10:34 +00003974// <operator-name>
3975// ::= aa # &&
3976// ::= ad # & (unary)
3977// ::= an # &
3978// ::= aN # &=
3979// ::= aS # =
3980// ::= cl # ()
3981// ::= cm # ,
3982// ::= co # ~
3983// ::= cv <type> # (cast)
3984// ::= da # delete[]
3985// ::= de # * (unary)
3986// ::= dl # delete
3987// ::= dv # /
3988// ::= dV # /=
3989// ::= eo # ^
3990// ::= eO # ^=
3991// ::= eq # ==
3992// ::= ge # >=
3993// ::= gt # >
3994// ::= ix # []
3995// ::= le # <=
Howard Hinnantf29757a2014-01-06 23:05:04 +00003996// ::= li <source-name> # operator ""
Howard Hinnant6c33e762013-06-17 18:10:34 +00003997// ::= ls # <<
3998// ::= lS # <<=
3999// ::= lt # <
4000// ::= mi # -
4001// ::= mI # -=
4002// ::= ml # *
4003// ::= mL # *=
4004// ::= mm # -- (postfix in <expression> context)
4005// ::= na # new[]
4006// ::= ne # !=
4007// ::= ng # - (unary)
4008// ::= nt # !
4009// ::= nw # new
4010// ::= oo # ||
4011// ::= or # |
4012// ::= oR # |=
4013// ::= pm # ->*
4014// ::= pl # +
4015// ::= pL # +=
4016// ::= pp # ++ (postfix in <expression> context)
4017// ::= ps # + (unary)
4018// ::= pt # ->
4019// ::= qu # ?
4020// ::= rm # %
4021// ::= rM # %=
4022// ::= rs # >>
4023// ::= rS # >>=
4024// ::= v <digit> <source-name> # vendor extended operator
Erik Pilkington5bff4122017-11-22 20:38:22 +00004025// extension ::= <operator-name> <abi-tag-seq>
Howard Hinnant6c33e762013-06-17 18:10:34 +00004026const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004027parse_operator_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004028{
Erik Pilkington5bff4122017-11-22 20:38:22 +00004029 const char* original_first = first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004030 if (last - first >= 2)
4031 {
4032 switch (first[0])
4033 {
4034 case 'a':
4035 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004036 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004037 case 'a':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004038 db.Names.push_back(db.make<NameType>("operator&&"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004039 first += 2;
4040 break;
4041 case 'd':
4042 case 'n':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004043 db.Names.push_back(db.make<NameType>("operator&"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004044 first += 2;
4045 break;
4046 case 'N':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004047 db.Names.push_back(db.make<NameType>("operator&="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004048 first += 2;
4049 break;
4050 case 'S':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004051 db.Names.push_back(db.make<NameType>("operator="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004052 first += 2;
4053 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004054 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004055 break;
4056 case 'c':
4057 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004058 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004059 case 'l':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004060 db.Names.push_back(db.make<NameType>("operator()"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004061 first += 2;
4062 break;
4063 case 'm':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004064 db.Names.push_back(db.make<NameType>("operator,"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004065 first += 2;
4066 break;
4067 case 'o':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004068 db.Names.push_back(db.make<NameType>("operator~"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004069 first += 2;
4070 break;
4071 case 'v':
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004072 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004073 bool TryToParseTemplateArgs = db.TryToParseTemplateArgs;
4074 db.TryToParseTemplateArgs = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004075 const char* t = parse_type(first+2, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004076 db.TryToParseTemplateArgs = TryToParseTemplateArgs;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004077 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004078 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004079 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004080 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004081 db.Names.back() =
4082 db.make<ConversionOperatorType>(db.Names.back());
4083 db.ParsedCtorDtorCV = true;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004084 first = t;
4085 }
4086 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004087 break;
4088 }
4089 break;
4090 case 'd':
4091 switch (first[1])
4092 {
4093 case 'a':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004094 db.Names.push_back(db.make<NameType>("operator delete[]"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004095 first += 2;
4096 break;
4097 case 'e':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004098 db.Names.push_back(db.make<NameType>("operator*"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004099 first += 2;
4100 break;
4101 case 'l':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004102 db.Names.push_back(db.make<NameType>("operator delete"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004103 first += 2;
4104 break;
4105 case 'v':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004106 db.Names.push_back(db.make<NameType>("operator/"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004107 first += 2;
4108 break;
4109 case 'V':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004110 db.Names.push_back(db.make<NameType>("operator/="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004111 first += 2;
4112 break;
4113 }
4114 break;
4115 case 'e':
4116 switch (first[1])
4117 {
4118 case 'o':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004119 db.Names.push_back(db.make<NameType>("operator^"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004120 first += 2;
4121 break;
4122 case 'O':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004123 db.Names.push_back(db.make<NameType>("operator^="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004124 first += 2;
4125 break;
4126 case 'q':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004127 db.Names.push_back(db.make<NameType>("operator=="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004128 first += 2;
4129 break;
4130 }
4131 break;
4132 case 'g':
4133 switch (first[1])
4134 {
4135 case 'e':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004136 db.Names.push_back(db.make<NameType>("operator>="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004137 first += 2;
4138 break;
4139 case 't':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004140 db.Names.push_back(db.make<NameType>("operator>"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004141 first += 2;
4142 break;
4143 }
4144 break;
4145 case 'i':
4146 if (first[1] == 'x')
4147 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004148 db.Names.push_back(db.make<NameType>("operator[]"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004149 first += 2;
4150 }
4151 break;
4152 case 'l':
4153 switch (first[1])
4154 {
4155 case 'e':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004156 db.Names.push_back(db.make<NameType>("operator<="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004157 first += 2;
4158 break;
Howard Hinnantf29757a2014-01-06 23:05:04 +00004159 case 'i':
4160 {
4161 const char* t = parse_source_name(first+2, last, db);
4162 if (t != first+2)
4163 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004164 if (db.Names.empty())
Howard Hinnantf29757a2014-01-06 23:05:04 +00004165 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004166 db.Names.back() =
4167 db.make<LiteralOperator>(db.Names.back());
Howard Hinnantf29757a2014-01-06 23:05:04 +00004168 first = t;
4169 }
4170 }
4171 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004172 case 's':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004173 db.Names.push_back(db.make<NameType>("operator<<"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004174 first += 2;
4175 break;
4176 case 'S':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004177 db.Names.push_back(db.make<NameType>("operator<<="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004178 first += 2;
4179 break;
4180 case 't':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004181 db.Names.push_back(db.make<NameType>("operator<"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004182 first += 2;
4183 break;
4184 }
4185 break;
4186 case 'm':
4187 switch (first[1])
4188 {
4189 case 'i':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004190 db.Names.push_back(db.make<NameType>("operator-"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004191 first += 2;
4192 break;
4193 case 'I':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004194 db.Names.push_back(db.make<NameType>("operator-="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004195 first += 2;
4196 break;
4197 case 'l':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004198 db.Names.push_back(db.make<NameType>("operator*"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004199 first += 2;
4200 break;
4201 case 'L':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004202 db.Names.push_back(db.make<NameType>("operator*="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004203 first += 2;
4204 break;
4205 case 'm':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004206 db.Names.push_back(db.make<NameType>("operator--"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004207 first += 2;
4208 break;
4209 }
4210 break;
4211 case 'n':
4212 switch (first[1])
4213 {
4214 case 'a':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004215 db.Names.push_back(db.make<NameType>("operator new[]"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004216 first += 2;
4217 break;
4218 case 'e':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004219 db.Names.push_back(db.make<NameType>("operator!="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004220 first += 2;
4221 break;
4222 case 'g':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004223 db.Names.push_back(db.make<NameType>("operator-"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004224 first += 2;
4225 break;
4226 case 't':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004227 db.Names.push_back(db.make<NameType>("operator!"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004228 first += 2;
4229 break;
4230 case 'w':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004231 db.Names.push_back(db.make<NameType>("operator new"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004232 first += 2;
4233 break;
4234 }
4235 break;
4236 case 'o':
4237 switch (first[1])
4238 {
4239 case 'o':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004240 db.Names.push_back(db.make<NameType>("operator||"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004241 first += 2;
4242 break;
4243 case 'r':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004244 db.Names.push_back(db.make<NameType>("operator|"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004245 first += 2;
4246 break;
4247 case 'R':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004248 db.Names.push_back(db.make<NameType>("operator|="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004249 first += 2;
4250 break;
4251 }
4252 break;
4253 case 'p':
4254 switch (first[1])
4255 {
4256 case 'm':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004257 db.Names.push_back(db.make<NameType>("operator->*"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004258 first += 2;
4259 break;
4260 case 'l':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004261 db.Names.push_back(db.make<NameType>("operator+"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004262 first += 2;
4263 break;
4264 case 'L':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004265 db.Names.push_back(db.make<NameType>("operator+="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004266 first += 2;
4267 break;
4268 case 'p':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004269 db.Names.push_back(db.make<NameType>("operator++"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004270 first += 2;
4271 break;
4272 case 's':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004273 db.Names.push_back(db.make<NameType>("operator+"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004274 first += 2;
4275 break;
4276 case 't':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004277 db.Names.push_back(db.make<NameType>("operator->"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004278 first += 2;
4279 break;
4280 }
4281 break;
4282 case 'q':
4283 if (first[1] == 'u')
4284 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004285 db.Names.push_back(db.make<NameType>("operator?"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004286 first += 2;
4287 }
4288 break;
4289 case 'r':
4290 switch (first[1])
4291 {
4292 case 'm':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004293 db.Names.push_back(db.make<NameType>("operator%"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004294 first += 2;
4295 break;
4296 case 'M':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004297 db.Names.push_back(db.make<NameType>("operator%="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004298 first += 2;
4299 break;
4300 case 's':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004301 db.Names.push_back(db.make<NameType>("operator>>"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004302 first += 2;
4303 break;
4304 case 'S':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004305 db.Names.push_back(db.make<NameType>("operator>>="));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004306 first += 2;
4307 break;
4308 }
4309 break;
4310 case 'v':
4311 if (std::isdigit(first[1]))
4312 {
4313 const char* t = parse_source_name(first+2, last, db);
4314 if (t != first+2)
4315 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004316 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004317 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004318 db.Names.back() =
4319 db.make<ConversionOperatorType>(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004320 first = t;
4321 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004322 }
4323 break;
4324 }
4325 }
Erik Pilkington5bff4122017-11-22 20:38:22 +00004326
4327 if (original_first != first)
4328 first = parse_abi_tag_seq(first, last, db);
4329
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004330 return first;
4331}
4332
Erik Pilkington0024acd2017-07-28 00:43:49 +00004333Node* maybe_change_special_sub_name(Node* inp, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004334{
Erik Pilkington0024acd2017-07-28 00:43:49 +00004335 if (inp->K != Node::KSpecialSubstitution)
4336 return inp;
4337 auto Kind = static_cast<SpecialSubstitution*>(inp)->SSK;
4338 switch (Kind)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004339 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00004340 case SpecialSubKind::string:
4341 case SpecialSubKind::istream:
4342 case SpecialSubKind::ostream:
4343 case SpecialSubKind::iostream:
4344 return db.make<ExpandedSpecialSubstitution>(Kind);
4345 default:
4346 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004347 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00004348 return inp;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004349}
4350
4351// <ctor-dtor-name> ::= C1 # complete object constructor
4352// ::= C2 # base object constructor
4353// ::= C3 # complete object allocating constructor
4354// extension ::= C5 # ?
4355// ::= D0 # deleting destructor
4356// ::= D1 # complete object destructor
4357// ::= D2 # base object destructor
4358// extension ::= D5 # ?
Erik Pilkington5bff4122017-11-22 20:38:22 +00004359// extension ::= <ctor-dtor-name> <abi-tag-seq>
Howard Hinnant6c33e762013-06-17 18:10:34 +00004360const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004361parse_ctor_dtor_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004362{
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004363 if (last-first >= 2 && !db.Names.empty())
Howard Hinnant6c33e762013-06-17 18:10:34 +00004364 {
4365 switch (first[0])
4366 {
4367 case 'C':
4368 switch (first[1])
4369 {
4370 case '1':
4371 case '2':
4372 case '3':
4373 case '5':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004374 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004375 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004376 db.Names.back() =
4377 maybe_change_special_sub_name(db.Names.back(), db);
4378 db.Names.push_back(
4379 db.make<CtorDtorName>(db.Names.back(), false));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004380 first += 2;
Erik Pilkington5bff4122017-11-22 20:38:22 +00004381 first = parse_abi_tag_seq(first, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004382 db.ParsedCtorDtorCV = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004383 break;
4384 }
4385 break;
4386 case 'D':
4387 switch (first[1])
4388 {
4389 case '0':
4390 case '1':
4391 case '2':
4392 case '5':
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004393 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004394 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004395 db.Names.push_back(
4396 db.make<CtorDtorName>(db.Names.back(), true));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004397 first += 2;
Erik Pilkington5bff4122017-11-22 20:38:22 +00004398 first = parse_abi_tag_seq(first, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004399 db.ParsedCtorDtorCV = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004400 break;
4401 }
4402 break;
4403 }
4404 }
4405 return first;
4406}
4407
Erik Pilkington5bff4122017-11-22 20:38:22 +00004408// <unnamed-type-name> ::= Ut [<nonnegative number>] _ [<abi-tag-seq>]
Howard Hinnant6c33e762013-06-17 18:10:34 +00004409// ::= <closure-type-name>
4410//
4411// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
4412//
4413// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
Howard Hinnant6c33e762013-06-17 18:10:34 +00004414const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004415parse_unnamed_type_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004416{
4417 if (last - first > 2 && first[0] == 'U')
4418 {
4419 char type = first[1];
4420 switch (type)
4421 {
4422 case 't':
4423 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004424 const char* t0 = first+2;
4425 if (t0 == last)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004426 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004427 StringView count;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004428 if (std::isdigit(*t0))
4429 {
4430 const char* t1 = t0 + 1;
4431 while (t1 != last && std::isdigit(*t1))
4432 ++t1;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004433 count = StringView(t0, t1);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004434 t0 = t1;
4435 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004436 if (t0 == last || *t0 != '_')
Howard Hinnant6c33e762013-06-17 18:10:34 +00004437 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004438 db.Names.push_back(db.make<UnnamedTypeName>(count));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004439 first = t0 + 1;
Erik Pilkington5bff4122017-11-22 20:38:22 +00004440 first = parse_abi_tag_seq(first, last, db);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004441 }
4442 break;
4443 case 'l':
4444 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004445 size_t begin_pos = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004446 const char* t0 = first+2;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004447 NodeArray lambda_params;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004448 if (first[2] == 'v')
4449 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004450 ++t0;
4451 }
4452 else
4453 {
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004454 while (true)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004455 {
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004456 const char* t1 = parse_type(t0, last, db);
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004457 if (t1 == t0)
4458 break;
Erik Pilkington0a91f7a2017-05-24 05:44:19 +00004459 t0 = t1;
4460 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004461 if (db.Names.size() < begin_pos)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004462 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00004463 lambda_params = db.popTrailingNodeArray(begin_pos);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004464 }
4465 if (t0 == last || *t0 != 'E')
Erik Pilkington0024acd2017-07-28 00:43:49 +00004466 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004467 ++t0;
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 }
4479 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<LambdaTypeName>(lambda_params, count));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004482 first = t0 + 1;
4483 }
4484 break;
4485 }
4486 }
4487 return first;
4488}
4489
4490// <unqualified-name> ::= <operator-name>
4491// ::= <ctor-dtor-name>
4492// ::= <source-name>
4493// ::= <unnamed-type-name>
4494
Howard Hinnant6c33e762013-06-17 18:10:34 +00004495const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004496parse_unqualified_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004497{
4498 if (first != last)
4499 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004500 const char* t;
4501 switch (*first)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00004502 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004503 case 'C':
4504 case 'D':
4505 t = parse_ctor_dtor_name(first, last, db);
4506 if (t != first)
4507 first = t;
4508 break;
4509 case 'U':
4510 t = parse_unnamed_type_name(first, last, db);
4511 if (t != first)
4512 first = t;
4513 break;
4514 case '1':
4515 case '2':
4516 case '3':
4517 case '4':
4518 case '5':
4519 case '6':
4520 case '7':
4521 case '8':
4522 case '9':
4523 t = parse_source_name(first, last, db);
4524 if (t != first)
4525 first = t;
4526 break;
4527 default:
4528 t = parse_operator_name(first, last, db);
4529 if (t != first)
4530 first = t;
4531 break;
4532 };
4533 }
4534 return first;
4535}
4536
4537// <unscoped-name> ::= <unqualified-name>
4538// ::= St <unqualified-name> # ::std::
4539// extension ::= StL<unqualified-name>
4540
Howard Hinnant6c33e762013-06-17 18:10:34 +00004541const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004542parse_unscoped_name(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004543{
4544 if (last - first >= 2)
4545 {
4546 const char* t0 = first;
4547 bool St = false;
4548 if (first[0] == 'S' && first[1] == 't')
4549 {
4550 t0 += 2;
4551 St = true;
4552 if (t0 != last && *t0 == 'L')
4553 ++t0;
4554 }
4555 const char* t1 = parse_unqualified_name(t0, last, db);
4556 if (t1 != t0)
4557 {
4558 if (St)
Howard Hinnant753a30d2013-12-11 19:44:25 +00004559 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004560 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004561 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004562 db.Names.back() =
4563 db.make<StdQualifiedName>(db.Names.back());
Howard Hinnant753a30d2013-12-11 19:44:25 +00004564 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004565 first = t1;
4566 }
4567 }
4568 return first;
4569}
4570
Howard Hinnant6c33e762013-06-17 18:10:34 +00004571// <template-arg> ::= <type> # type or template
4572// ::= X <expression> E # expression
4573// ::= <expr-primary> # simple expressions
4574// ::= J <template-arg>* E # argument pack
4575// ::= LZ <encoding> E # extension
Howard Hinnant6c33e762013-06-17 18:10:34 +00004576const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004577parse_template_arg(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004578{
4579 if (first != last)
4580 {
4581 const char* t;
4582 switch (*first)
4583 {
4584 case 'X':
4585 t = parse_expression(first+1, last, db);
4586 if (t != first+1)
4587 {
4588 if (t != last && *t == 'E')
4589 first = t+1;
4590 }
4591 break;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004592 case 'J': {
Howard Hinnant6c33e762013-06-17 18:10:34 +00004593 t = first+1;
4594 if (t == last)
4595 return first;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004596 size_t ArgsBegin = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004597 while (*t != 'E')
4598 {
4599 const char* t1 = parse_template_arg(t, last, db);
4600 if (t1 == t)
4601 return first;
4602 t = t1;
4603 }
Erik Pilkington761e6b02018-01-31 20:17:06 +00004604 NodeArray Args = db.popTrailingNodeArray(ArgsBegin);
4605 db.Names.push_back(db.make<TemplateArgumentPack>(Args));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004606 first = t+1;
4607 break;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004608 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00004609 case 'L':
4610 // <expr-primary> or LZ <encoding> E
4611 if (first+1 != last && first[1] == 'Z')
4612 {
4613 t = parse_encoding(first+2, last, db);
4614 if (t != first+2 && t != last && *t == 'E')
4615 first = t+1;
4616 }
4617 else
4618 first = parse_expr_primary(first, last, db);
4619 break;
4620 default:
4621 // <type>
4622 first = parse_type(first, last, db);
4623 break;
4624 }
4625 }
4626 return first;
4627}
4628
4629// <template-args> ::= I <template-arg>* E
4630// extension, the abi says <template-arg>+
Howard Hinnant6c33e762013-06-17 18:10:34 +00004631const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004632parse_template_args(const char* first, const char* last, Db& db)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004633{
4634 if (last - first >= 2 && *first == 'I')
4635 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004636 if (db.TagTemplates)
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004637 db.TemplateParams.clear();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004638 const char* t = first+1;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004639 size_t begin_idx = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004640 while (*t != 'E')
4641 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004642 if (db.TagTemplates)
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004643 {
4644 auto TmpParams = std::move(db.TemplateParams);
4645 size_t k0 = db.Names.size();
4646 const char* t1 = parse_template_arg(t, last, db);
4647 size_t k1 = db.Names.size();
4648 db.TemplateParams = std::move(TmpParams);
Erik Pilkington761e6b02018-01-31 20:17:06 +00004649 if (t1 == t || t1 == last || k0 + 1 != k1)
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004650 return first;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004651 Node *TableEntry = db.Names.back();
4652 if (TableEntry->getKind() == Node::KTemplateArgumentPack)
4653 TableEntry = db.make<ParameterPack>(
4654 static_cast<TemplateArgumentPack*>(TableEntry)
4655 ->getElements());
4656 db.TemplateParams.push_back(TableEntry);
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004657 t = t1;
4658 continue;
4659 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004660 size_t k0 = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004661 const char* t1 = parse_template_arg(t, last, db);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004662 size_t k1 = db.Names.size();
Erik Pilkington0024acd2017-07-28 00:43:49 +00004663 if (t1 == t || t1 == last || k0 > k1)
Erik Pilkingtonba34a242017-08-09 21:30:57 +00004664 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004665 t = t1;
4666 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004667 if (begin_idx > db.Names.size())
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004668 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004669 first = t + 1;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004670 auto *tp = db.make<TemplateArgs>(
Erik Pilkington0024acd2017-07-28 00:43:49 +00004671 db.popTrailingNodeArray(begin_idx));
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004672 db.Names.push_back(tp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004673 }
4674 return first;
4675}
4676
Erik Pilkington0024acd2017-07-28 00:43:49 +00004677// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
4678// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
Howard Hinnant6c33e762013-06-17 18:10:34 +00004679//
4680// <prefix> ::= <prefix> <unqualified-name>
4681// ::= <template-prefix> <template-args>
4682// ::= <template-param>
4683// ::= <decltype>
4684// ::= # empty
4685// ::= <substitution>
4686// ::= <prefix> <data-member-prefix>
4687// extension ::= L
4688//
4689// <template-prefix> ::= <prefix> <template unqualified-name>
4690// ::= <template-param>
4691// ::= <substitution>
4692
Howard Hinnant6c33e762013-06-17 18:10:34 +00004693const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004694parse_nested_name(const char* first, const char* last, Db& db,
Richard Smith24ecd092014-05-12 18:44:13 +00004695 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004696{
4697 if (first != last && *first == 'N')
4698 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00004699 Qualifiers cv;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004700 const char* t0 = parse_cv_qualifiers(first+1, last, cv);
4701 if (t0 == last)
4702 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004703 db.RefQuals = FrefQualNone;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004704 if (*t0 == 'R')
4705 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004706 db.RefQuals = FrefQualLValue;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004707 ++t0;
4708 }
4709 else if (*t0 == 'O')
4710 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004711 db.RefQuals = FrefQualRValue;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004712 ++t0;
4713 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004714 db.Names.push_back(db.make<EmptyName>());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004715 if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't')
4716 {
4717 t0 += 2;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004718 db.Names.back() = db.make<NameType>("std");
Howard Hinnant6c33e762013-06-17 18:10:34 +00004719 }
4720 if (t0 == last)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004721 return first;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004722 bool pop_subs = false;
Richard Smith24ecd092014-05-12 18:44:13 +00004723 bool component_ends_with_template_args = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004724 while (*t0 != 'E')
4725 {
Richard Smith24ecd092014-05-12 18:44:13 +00004726 component_ends_with_template_args = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004727 const char* t1;
4728 switch (*t0)
4729 {
4730 case 'S':
4731 if (t0 + 1 != last && t0[1] == 't')
4732 goto do_parse_unqualified_name;
4733 t1 = parse_substitution(t0, last, db);
4734 if (t1 != t0 && t1 != last)
4735 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004736 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004737 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004738 auto name = db.Names.back();
4739 db.Names.pop_back();
4740 if (db.Names.back()->K != Node::KEmptyName)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004741 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004742 db.Names.back() = db.make<QualifiedName>(
4743 db.Names.back(), name);
Erik Pilkington761e6b02018-01-31 20:17:06 +00004744 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004745 }
4746 else
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004747 db.Names.back() = name;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004748 pop_subs = true;
4749 t0 = t1;
4750 }
4751 else
4752 return first;
4753 break;
4754 case 'T':
4755 t1 = parse_template_param(t0, last, db);
4756 if (t1 != t0 && t1 != last)
4757 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004758 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004759 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004760 auto name = db.Names.back();
4761 db.Names.pop_back();
4762 if (db.Names.back()->K != Node::KEmptyName)
4763 db.Names.back() =
4764 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004765 else
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004766 db.Names.back() = name;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004767 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004768 pop_subs = true;
4769 t0 = t1;
4770 }
4771 else
4772 return first;
4773 break;
4774 case 'D':
4775 if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')
4776 goto do_parse_unqualified_name;
4777 t1 = parse_decltype(t0, last, db);
4778 if (t1 != t0 && t1 != last)
4779 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004780 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004781 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004782 auto name = db.Names.back();
4783 db.Names.pop_back();
4784 if (db.Names.back()->K != Node::KEmptyName)
4785 db.Names.back() =
4786 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004787 else
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004788 db.Names.back() = name;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004789 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004790 pop_subs = true;
4791 t0 = t1;
4792 }
4793 else
4794 return first;
4795 break;
4796 case 'I':
4797 t1 = parse_template_args(t0, last, db);
4798 if (t1 != t0 && t1 != last)
4799 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004800 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004801 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004802 auto name = db.Names.back();
4803 db.Names.pop_back();
4804 db.Names.back() = db.make<NameWithTemplateArgs>(
4805 db.Names.back(), name);
Erik Pilkington761e6b02018-01-31 20:17:06 +00004806 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004807 t0 = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00004808 component_ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004809 }
4810 else
4811 return first;
4812 break;
4813 case 'L':
4814 if (++t0 == last)
4815 return first;
4816 break;
4817 default:
4818 do_parse_unqualified_name:
4819 t1 = parse_unqualified_name(t0, last, db);
4820 if (t1 != t0 && t1 != last)
4821 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004822 if (db.Names.size() < 2)
Erik Pilkingtonffdace52017-07-30 20:09:55 +00004823 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004824 auto name = db.Names.back();
4825 db.Names.pop_back();
4826 if (db.Names.back()->K != Node::KEmptyName)
4827 db.Names.back() =
4828 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004829 else
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004830 db.Names.back() = name;
Erik Pilkington761e6b02018-01-31 20:17:06 +00004831 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00004832 pop_subs = true;
4833 t0 = t1;
4834 }
4835 else
4836 return first;
4837 }
4838 }
4839 first = t0 + 1;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004840 db.CV = cv;
4841 if (pop_subs && !db.Subs.empty())
Erik Pilkington761e6b02018-01-31 20:17:06 +00004842 db.Subs.pop_back();
Richard Smith24ecd092014-05-12 18:44:13 +00004843 if (ends_with_template_args)
4844 *ends_with_template_args = component_ends_with_template_args;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004845 }
4846 return first;
4847}
4848
4849// <discriminator> := _ <non-negative number> # when number < 10
4850// := __ <non-negative number> _ # when number >= 10
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00004851// extension := decimal-digit+ # at the end of string
Howard Hinnant6c33e762013-06-17 18:10:34 +00004852
4853const char*
4854parse_discriminator(const char* first, const char* last)
4855{
4856 // parse but ignore discriminator
4857 if (first != last)
4858 {
4859 if (*first == '_')
4860 {
4861 const char* t1 = first+1;
4862 if (t1 != last)
4863 {
4864 if (std::isdigit(*t1))
4865 first = t1+1;
4866 else if (*t1 == '_')
4867 {
4868 for (++t1; t1 != last && std::isdigit(*t1); ++t1)
4869 ;
4870 if (t1 != last && *t1 == '_')
4871 first = t1 + 1;
4872 }
4873 }
4874 }
4875 else if (std::isdigit(*first))
4876 {
4877 const char* t1 = first+1;
4878 for (; t1 != last && std::isdigit(*t1); ++t1)
4879 ;
Marshall Clow6c6d9cb2015-10-08 03:02:09 +00004880 if (t1 == last)
4881 first = last;
Howard Hinnant6c33e762013-06-17 18:10:34 +00004882 }
4883 }
4884 return first;
4885}
4886
4887// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
4888// := Z <function encoding> E s [<discriminator>]
4889// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
4890
Howard Hinnant6c33e762013-06-17 18:10:34 +00004891const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004892parse_local_name(const char* first, const char* last, Db& db,
Richard Smith24ecd092014-05-12 18:44:13 +00004893 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004894{
4895 if (first != last && *first == 'Z')
4896 {
4897 const char* t = parse_encoding(first+1, last, db);
4898 if (t != first+1 && t != last && *t == 'E' && ++t != last)
4899 {
4900 switch (*t)
4901 {
4902 case 's':
4903 first = parse_discriminator(t+1, last);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004904 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00004905 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004906 db.Names.back() = db.make<QualifiedName>(
4907 db.Names.back(), db.make<NameType>("string literal"));
Howard Hinnant6c33e762013-06-17 18:10:34 +00004908 break;
4909 case 'd':
4910 if (++t != last)
4911 {
4912 const char* t1 = parse_number(t, last);
4913 if (t1 != last && *t1 == '_')
4914 {
4915 t = t1 + 1;
Richard Smith24ecd092014-05-12 18:44:13 +00004916 t1 = parse_name(t, last, db,
4917 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004918 if (t1 != t)
4919 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004920 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00004921 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004922 auto name = db.Names.back();
4923 db.Names.pop_back();
4924 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004925 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004926 db.Names.back() =
4927 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004928 first = t1;
4929 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004930 else if (!db.Names.empty())
4931 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004932 }
4933 }
4934 break;
4935 default:
4936 {
Richard Smith24ecd092014-05-12 18:44:13 +00004937 const char* t1 = parse_name(t, last, db,
4938 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004939 if (t1 != t)
4940 {
4941 // parse but ignore discriminator
4942 first = parse_discriminator(t1, last);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004943 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00004944 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004945 auto name = db.Names.back();
4946 db.Names.pop_back();
4947 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00004948 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004949 db.Names.back() =
4950 db.make<QualifiedName>(db.Names.back(), name);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004951 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00004952 else if (!db.Names.empty())
4953 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00004954 }
4955 break;
4956 }
4957 }
4958 }
4959 return first;
4960}
4961
4962// <name> ::= <nested-name> // N
4963// ::= <local-name> # See Scope Encoding below // Z
4964// ::= <unscoped-template-name> <template-args>
4965// ::= <unscoped-name>
4966
4967// <unscoped-template-name> ::= <unscoped-name>
4968// ::= <substitution>
4969
Howard Hinnant6c33e762013-06-17 18:10:34 +00004970const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00004971parse_name(const char* first, const char* last, Db& db,
Richard Smith24ecd092014-05-12 18:44:13 +00004972 bool* ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00004973{
4974 if (last - first >= 2)
4975 {
4976 const char* t0 = first;
4977 // extension: ignore L here
4978 if (*t0 == 'L')
4979 ++t0;
4980 switch (*t0)
4981 {
4982 case 'N':
4983 {
Richard Smith24ecd092014-05-12 18:44:13 +00004984 const char* t1 = parse_nested_name(t0, last, db,
4985 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004986 if (t1 != t0)
4987 first = t1;
4988 break;
4989 }
4990 case 'Z':
4991 {
Richard Smith24ecd092014-05-12 18:44:13 +00004992 const char* t1 = parse_local_name(t0, last, db,
4993 ends_with_template_args);
Howard Hinnant6c33e762013-06-17 18:10:34 +00004994 if (t1 != t0)
4995 first = t1;
4996 break;
4997 }
4998 default:
4999 {
5000 const char* t1 = parse_unscoped_name(t0, last, db);
5001 if (t1 != t0)
5002 {
5003 if (t1 != last && *t1 == 'I') // <unscoped-template-name> <template-args>
5004 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005005 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005006 return first;
Erik Pilkington761e6b02018-01-31 20:17:06 +00005007 db.Subs.push_back(db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005008 t0 = t1;
5009 t1 = parse_template_args(t0, last, db);
5010 if (t1 != t0)
5011 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005012 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00005013 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005014 auto tmp = db.Names.back();
5015 db.Names.pop_back();
5016 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005017 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005018 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005019 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005020 db.Names.back(), tmp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005021 first = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00005022 if (ends_with_template_args)
5023 *ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005024 }
5025 }
5026 else // <unscoped-name>
5027 first = t1;
5028 }
5029 else
5030 { // try <substitution> <template-args>
5031 t1 = parse_substitution(t0, last, db);
Howard Hinnantb4033ff2013-06-20 01:55:07 +00005032 if (t1 != t0 && t1 != last && *t1 == 'I')
Howard Hinnant6c33e762013-06-17 18:10:34 +00005033 {
5034 t0 = t1;
5035 t1 = parse_template_args(t0, last, db);
5036 if (t1 != t0)
5037 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005038 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00005039 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005040 auto tmp = db.Names.back();
5041 db.Names.pop_back();
5042 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005043 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005044 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005045 db.make<NameWithTemplateArgs>(
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005046 db.Names.back(), tmp);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005047 first = t1;
Richard Smith24ecd092014-05-12 18:44:13 +00005048 if (ends_with_template_args)
5049 *ends_with_template_args = true;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005050 }
5051 }
5052 }
5053 break;
5054 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005055 }
5056 }
5057 return first;
5058}
5059
5060// <call-offset> ::= h <nv-offset> _
5061// ::= v <v-offset> _
5062//
5063// <nv-offset> ::= <offset number>
5064// # non-virtual base override
5065//
5066// <v-offset> ::= <offset number> _ <virtual offset number>
5067// # virtual base override, with vcall offset
5068
5069const char*
Howard Hinnant6c33e762013-06-17 18:10:34 +00005070parse_call_offset(const char* first, const char* last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005071{
5072 if (first != last)
5073 {
5074 switch (*first)
5075 {
5076 case 'h':
5077 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005078 const char* t = parse_number(first + 1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005079 if (t != first + 1 && t != last && *t == '_')
5080 first = t + 1;
5081 }
5082 break;
5083 case 'v':
5084 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005085 const char* t = parse_number(first + 1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005086 if (t != first + 1 && t != last && *t == '_')
5087 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005088 const char* t2 = parse_number(++t, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005089 if (t2 != t && t2 != last && *t2 == '_')
5090 first = t2 + 1;
5091 }
5092 }
5093 break;
5094 }
5095 }
5096 return first;
5097}
5098
5099// <special-name> ::= TV <type> # virtual table
5100// ::= TT <type> # VTT structure (construction vtable index)
5101// ::= TI <type> # typeinfo structure
5102// ::= TS <type> # typeinfo name (null-terminated byte string)
5103// ::= Tc <call-offset> <call-offset> <base encoding>
5104// # base is the nominal target function of thunk
5105// # first call-offset is 'this' adjustment
5106// # second call-offset is result adjustment
5107// ::= T <call-offset> <base encoding>
5108// # base is the nominal target function of thunk
5109// ::= GV <object name> # Guard variable for one-time initialization
5110// # No <type>
David Bozierc2fa8f12017-01-31 15:18:56 +00005111// ::= TW <object name> # Thread-local wrapper
5112// ::= TH <object name> # Thread-local initialization
Howard Hinnantf2700352011-12-09 20:07:56 +00005113// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
5114// extension ::= GR <object name> # reference temporary for object
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005115
5116const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005117parse_special_name(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005118{
5119 if (last - first > 2)
5120 {
5121 const char* t;
5122 switch (*first)
5123 {
5124 case 'T':
5125 switch (first[1])
5126 {
5127 case 'V':
5128 // TV <type> # virtual table
Howard Hinnant6c33e762013-06-17 18:10:34 +00005129 t = parse_type(first+2, last, db);
5130 if (t != first+2)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005131 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005132 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005133 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005134 db.Names.back() =
5135 db.make<SpecialName>("vtable for ", db.Names.back());
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005136 first = t;
5137 }
5138 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005139 case 'T':
5140 // TT <type> # VTT structure (construction vtable index)
5141 t = parse_type(first+2, last, db);
Howard Hinnantf2700352011-12-09 20:07:56 +00005142 if (t != first+2)
5143 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005144 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005145 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005146 db.Names.back() =
5147 db.make<SpecialName>("VTT for ", db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005148 first = t;
5149 }
5150 break;
5151 case 'I':
5152 // TI <type> # typeinfo structure
5153 t = parse_type(first+2, last, db);
5154 if (t != first+2)
5155 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005156 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005157 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005158 db.Names.back() =
5159 db.make<SpecialName>("typeinfo for ", db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005160 first = t;
5161 }
5162 break;
5163 case 'S':
5164 // TS <type> # typeinfo name (null-terminated byte string)
5165 t = parse_type(first+2, last, db);
5166 if (t != first+2)
5167 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005168 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005169 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005170 db.Names.back() =
5171 db.make<SpecialName>("typeinfo name for ", db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005172 first = t;
5173 }
5174 break;
5175 case 'c':
5176 // Tc <call-offset> <call-offset> <base encoding>
5177 {
5178 const char* t0 = parse_call_offset(first+2, last);
5179 if (t0 == first+2)
5180 break;
5181 const char* t1 = parse_call_offset(t0, last);
5182 if (t1 == t0)
5183 break;
5184 t = parse_encoding(t1, last, db);
5185 if (t != t1)
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() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005190 db.make<SpecialName>("covariant return thunk to ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005191 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005192 first = t;
5193 }
5194 }
5195 break;
5196 case 'C':
5197 // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
5198 t = parse_type(first+2, last, db);
5199 if (t != first+2)
5200 {
5201 const char* t0 = parse_number(t, last);
Howard Hinnantf2700352011-12-09 20:07:56 +00005202 if (t0 != t && t0 != last && *t0 == '_')
5203 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005204 const char* t1 = parse_type(++t0, last, db);
Howard Hinnantf2700352011-12-09 20:07:56 +00005205 if (t1 != t0)
5206 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005207 if (db.Names.size() < 2)
Howard Hinnant753a30d2013-12-11 19:44:25 +00005208 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005209 auto left = db.Names.back();
5210 db.Names.pop_back();
5211 if (db.Names.empty())
Mehdi Aminieb3e8cf2016-08-13 00:02:33 +00005212 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005213 db.Names.back() = db.make<CtorVtableSpecialName>(
5214 left, db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005215 first = t1;
Howard Hinnantf2700352011-12-09 20:07:56 +00005216 }
5217 }
5218 }
5219 break;
David Bozierc2fa8f12017-01-31 15:18:56 +00005220 case 'W':
5221 // TW <object name> # Thread-local wrapper
5222 t = parse_name(first + 2, last, db);
5223 if (t != first + 2)
5224 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005225 if (db.Names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005226 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005227 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005228 db.make<SpecialName>("thread-local wrapper routine for ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005229 db.Names.back());
David Bozierc2fa8f12017-01-31 15:18:56 +00005230 first = t;
5231 }
5232 break;
5233 case 'H':
5234 //TH <object name> # Thread-local initialization
5235 t = parse_name(first + 2, last, db);
5236 if (t != first + 2)
5237 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005238 if (db.Names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005239 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005240 db.Names.back() = db.make<SpecialName>(
5241 "thread-local initialization routine for ", db.Names.back());
David Bozierc2fa8f12017-01-31 15:18:56 +00005242 first = t;
5243 }
5244 break;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005245 default:
5246 // T <call-offset> <base encoding>
5247 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005248 const char* t0 = parse_call_offset(first+1, last);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005249 if (t0 == first+1)
5250 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005251 t = parse_encoding(t0, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005252 if (t != t0)
5253 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005254 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005255 return first;
Marshall Clowfdccce62015-10-12 20:45:05 +00005256 if (first[1] == 'v')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005257 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005258 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005259 db.make<SpecialName>("virtual thunk to ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005260 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005261 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005262 }
5263 else
5264 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005265 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005266 db.make<SpecialName>("non-virtual thunk to ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005267 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005268 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005269 }
5270 }
5271 }
5272 break;
5273 }
5274 break;
5275 case 'G':
Howard Hinnantf2700352011-12-09 20:07:56 +00005276 switch (first[1])
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005277 {
Howard Hinnantf2700352011-12-09 20:07:56 +00005278 case 'V':
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005279 // GV <object name> # Guard variable for one-time initialization
Howard Hinnant6c33e762013-06-17 18:10:34 +00005280 t = parse_name(first+2, last, db);
5281 if (t != first+2)
5282 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005283 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005284 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005285 db.Names.back() =
5286 db.make<SpecialName>("guard variable for ", db.Names.back());
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005287 first = t;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005288 }
Howard Hinnantf2700352011-12-09 20:07:56 +00005289 break;
5290 case 'R':
5291 // extension ::= GR <object name> # reference temporary for object
Howard Hinnant6c33e762013-06-17 18:10:34 +00005292 t = parse_name(first+2, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005293 if (t != first+2)
5294 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005295 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005296 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005297 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005298 db.make<SpecialName>("reference temporary for ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005299 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005300 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005301 }
5302 break;
5303 }
5304 break;
5305 }
5306 }
5307 return first;
5308}
5309
Howard Hinnant753a30d2013-12-11 19:44:25 +00005310template <class T>
5311class save_value
5312{
5313 T& restore_;
5314 T original_value_;
5315public:
5316 save_value(T& restore)
5317 : restore_(restore),
5318 original_value_(restore)
5319 {}
5320
5321 ~save_value()
5322 {
5323 restore_ = std::move(original_value_);
5324 }
5325
5326 save_value(const save_value&) = delete;
5327 save_value& operator=(const save_value&) = delete;
5328};
5329
Howard Hinnant6c33e762013-06-17 18:10:34 +00005330// <encoding> ::= <function name> <bare-function-type>
5331// ::= <data name>
5332// ::= <special-name>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005333
5334const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005335parse_encoding(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005336{
5337 if (first != last)
5338 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005339 save_value<decltype(db.EncodingDepth)> su(db.EncodingDepth);
5340 ++db.EncodingDepth;
5341 save_value<decltype(db.TagTemplates)> sb(db.TagTemplates);
5342 if (db.EncodingDepth > 1)
5343 db.TagTemplates = true;
5344 save_value<decltype(db.ParsedCtorDtorCV)> sp(db.ParsedCtorDtorCV);
5345 db.ParsedCtorDtorCV = false;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005346 switch (*first)
5347 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005348 case 'G':
5349 case 'T':
5350 first = parse_special_name(first, last, db);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005351 break;
5352 default:
Howard Hinnant6c33e762013-06-17 18:10:34 +00005353 {
Richard Smith24ecd092014-05-12 18:44:13 +00005354 bool ends_with_template_args = false;
5355 const char* t = parse_name(first, last, db,
5356 &ends_with_template_args);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005357 if (db.Names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005358 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005359 Qualifiers cv = db.CV;
5360 FunctionRefQual ref = db.RefQuals;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005361 if (t != first)
Howard Hinnantab87dcf2011-12-15 20:02:15 +00005362 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005363 if (t != last && *t != 'E' && *t != '.')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005364 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005365 save_value<bool> sb2(db.TagTemplates);
5366 db.TagTemplates = false;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005367 const char* t2;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005368 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005369 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005370 if (!db.Names.back())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005371 return first;
Erik Pilkington0024acd2017-07-28 00:43:49 +00005372 Node* return_type = nullptr;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005373 if (!db.ParsedCtorDtorCV && ends_with_template_args)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005374 {
5375 t2 = parse_type(t, last, db);
5376 if (t2 == t)
5377 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005378 if (db.Names.size() < 1)
Howard Hinnant753a30d2013-12-11 19:44:25 +00005379 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005380 return_type = db.Names.back();
5381 db.Names.pop_back();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005382 t = t2;
5383 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005384
5385 Node* result = nullptr;
5386
Howard Hinnant6c33e762013-06-17 18:10:34 +00005387 if (t != last && *t == 'v')
5388 {
5389 ++t;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005390 if (db.Names.empty())
Erik Pilkingtonb9008222017-08-01 02:38:41 +00005391 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005392 Node* name = db.Names.back();
5393 db.Names.pop_back();
Erik Pilkington761e6b02018-01-31 20:17:06 +00005394 result = db.make<FunctionEncoding>(
Erik Pilkington0024acd2017-07-28 00:43:49 +00005395 return_type, name, NodeArray());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005396 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005397 else
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005398 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005399 size_t params_begin = db.Names.size();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005400 while (true)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005401 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005402 t2 = parse_type(t, last, db);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005403 if (t2 == t)
5404 break;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005405 t = t2;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005406 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005407 if (db.Names.size() < params_begin)
Erik Pilkington0024acd2017-07-28 00:43:49 +00005408 return first;
5409 NodeArray params =
5410 db.popTrailingNodeArray(params_begin);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005411 if (db.Names.empty())
Erik Pilkington0024acd2017-07-28 00:43:49 +00005412 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005413 Node* name = db.Names.back();
5414 db.Names.pop_back();
Erik Pilkington761e6b02018-01-31 20:17:06 +00005415 result = db.make<FunctionEncoding>(
Erik Pilkington0024acd2017-07-28 00:43:49 +00005416 return_type, name, params);
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005417 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005418 if (ref != FrefQualNone)
5419 result = db.make<FunctionRefQualType>(result, ref);
5420 if (cv != QualNone)
5421 result = db.make<FunctionQualType>(result, cv);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005422 db.Names.push_back(result);
Howard Hinnant6c33e762013-06-17 18:10:34 +00005423 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005424 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005425 else
5426 first = t;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005427 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005428 break;
5429 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005430 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005431 }
5432 return first;
5433}
5434
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005435// _block_invoke
5436// _block_invoke<decimal-digit>+
5437// _block_invoke_<decimal-digit>+
5438
5439const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005440parse_block_invoke(const char* first, const char* last, Db& db)
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005441{
5442 if (last - first >= 13)
5443 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005444 // FIXME: strcmp?
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005445 const char test[] = "_block_invoke";
5446 const char* t = first;
5447 for (int i = 0; i < 13; ++i, ++t)
5448 {
5449 if (*t != test[i])
5450 return first;
5451 }
5452 if (t != last)
5453 {
5454 if (*t == '_')
5455 {
5456 // must have at least 1 decimal digit
Howard Hinnant6c33e762013-06-17 18:10:34 +00005457 if (++t == last || !std::isdigit(*t))
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005458 return first;
5459 ++t;
5460 }
5461 // parse zero or more digits
5462 while (t != last && isdigit(*t))
5463 ++t;
5464 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005465 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005466 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005467 db.Names.back() =
Erik Pilkington0024acd2017-07-28 00:43:49 +00005468 db.make<SpecialName>("invocation function for block in ",
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005469 db.Names.back());
Howard Hinnant6c33e762013-06-17 18:10:34 +00005470 first = t;
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005471 }
5472 return first;
5473}
5474
Howard Hinnant6c33e762013-06-17 18:10:34 +00005475// extension
5476// <dot-suffix> := .<anything and everything>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005477
5478const char*
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005479parse_dot_suffix(const char* first, const char* last, Db& db)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005480{
Howard Hinnant6c33e762013-06-17 18:10:34 +00005481 if (first != last && *first == '.')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005482 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005483 if (db.Names.empty())
Howard Hinnant753a30d2013-12-11 19:44:25 +00005484 return first;
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005485 db.Names.back() =
5486 db.make<DotSuffix>(db.Names.back(), StringView(first, last));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005487 first = last;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005488 }
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005489 return first;
5490}
5491
Erik Pilkington761e6b02018-01-31 20:17:06 +00005492enum {
5493 unknown_error = -4,
5494 invalid_args = -3,
5495 invalid_mangled_name,
5496 memory_alloc_failure,
5497 success
5498};
5499
Howard Hinnant5dd173b2013-04-10 19:44:03 +00005500// <block-involcaton-function> ___Z<encoding>_block_invoke
5501// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+
5502// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005503// <mangled-name> ::= _Z<encoding>
5504// ::= <type>
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005505void
Erik Pilkingtonc3926622017-07-08 18:54:08 +00005506demangle(const char* first, const char* last, Db& db, int& status)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005507{
Howard Hinnanteb8d46c2013-06-23 17:14:35 +00005508 if (first >= last)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005509 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005510 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005511 return;
5512 }
Howard Hinnant6c33e762013-06-17 18:10:34 +00005513 if (*first == '_')
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005514 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005515 if (last - first >= 4)
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005516 {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005517 if (first[1] == 'Z')
5518 {
5519 const char* t = parse_encoding(first+2, last, db);
5520 if (t != first+2 && t != last && *t == '.')
5521 t = parse_dot_suffix(t, last, db);
5522 if (t != last)
5523 status = invalid_mangled_name;
5524 }
5525 else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z')
5526 {
5527 const char* t = parse_encoding(first+4, last, db);
5528 if (t != first+4 && t != last)
5529 {
5530 const char* t1 = parse_block_invoke(t, last, db);
5531 if (t1 != last)
5532 status = invalid_mangled_name;
5533 }
5534 else
5535 status = invalid_mangled_name;
5536 }
5537 else
5538 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005539 }
5540 else
Howard Hinnant6c33e762013-06-17 18:10:34 +00005541 status = invalid_mangled_name;
5542 }
5543 else
5544 {
5545 const char* t = parse_type(first, last, db);
5546 if (t != last)
5547 status = invalid_mangled_name;
5548 }
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005549 if (status == success && db.Names.empty())
Howard Hinnanteb8d46c2013-06-23 17:14:35 +00005550 status = invalid_mangled_name;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005551}
5552
Howard Hinnant6c33e762013-06-17 18:10:34 +00005553} // unnamed namespace
5554
Erik Pilkington761e6b02018-01-31 20:17:06 +00005555
5556namespace __cxxabiv1 {
Saleem Abdulrasoolb4ec5792015-12-04 02:14:58 +00005557extern "C" _LIBCXXABI_FUNC_VIS char *
Saleem Abdulrasool77a304b2015-12-04 02:14:41 +00005558__cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status) {
Howard Hinnant6c33e762013-06-17 18:10:34 +00005559 if (mangled_name == nullptr || (buf != nullptr && n == nullptr))
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005560 {
5561 if (status)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005562 *status = invalid_args;
5563 return nullptr;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005564 }
Saleem Abdulrasool8cfa5a32016-11-14 01:55:54 +00005565
Howard Hinnant8ad6a222013-07-26 22:14:53 +00005566 size_t internal_size = buf != nullptr ? *n : 0;
Erik Pilkingtonba34a242017-08-09 21:30:57 +00005567 Db db;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005568 int internal_status = success;
Jonathan Roelofs0cbb1da2017-01-18 18:12:39 +00005569 size_t len = std::strlen(mangled_name);
Howard Hinnantb2d1f942013-06-23 19:52:45 +00005570 demangle(mangled_name, mangled_name + len, db,
Howard Hinnant6c33e762013-06-17 18:10:34 +00005571 internal_status);
Erik Pilkington0024acd2017-07-28 00:43:49 +00005572
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005573 if (internal_status == success && db.FixForwardReferences &&
Erik Pilkingtonba34a242017-08-09 21:30:57 +00005574 !db.TemplateParams.empty())
Howard Hinnantb2d1f942013-06-23 19:52:45 +00005575 {
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005576 db.FixForwardReferences = false;
5577 db.TagTemplates = false;
5578 db.Names.clear();
5579 db.Subs.clear();
Howard Hinnantb2d1f942013-06-23 19:52:45 +00005580 demangle(mangled_name, mangled_name + len, db, internal_status);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005581 if (db.FixForwardReferences)
Howard Hinnantb2d1f942013-06-23 19:52:45 +00005582 internal_status = invalid_mangled_name;
5583 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005584
Erik Pilkington761e6b02018-01-31 20:17:06 +00005585 if (internal_status == success &&
5586 db.Names.back()->containsUnexpandedParameterPack())
5587 internal_status = invalid_mangled_name;
5588
Howard Hinnant6c33e762013-06-17 18:10:34 +00005589 if (internal_status == success)
5590 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005591 if (!buf)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005592 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005593 internal_size = 1024;
5594 buf = static_cast<char*>(std::malloc(internal_size));
Howard Hinnant6c33e762013-06-17 18:10:34 +00005595 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005596
5597 if (buf)
Howard Hinnant6c33e762013-06-17 18:10:34 +00005598 {
Erik Pilkington0024acd2017-07-28 00:43:49 +00005599 OutputStream s(buf, internal_size);
Erik Pilkingtondc64cee2017-08-08 20:57:10 +00005600 db.Names.back()->print(s);
Erik Pilkington0024acd2017-07-28 00:43:49 +00005601 s += '\0';
5602 if (n) *n = s.getCurrentPosition();
5603 buf = s.getBuffer();
Howard Hinnant6c33e762013-06-17 18:10:34 +00005604 }
Erik Pilkington0024acd2017-07-28 00:43:49 +00005605 else
5606 internal_status = memory_alloc_failure;
Howard Hinnant6c33e762013-06-17 18:10:34 +00005607 }
5608 else
5609 buf = nullptr;
5610 if (status)
5611 *status = internal_status;
Howard Hinnantd213ffd2011-05-05 15:27:28 +00005612 return buf;
5613}
Howard Hinnant6c33e762013-06-17 18:10:34 +00005614} // __cxxabiv1