summaryrefslogtreecommitdiff
path: root/externals/demangle/llvm/Demangle/ItaniumDemangle.h
diff options
context:
space:
mode:
Diffstat (limited to 'externals/demangle/llvm/Demangle/ItaniumDemangle.h')
-rw-r--r--externals/demangle/llvm/Demangle/ItaniumDemangle.h3888
1 files changed, 1909 insertions, 1979 deletions
diff --git a/externals/demangle/llvm/Demangle/ItaniumDemangle.h b/externals/demangle/llvm/Demangle/ItaniumDemangle.h
index 64b35c142..0dc3d7337 100644
--- a/externals/demangle/llvm/Demangle/ItaniumDemangle.h
+++ b/externals/demangle/llvm/Demangle/ItaniumDemangle.h
@@ -1,5 +1,5 @@
1//===------------------------- ItaniumDemangle.h ----------------*- C++ -*-===// 1//===--- ItaniumDemangle.h -----------*- mode:c++;eval:(read-only-mode) -*-===//
2// 2// Do not edit! See README.txt.
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information. 4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-FileCopyrightText: Part of the LLVM Project 5// SPDX-FileCopyrightText: Part of the LLVM Project
@@ -7,144 +7,220 @@
7// 7//
8//===----------------------------------------------------------------------===// 8//===----------------------------------------------------------------------===//
9// 9//
10// Generic itanium demangler library. This file has two byte-per-byte identical 10// Generic itanium demangler library.
11// copies in the source tree, one in libcxxabi, and the other in llvm. 11// There are two copies of this file in the source tree. The one under
12// libcxxabi is the original and the one under llvm is the copy. Use
13// cp-to-llvm.sh to update the copy. See README.txt for more details.
12// 14//
13//===----------------------------------------------------------------------===// 15//===----------------------------------------------------------------------===//
14 16
15#ifndef DEMANGLE_ITANIUMDEMANGLE_H 17#ifndef DEMANGLE_ITANIUMDEMANGLE_H
16#define DEMANGLE_ITANIUMDEMANGLE_H 18#define DEMANGLE_ITANIUMDEMANGLE_H
17 19
18// FIXME: (possibly) incomplete list of features that clang mangles that this
19// file does not yet support:
20// - C++ modules TS
21
22#include "DemangleConfig.h" 20#include "DemangleConfig.h"
23#include "StringView.h" 21#include "StringViewExtras.h"
24#include "Utility.h" 22#include "Utility.h"
23#include <algorithm>
25#include <cassert> 24#include <cassert>
26#include <cctype> 25#include <cctype>
27#include <cstdio> 26#include <cstdio>
28#include <cstdlib> 27#include <cstdlib>
29#include <cstring> 28#include <cstring>
30#include <numeric> 29#include <limits>
30#include <new>
31#include <string_view>
32#include <type_traits>
31#include <utility> 33#include <utility>
32 34
33#define FOR_EACH_NODE_KIND(X) \
34 X(NodeArrayNode) \
35 X(DotSuffix) \
36 X(VendorExtQualType) \
37 X(QualType) \
38 X(ConversionOperatorType) \
39 X(PostfixQualifiedType) \
40 X(ElaboratedTypeSpefType) \
41 X(NameType) \
42 X(AbiTagAttr) \
43 X(EnableIfAttr) \
44 X(ObjCProtoName) \
45 X(PointerType) \
46 X(ReferenceType) \
47 X(PointerToMemberType) \
48 X(ArrayType) \
49 X(FunctionType) \
50 X(NoexceptSpec) \
51 X(DynamicExceptionSpec) \
52 X(FunctionEncoding) \
53 X(LiteralOperator) \
54 X(SpecialName) \
55 X(CtorVtableSpecialName) \
56 X(QualifiedName) \
57 X(NestedName) \
58 X(LocalName) \
59 X(VectorType) \
60 X(PixelVectorType) \
61 X(SyntheticTemplateParamName) \
62 X(TypeTemplateParamDecl) \
63 X(NonTypeTemplateParamDecl) \
64 X(TemplateTemplateParamDecl) \
65 X(TemplateParamPackDecl) \
66 X(ParameterPack) \
67 X(TemplateArgumentPack) \
68 X(ParameterPackExpansion) \
69 X(TemplateArgs) \
70 X(ForwardTemplateReference) \
71 X(NameWithTemplateArgs) \
72 X(GlobalQualifiedName) \
73 X(StdQualifiedName) \
74 X(ExpandedSpecialSubstitution) \
75 X(SpecialSubstitution) \
76 X(CtorDtorName) \
77 X(DtorName) \
78 X(UnnamedTypeName) \
79 X(ClosureTypeName) \
80 X(StructuredBindingName) \
81 X(BinaryExpr) \
82 X(ArraySubscriptExpr) \
83 X(PostfixExpr) \
84 X(ConditionalExpr) \
85 X(MemberExpr) \
86 X(EnclosingExpr) \
87 X(CastExpr) \
88 X(SizeofParamPackExpr) \
89 X(CallExpr) \
90 X(NewExpr) \
91 X(DeleteExpr) \
92 X(PrefixExpr) \
93 X(FunctionParam) \
94 X(ConversionExpr) \
95 X(InitListExpr) \
96 X(FoldExpr) \
97 X(ThrowExpr) \
98 X(UUIDOfExpr) \
99 X(BoolExpr) \
100 X(StringLiteral) \
101 X(LambdaExpr) \
102 X(IntegerCastExpr) \
103 X(IntegerLiteral) \
104 X(FloatLiteral) \
105 X(DoubleLiteral) \
106 X(LongDoubleLiteral) \
107 X(BracedExpr) \
108 X(BracedRangeExpr)
109
110DEMANGLE_NAMESPACE_BEGIN 35DEMANGLE_NAMESPACE_BEGIN
111 36
37template <class T, size_t N> class PODSmallVector {
38 static_assert(std::is_pod<T>::value,
39 "T is required to be a plain old data type");
40
41 T *First = nullptr;
42 T *Last = nullptr;
43 T *Cap = nullptr;
44 T Inline[N] = {0};
45
46 bool isInline() const { return First == Inline; }
47
48 void clearInline() {
49 First = Inline;
50 Last = Inline;
51 Cap = Inline + N;
52 }
53
54 void reserve(size_t NewCap) {
55 size_t S = size();
56 if (isInline()) {
57 auto *Tmp = static_cast<T *>(std::malloc(NewCap * sizeof(T)));
58 if (Tmp == nullptr)
59 std::terminate();
60 std::copy(First, Last, Tmp);
61 First = Tmp;
62 } else {
63 First = static_cast<T *>(std::realloc(First, NewCap * sizeof(T)));
64 if (First == nullptr)
65 std::terminate();
66 }
67 Last = First + S;
68 Cap = First + NewCap;
69 }
70
71public:
72 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
73
74 PODSmallVector(const PODSmallVector &) = delete;
75 PODSmallVector &operator=(const PODSmallVector &) = delete;
76
77 PODSmallVector(PODSmallVector &&Other) : PODSmallVector() {
78 if (Other.isInline()) {
79 std::copy(Other.begin(), Other.end(), First);
80 Last = First + Other.size();
81 Other.clear();
82 return;
83 }
84
85 First = Other.First;
86 Last = Other.Last;
87 Cap = Other.Cap;
88 Other.clearInline();
89 }
90
91 PODSmallVector &operator=(PODSmallVector &&Other) {
92 if (Other.isInline()) {
93 if (!isInline()) {
94 std::free(First);
95 clearInline();
96 }
97 std::copy(Other.begin(), Other.end(), First);
98 Last = First + Other.size();
99 Other.clear();
100 return *this;
101 }
102
103 if (isInline()) {
104 First = Other.First;
105 Last = Other.Last;
106 Cap = Other.Cap;
107 Other.clearInline();
108 return *this;
109 }
110
111 std::swap(First, Other.First);
112 std::swap(Last, Other.Last);
113 std::swap(Cap, Other.Cap);
114 Other.clear();
115 return *this;
116 }
117
118 // NOLINTNEXTLINE(readability-identifier-naming)
119 void push_back(const T &Elem) {
120 if (Last == Cap)
121 reserve(size() * 2);
122 *Last++ = Elem;
123 }
124
125 // NOLINTNEXTLINE(readability-identifier-naming)
126 void pop_back() {
127 assert(Last != First && "Popping empty vector!");
128 --Last;
129 }
130
131 void dropBack(size_t Index) {
132 assert(Index <= size() && "dropBack() can't expand!");
133 Last = First + Index;
134 }
135
136 T *begin() { return First; }
137 T *end() { return Last; }
138
139 bool empty() const { return First == Last; }
140 size_t size() const { return static_cast<size_t>(Last - First); }
141 T &back() {
142 assert(Last != First && "Calling back() on empty vector!");
143 return *(Last - 1);
144 }
145 T &operator[](size_t Index) {
146 assert(Index < size() && "Invalid access!");
147 return *(begin() + Index);
148 }
149 void clear() { Last = First; }
150
151 ~PODSmallVector() {
152 if (!isInline())
153 std::free(First);
154 }
155};
156
112// Base class of all AST nodes. The AST is built by the parser, then is 157// Base class of all AST nodes. The AST is built by the parser, then is
113// traversed by the printLeft/Right functions to produce a demangled string. 158// traversed by the printLeft/Right functions to produce a demangled string.
114class Node { 159class Node {
115public: 160public:
116 enum Kind : unsigned char { 161 enum Kind : unsigned char {
117#define ENUMERATOR(NodeKind) K ## NodeKind, 162#define NODE(NodeKind) K##NodeKind,
118 FOR_EACH_NODE_KIND(ENUMERATOR) 163#include "ItaniumNodes.def"
119#undef ENUMERATOR
120 }; 164 };
121 165
122 /// Three-way bool to track a cached value. Unknown is possible if this node 166 /// Three-way bool to track a cached value. Unknown is possible if this node
123 /// has an unexpanded parameter pack below it that may affect this cache. 167 /// has an unexpanded parameter pack below it that may affect this cache.
124 enum class Cache : unsigned char { Yes, No, Unknown, }; 168 enum class Cache : unsigned char { Yes, No, Unknown, };
125 169
170 /// Operator precedence for expression nodes. Used to determine required
171 /// parens in expression emission.
172 enum class Prec {
173 Primary,
174 Postfix,
175 Unary,
176 Cast,
177 PtrMem,
178 Multiplicative,
179 Additive,
180 Shift,
181 Spaceship,
182 Relational,
183 Equality,
184 And,
185 Xor,
186 Ior,
187 AndIf,
188 OrIf,
189 Conditional,
190 Assign,
191 Comma,
192 Default,
193 };
194
126private: 195private:
127 Kind K; 196 Kind K;
128 197
198 Prec Precedence : 6;
199
129 // FIXME: Make these protected. 200 // FIXME: Make these protected.
130public: 201public:
131 /// Tracks if this node has a component on its right side, in which case we 202 /// Tracks if this node has a component on its right side, in which case we
132 /// need to call printRight. 203 /// need to call printRight.
133 Cache RHSComponentCache; 204 Cache RHSComponentCache : 2;
134 205
135 /// Track if this node is a (possibly qualified) array type. This can affect 206 /// Track if this node is a (possibly qualified) array type. This can affect
136 /// how we format the output string. 207 /// how we format the output string.
137 Cache ArrayCache; 208 Cache ArrayCache : 2;
138 209
139 /// Track if this node is a (possibly qualified) function type. This can 210 /// Track if this node is a (possibly qualified) function type. This can
140 /// affect how we format the output string. 211 /// affect how we format the output string.
141 Cache FunctionCache; 212 Cache FunctionCache : 2;
142 213
143public: 214public:
144 Node(Kind K_, Cache RHSComponentCache_ = Cache::No, 215 Node(Kind K_, Prec Precedence_ = Prec::Primary,
145 Cache ArrayCache_ = Cache::No, Cache FunctionCache_ = Cache::No) 216 Cache RHSComponentCache_ = Cache::No, Cache ArrayCache_ = Cache::No,
146 : K(K_), RHSComponentCache(RHSComponentCache_), ArrayCache(ArrayCache_), 217 Cache FunctionCache_ = Cache::No)
147 FunctionCache(FunctionCache_) {} 218 : K(K_), Precedence(Precedence_), RHSComponentCache(RHSComponentCache_),
219 ArrayCache(ArrayCache_), FunctionCache(FunctionCache_) {}
220 Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_ = Cache::No,
221 Cache FunctionCache_ = Cache::No)
222 : Node(K_, Prec::Primary, RHSComponentCache_, ArrayCache_,
223 FunctionCache_) {}
148 224
149 /// Visit the most-derived object corresponding to this object. 225 /// Visit the most-derived object corresponding to this object.
150 template<typename Fn> void visit(Fn F) const; 226 template<typename Fn> void visit(Fn F) const;
@@ -155,52 +231,65 @@ public:
155 // would construct an equivalent node. 231 // would construct an equivalent node.
156 //template<typename Fn> void match(Fn F) const; 232 //template<typename Fn> void match(Fn F) const;
157 233
158 bool hasRHSComponent(OutputStream &S) const { 234 bool hasRHSComponent(OutputBuffer &OB) const {
159 if (RHSComponentCache != Cache::Unknown) 235 if (RHSComponentCache != Cache::Unknown)
160 return RHSComponentCache == Cache::Yes; 236 return RHSComponentCache == Cache::Yes;
161 return hasRHSComponentSlow(S); 237 return hasRHSComponentSlow(OB);
162 } 238 }
163 239
164 bool hasArray(OutputStream &S) const { 240 bool hasArray(OutputBuffer &OB) const {
165 if (ArrayCache != Cache::Unknown) 241 if (ArrayCache != Cache::Unknown)
166 return ArrayCache == Cache::Yes; 242 return ArrayCache == Cache::Yes;
167 return hasArraySlow(S); 243 return hasArraySlow(OB);
168 } 244 }
169 245
170 bool hasFunction(OutputStream &S) const { 246 bool hasFunction(OutputBuffer &OB) const {
171 if (FunctionCache != Cache::Unknown) 247 if (FunctionCache != Cache::Unknown)
172 return FunctionCache == Cache::Yes; 248 return FunctionCache == Cache::Yes;
173 return hasFunctionSlow(S); 249 return hasFunctionSlow(OB);
174 } 250 }
175 251
176 Kind getKind() const { return K; } 252 Kind getKind() const { return K; }
177 253
178 virtual bool hasRHSComponentSlow(OutputStream &) const { return false; } 254 Prec getPrecedence() const { return Precedence; }
179 virtual bool hasArraySlow(OutputStream &) const { return false; } 255
180 virtual bool hasFunctionSlow(OutputStream &) const { return false; } 256 virtual bool hasRHSComponentSlow(OutputBuffer &) const { return false; }
257 virtual bool hasArraySlow(OutputBuffer &) const { return false; }
258 virtual bool hasFunctionSlow(OutputBuffer &) const { return false; }
181 259
182 // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to 260 // Dig through "glue" nodes like ParameterPack and ForwardTemplateReference to
183 // get at a node that actually represents some concrete syntax. 261 // get at a node that actually represents some concrete syntax.
184 virtual const Node *getSyntaxNode(OutputStream &) const { 262 virtual const Node *getSyntaxNode(OutputBuffer &) const { return this; }
185 return this; 263
186 } 264 // Print this node as an expression operand, surrounding it in parentheses if
187 265 // its precedence is [Strictly] weaker than P.
188 void print(OutputStream &S) const { 266 void printAsOperand(OutputBuffer &OB, Prec P = Prec::Default,
189 printLeft(S); 267 bool StrictlyWorse = false) const {
268 bool Paren =
269 unsigned(getPrecedence()) >= unsigned(P) + unsigned(StrictlyWorse);
270 if (Paren)
271 OB.printOpen();
272 print(OB);
273 if (Paren)
274 OB.printClose();
275 }
276
277 void print(OutputBuffer &OB) const {
278 printLeft(OB);
190 if (RHSComponentCache != Cache::No) 279 if (RHSComponentCache != Cache::No)
191 printRight(S); 280 printRight(OB);
192 } 281 }
193 282
194 // Print the "left" side of this Node into OutputStream. 283 // Print the "left" side of this Node into OutputBuffer.
195 virtual void printLeft(OutputStream &) const = 0; 284 virtual void printLeft(OutputBuffer &) const = 0;
196 285
197 // Print the "right". This distinction is necessary to represent C++ types 286 // Print the "right". This distinction is necessary to represent C++ types
198 // that appear on the RHS of their subtype, such as arrays or functions. 287 // that appear on the RHS of their subtype, such as arrays or functions.
199 // Since most types don't have such a component, provide a default 288 // Since most types don't have such a component, provide a default
200 // implementation. 289 // implementation.
201 virtual void printRight(OutputStream &) const {} 290 virtual void printRight(OutputBuffer &) const {}
202 291
203 virtual StringView getBaseName() const { return StringView(); } 292 virtual std::string_view getBaseName() const { return {}; }
204 293
205 // Silence compiler warnings, this dtor will never be called. 294 // Silence compiler warnings, this dtor will never be called.
206 virtual ~Node() = default; 295 virtual ~Node() = default;
@@ -227,19 +316,19 @@ public:
227 316
228 Node *operator[](size_t Idx) const { return Elements[Idx]; } 317 Node *operator[](size_t Idx) const { return Elements[Idx]; }
229 318
230 void printWithComma(OutputStream &S) const { 319 void printWithComma(OutputBuffer &OB) const {
231 bool FirstElement = true; 320 bool FirstElement = true;
232 for (size_t Idx = 0; Idx != NumElements; ++Idx) { 321 for (size_t Idx = 0; Idx != NumElements; ++Idx) {
233 size_t BeforeComma = S.getCurrentPosition(); 322 size_t BeforeComma = OB.getCurrentPosition();
234 if (!FirstElement) 323 if (!FirstElement)
235 S += ", "; 324 OB += ", ";
236 size_t AfterComma = S.getCurrentPosition(); 325 size_t AfterComma = OB.getCurrentPosition();
237 Elements[Idx]->print(S); 326 Elements[Idx]->printAsOperand(OB, Node::Prec::Comma);
238 327
239 // Elements[Idx] is an empty parameter pack expansion, we should erase the 328 // Elements[Idx] is an empty parameter pack expansion, we should erase the
240 // comma we just printed. 329 // comma we just printed.
241 if (AfterComma == S.getCurrentPosition()) { 330 if (AfterComma == OB.getCurrentPosition()) {
242 S.setCurrentPosition(BeforeComma); 331 OB.setCurrentPosition(BeforeComma);
243 continue; 332 continue;
244 } 333 }
245 334
@@ -254,43 +343,48 @@ struct NodeArrayNode : Node {
254 343
255 template<typename Fn> void match(Fn F) const { F(Array); } 344 template<typename Fn> void match(Fn F) const { F(Array); }
256 345
257 void printLeft(OutputStream &S) const override { 346 void printLeft(OutputBuffer &OB) const override { Array.printWithComma(OB); }
258 Array.printWithComma(S);
259 }
260}; 347};
261 348
262class DotSuffix final : public Node { 349class DotSuffix final : public Node {
263 const Node *Prefix; 350 const Node *Prefix;
264 const StringView Suffix; 351 const std::string_view Suffix;
265 352
266public: 353public:
267 DotSuffix(const Node *Prefix_, StringView Suffix_) 354 DotSuffix(const Node *Prefix_, std::string_view Suffix_)
268 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {} 355 : Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
269 356
270 template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); } 357 template<typename Fn> void match(Fn F) const { F(Prefix, Suffix); }
271 358
272 void printLeft(OutputStream &s) const override { 359 void printLeft(OutputBuffer &OB) const override {
273 Prefix->print(s); 360 Prefix->print(OB);
274 s += " ("; 361 OB += " (";
275 s += Suffix; 362 OB += Suffix;
276 s += ")"; 363 OB += ")";
277 } 364 }
278}; 365};
279 366
280class VendorExtQualType final : public Node { 367class VendorExtQualType final : public Node {
281 const Node *Ty; 368 const Node *Ty;
282 StringView Ext; 369 std::string_view Ext;
370 const Node *TA;
283 371
284public: 372public:
285 VendorExtQualType(const Node *Ty_, StringView Ext_) 373 VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
286 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_) {} 374 : Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
375
376 const Node *getTy() const { return Ty; }
377 std::string_view getExt() const { return Ext; }
378 const Node *getTA() const { return TA; }
287 379
288 template<typename Fn> void match(Fn F) const { F(Ty, Ext); } 380 template <typename Fn> void match(Fn F) const { F(Ty, Ext, TA); }
289 381
290 void printLeft(OutputStream &S) const override { 382 void printLeft(OutputBuffer &OB) const override {
291 Ty->print(S); 383 Ty->print(OB);
292 S += " "; 384 OB += " ";
293 S += Ext; 385 OB += Ext;
386 if (TA != nullptr)
387 TA->print(OB);
294 } 388 }
295}; 389};
296 390
@@ -316,13 +410,13 @@ protected:
316 const Qualifiers Quals; 410 const Qualifiers Quals;
317 const Node *Child; 411 const Node *Child;
318 412
319 void printQuals(OutputStream &S) const { 413 void printQuals(OutputBuffer &OB) const {
320 if (Quals & QualConst) 414 if (Quals & QualConst)
321 S += " const"; 415 OB += " const";
322 if (Quals & QualVolatile) 416 if (Quals & QualVolatile)
323 S += " volatile"; 417 OB += " volatile";
324 if (Quals & QualRestrict) 418 if (Quals & QualRestrict)
325 S += " restrict"; 419 OB += " restrict";
326 } 420 }
327 421
328public: 422public:
@@ -331,24 +425,27 @@ public:
331 Child_->ArrayCache, Child_->FunctionCache), 425 Child_->ArrayCache, Child_->FunctionCache),
332 Quals(Quals_), Child(Child_) {} 426 Quals(Quals_), Child(Child_) {}
333 427
428 Qualifiers getQuals() const { return Quals; }
429 const Node *getChild() const { return Child; }
430
334 template<typename Fn> void match(Fn F) const { F(Child, Quals); } 431 template<typename Fn> void match(Fn F) const { F(Child, Quals); }
335 432
336 bool hasRHSComponentSlow(OutputStream &S) const override { 433 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
337 return Child->hasRHSComponent(S); 434 return Child->hasRHSComponent(OB);
338 } 435 }
339 bool hasArraySlow(OutputStream &S) const override { 436 bool hasArraySlow(OutputBuffer &OB) const override {
340 return Child->hasArray(S); 437 return Child->hasArray(OB);
341 } 438 }
342 bool hasFunctionSlow(OutputStream &S) const override { 439 bool hasFunctionSlow(OutputBuffer &OB) const override {
343 return Child->hasFunction(S); 440 return Child->hasFunction(OB);
344 } 441 }
345 442
346 void printLeft(OutputStream &S) const override { 443 void printLeft(OutputBuffer &OB) const override {
347 Child->printLeft(S); 444 Child->printLeft(OB);
348 printQuals(S); 445 printQuals(OB);
349 } 446 }
350 447
351 void printRight(OutputStream &S) const override { Child->printRight(S); } 448 void printRight(OutputBuffer &OB) const override { Child->printRight(OB); }
352}; 449};
353 450
354class ConversionOperatorType final : public Node { 451class ConversionOperatorType final : public Node {
@@ -360,74 +457,96 @@ public:
360 457
361 template<typename Fn> void match(Fn F) const { F(Ty); } 458 template<typename Fn> void match(Fn F) const { F(Ty); }
362 459
363 void printLeft(OutputStream &S) const override { 460 void printLeft(OutputBuffer &OB) const override {
364 S += "operator "; 461 OB += "operator ";
365 Ty->print(S); 462 Ty->print(OB);
366 } 463 }
367}; 464};
368 465
369class PostfixQualifiedType final : public Node { 466class PostfixQualifiedType final : public Node {
370 const Node *Ty; 467 const Node *Ty;
371 const StringView Postfix; 468 const std::string_view Postfix;
372 469
373public: 470public:
374 PostfixQualifiedType(Node *Ty_, StringView Postfix_) 471 PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
375 : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {} 472 : Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
376 473
377 template<typename Fn> void match(Fn F) const { F(Ty, Postfix); } 474 template<typename Fn> void match(Fn F) const { F(Ty, Postfix); }
378 475
379 void printLeft(OutputStream &s) const override { 476 void printLeft(OutputBuffer &OB) const override {
380 Ty->printLeft(s); 477 Ty->printLeft(OB);
381 s += Postfix; 478 OB += Postfix;
382 } 479 }
383}; 480};
384 481
385class NameType final : public Node { 482class NameType final : public Node {
386 const StringView Name; 483 const std::string_view Name;
387 484
388public: 485public:
389 NameType(StringView Name_) : Node(KNameType), Name(Name_) {} 486 NameType(std::string_view Name_) : Node(KNameType), Name(Name_) {}
390 487
391 template<typename Fn> void match(Fn F) const { F(Name); } 488 template<typename Fn> void match(Fn F) const { F(Name); }
392 489
393 StringView getName() const { return Name; } 490 std::string_view getName() const { return Name; }
394 StringView getBaseName() const override { return Name; } 491 std::string_view getBaseName() const override { return Name; }
492
493 void printLeft(OutputBuffer &OB) const override { OB += Name; }
494};
495
496class BitIntType final : public Node {
497 const Node *Size;
498 bool Signed;
499
500public:
501 BitIntType(const Node *Size_, bool Signed_)
502 : Node(KBitIntType), Size(Size_), Signed(Signed_) {}
503
504 template <typename Fn> void match(Fn F) const { F(Size, Signed); }
395 505
396 void printLeft(OutputStream &s) const override { s += Name; } 506 void printLeft(OutputBuffer &OB) const override {
507 if (!Signed)
508 OB += "unsigned ";
509 OB += "_BitInt";
510 OB.printOpen();
511 Size->printAsOperand(OB);
512 OB.printClose();
513 }
397}; 514};
398 515
399class ElaboratedTypeSpefType : public Node { 516class ElaboratedTypeSpefType : public Node {
400 StringView Kind; 517 std::string_view Kind;
401 Node *Child; 518 Node *Child;
402public: 519public:
403 ElaboratedTypeSpefType(StringView Kind_, Node *Child_) 520 ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
404 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {} 521 : Node(KElaboratedTypeSpefType), Kind(Kind_), Child(Child_) {}
405 522
406 template<typename Fn> void match(Fn F) const { F(Kind, Child); } 523 template<typename Fn> void match(Fn F) const { F(Kind, Child); }
407 524
408 void printLeft(OutputStream &S) const override { 525 void printLeft(OutputBuffer &OB) const override {
409 S += Kind; 526 OB += Kind;
410 S += ' '; 527 OB += ' ';
411 Child->print(S); 528 Child->print(OB);
412 } 529 }
413}; 530};
414 531
415struct AbiTagAttr : Node { 532struct AbiTagAttr : Node {
416 Node *Base; 533 Node *Base;
417 StringView Tag; 534 std::string_view Tag;
418 535
419 AbiTagAttr(Node* Base_, StringView Tag_) 536 AbiTagAttr(Node *Base_, std::string_view Tag_)
420 : Node(KAbiTagAttr, Base_->RHSComponentCache, 537 : Node(KAbiTagAttr, Base_->RHSComponentCache, Base_->ArrayCache,
421 Base_->ArrayCache, Base_->FunctionCache), 538 Base_->FunctionCache),
422 Base(Base_), Tag(Tag_) {} 539 Base(Base_), Tag(Tag_) {}
423 540
424 template<typename Fn> void match(Fn F) const { F(Base, Tag); } 541 template<typename Fn> void match(Fn F) const { F(Base, Tag); }
425 542
426 void printLeft(OutputStream &S) const override { 543 std::string_view getBaseName() const override { return Base->getBaseName(); }
427 Base->printLeft(S); 544
428 S += "[abi:"; 545 void printLeft(OutputBuffer &OB) const override {
429 S += Tag; 546 Base->printLeft(OB);
430 S += "]"; 547 OB += "[abi:";
548 OB += Tag;
549 OB += "]";
431 } 550 }
432}; 551};
433 552
@@ -439,21 +558,21 @@ public:
439 558
440 template<typename Fn> void match(Fn F) const { F(Conditions); } 559 template<typename Fn> void match(Fn F) const { F(Conditions); }
441 560
442 void printLeft(OutputStream &S) const override { 561 void printLeft(OutputBuffer &OB) const override {
443 S += " [enable_if:"; 562 OB += " [enable_if:";
444 Conditions.printWithComma(S); 563 Conditions.printWithComma(OB);
445 S += ']'; 564 OB += ']';
446 } 565 }
447}; 566};
448 567
449class ObjCProtoName : public Node { 568class ObjCProtoName : public Node {
450 const Node *Ty; 569 const Node *Ty;
451 StringView Protocol; 570 std::string_view Protocol;
452 571
453 friend class PointerType; 572 friend class PointerType;
454 573
455public: 574public:
456 ObjCProtoName(const Node *Ty_, StringView Protocol_) 575 ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
457 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {} 576 : Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
458 577
459 template<typename Fn> void match(Fn F) const { F(Ty, Protocol); } 578 template<typename Fn> void match(Fn F) const { F(Ty, Protocol); }
@@ -463,11 +582,11 @@ public:
463 static_cast<const NameType *>(Ty)->getName() == "objc_object"; 582 static_cast<const NameType *>(Ty)->getName() == "objc_object";
464 } 583 }
465 584
466 void printLeft(OutputStream &S) const override { 585 void printLeft(OutputBuffer &OB) const override {
467 Ty->print(S); 586 Ty->print(OB);
468 S += "<"; 587 OB += "<";
469 S += Protocol; 588 OB += Protocol;
470 S += ">"; 589 OB += ">";
471 } 590 }
472}; 591};
473 592
@@ -479,36 +598,38 @@ public:
479 : Node(KPointerType, Pointee_->RHSComponentCache), 598 : Node(KPointerType, Pointee_->RHSComponentCache),
480 Pointee(Pointee_) {} 599 Pointee(Pointee_) {}
481 600
601 const Node *getPointee() const { return Pointee; }
602
482 template<typename Fn> void match(Fn F) const { F(Pointee); } 603 template<typename Fn> void match(Fn F) const { F(Pointee); }
483 604
484 bool hasRHSComponentSlow(OutputStream &S) const override { 605 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
485 return Pointee->hasRHSComponent(S); 606 return Pointee->hasRHSComponent(OB);
486 } 607 }
487 608
488 void printLeft(OutputStream &s) const override { 609 void printLeft(OutputBuffer &OB) const override {
489 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>. 610 // We rewrite objc_object<SomeProtocol>* into id<SomeProtocol>.
490 if (Pointee->getKind() != KObjCProtoName || 611 if (Pointee->getKind() != KObjCProtoName ||
491 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) { 612 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
492 Pointee->printLeft(s); 613 Pointee->printLeft(OB);
493 if (Pointee->hasArray(s)) 614 if (Pointee->hasArray(OB))
494 s += " "; 615 OB += " ";
495 if (Pointee->hasArray(s) || Pointee->hasFunction(s)) 616 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
496 s += "("; 617 OB += "(";
497 s += "*"; 618 OB += "*";
498 } else { 619 } else {
499 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee); 620 const auto *objcProto = static_cast<const ObjCProtoName *>(Pointee);
500 s += "id<"; 621 OB += "id<";
501 s += objcProto->Protocol; 622 OB += objcProto->Protocol;
502 s += ">"; 623 OB += ">";
503 } 624 }
504 } 625 }
505 626
506 void printRight(OutputStream &s) const override { 627 void printRight(OutputBuffer &OB) const override {
507 if (Pointee->getKind() != KObjCProtoName || 628 if (Pointee->getKind() != KObjCProtoName ||
508 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) { 629 !static_cast<const ObjCProtoName *>(Pointee)->isObjCObject()) {
509 if (Pointee->hasArray(s) || Pointee->hasFunction(s)) 630 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
510 s += ")"; 631 OB += ")";
511 Pointee->printRight(s); 632 Pointee->printRight(OB);
512 } 633 }
513 } 634 }
514}; 635};
@@ -528,15 +649,30 @@ class ReferenceType : public Node {
528 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The 649 // Dig through any refs to refs, collapsing the ReferenceTypes as we go. The
529 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any 650 // rule here is rvalue ref to rvalue ref collapses to a rvalue ref, and any
530 // other combination collapses to a lvalue ref. 651 // other combination collapses to a lvalue ref.
531 std::pair<ReferenceKind, const Node *> collapse(OutputStream &S) const { 652 //
653 // A combination of a TemplateForwardReference and a back-ref Substitution
654 // from an ill-formed string may have created a cycle; use cycle detection to
655 // avoid looping forever.
656 std::pair<ReferenceKind, const Node *> collapse(OutputBuffer &OB) const {
532 auto SoFar = std::make_pair(RK, Pointee); 657 auto SoFar = std::make_pair(RK, Pointee);
658 // Track the chain of nodes for the Floyd's 'tortoise and hare'
659 // cycle-detection algorithm, since getSyntaxNode(S) is impure
660 PODSmallVector<const Node *, 8> Prev;
533 for (;;) { 661 for (;;) {
534 const Node *SN = SoFar.second->getSyntaxNode(S); 662 const Node *SN = SoFar.second->getSyntaxNode(OB);
535 if (SN->getKind() != KReferenceType) 663 if (SN->getKind() != KReferenceType)
536 break; 664 break;
537 auto *RT = static_cast<const ReferenceType *>(SN); 665 auto *RT = static_cast<const ReferenceType *>(SN);
538 SoFar.second = RT->Pointee; 666 SoFar.second = RT->Pointee;
539 SoFar.first = std::min(SoFar.first, RT->RK); 667 SoFar.first = std::min(SoFar.first, RT->RK);
668
669 // The middle of Prev is the 'slow' pointer moving at half speed
670 Prev.push_back(SoFar.second);
671 if (Prev.size() > 1 && SoFar.second == Prev[(Prev.size() - 1) / 2]) {
672 // Cycle detected
673 SoFar.second = nullptr;
674 break;
675 }
540 } 676 }
541 return SoFar; 677 return SoFar;
542 } 678 }
@@ -548,31 +684,35 @@ public:
548 684
549 template<typename Fn> void match(Fn F) const { F(Pointee, RK); } 685 template<typename Fn> void match(Fn F) const { F(Pointee, RK); }
550 686
551 bool hasRHSComponentSlow(OutputStream &S) const override { 687 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
552 return Pointee->hasRHSComponent(S); 688 return Pointee->hasRHSComponent(OB);
553 } 689 }
554 690
555 void printLeft(OutputStream &s) const override { 691 void printLeft(OutputBuffer &OB) const override {
556 if (Printing) 692 if (Printing)
557 return; 693 return;
558 SwapAndRestore<bool> SavePrinting(Printing, true); 694 ScopedOverride<bool> SavePrinting(Printing, true);
559 std::pair<ReferenceKind, const Node *> Collapsed = collapse(s); 695 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
560 Collapsed.second->printLeft(s); 696 if (!Collapsed.second)
561 if (Collapsed.second->hasArray(s)) 697 return;
562 s += " "; 698 Collapsed.second->printLeft(OB);
563 if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s)) 699 if (Collapsed.second->hasArray(OB))
564 s += "("; 700 OB += " ";
701 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
702 OB += "(";
565 703
566 s += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&"); 704 OB += (Collapsed.first == ReferenceKind::LValue ? "&" : "&&");
567 } 705 }
568 void printRight(OutputStream &s) const override { 706 void printRight(OutputBuffer &OB) const override {
569 if (Printing) 707 if (Printing)
570 return; 708 return;
571 SwapAndRestore<bool> SavePrinting(Printing, true); 709 ScopedOverride<bool> SavePrinting(Printing, true);
572 std::pair<ReferenceKind, const Node *> Collapsed = collapse(s); 710 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
573 if (Collapsed.second->hasArray(s) || Collapsed.second->hasFunction(s)) 711 if (!Collapsed.second)
574 s += ")"; 712 return;
575 Collapsed.second->printRight(s); 713 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
714 OB += ")";
715 Collapsed.second->printRight(OB);
576 } 716 }
577}; 717};
578 718
@@ -587,69 +727,33 @@ public:
587 727
588 template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); } 728 template<typename Fn> void match(Fn F) const { F(ClassType, MemberType); }
589 729
590 bool hasRHSComponentSlow(OutputStream &S) const override { 730 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
591 return MemberType->hasRHSComponent(S); 731 return MemberType->hasRHSComponent(OB);
592 } 732 }
593 733
594 void printLeft(OutputStream &s) const override { 734 void printLeft(OutputBuffer &OB) const override {
595 MemberType->printLeft(s); 735 MemberType->printLeft(OB);
596 if (MemberType->hasArray(s) || MemberType->hasFunction(s)) 736 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
597 s += "("; 737 OB += "(";
598 else 738 else
599 s += " "; 739 OB += " ";
600 ClassType->print(s); 740 ClassType->print(OB);
601 s += "::*"; 741 OB += "::*";
602 }
603
604 void printRight(OutputStream &s) const override {
605 if (MemberType->hasArray(s) || MemberType->hasFunction(s))
606 s += ")";
607 MemberType->printRight(s);
608 }
609};
610
611class NodeOrString {
612 const void *First;
613 const void *Second;
614
615public:
616 /* implicit */ NodeOrString(StringView Str) {
617 const char *FirstChar = Str.begin();
618 const char *SecondChar = Str.end();
619 if (SecondChar == nullptr) {
620 assert(FirstChar == SecondChar);
621 ++FirstChar, ++SecondChar;
622 }
623 First = static_cast<const void *>(FirstChar);
624 Second = static_cast<const void *>(SecondChar);
625 } 742 }
626 743
627 /* implicit */ NodeOrString(Node *N) 744 void printRight(OutputBuffer &OB) const override {
628 : First(static_cast<const void *>(N)), Second(nullptr) {} 745 if (MemberType->hasArray(OB) || MemberType->hasFunction(OB))
629 NodeOrString() : First(nullptr), Second(nullptr) {} 746 OB += ")";
630 747 MemberType->printRight(OB);
631 bool isString() const { return Second && First; }
632 bool isNode() const { return First && !Second; }
633 bool isEmpty() const { return !First && !Second; }
634
635 StringView asString() const {
636 assert(isString());
637 return StringView(static_cast<const char *>(First),
638 static_cast<const char *>(Second));
639 }
640
641 const Node *asNode() const {
642 assert(isNode());
643 return static_cast<const Node *>(First);
644 } 748 }
645}; 749};
646 750
647class ArrayType final : public Node { 751class ArrayType final : public Node {
648 const Node *Base; 752 const Node *Base;
649 NodeOrString Dimension; 753 Node *Dimension;
650 754
651public: 755public:
652 ArrayType(const Node *Base_, NodeOrString Dimension_) 756 ArrayType(const Node *Base_, Node *Dimension_)
653 : Node(KArrayType, 757 : Node(KArrayType,
654 /*RHSComponentCache=*/Cache::Yes, 758 /*RHSComponentCache=*/Cache::Yes,
655 /*ArrayCache=*/Cache::Yes), 759 /*ArrayCache=*/Cache::Yes),
@@ -657,21 +761,19 @@ public:
657 761
658 template<typename Fn> void match(Fn F) const { F(Base, Dimension); } 762 template<typename Fn> void match(Fn F) const { F(Base, Dimension); }
659 763
660 bool hasRHSComponentSlow(OutputStream &) const override { return true; } 764 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
661 bool hasArraySlow(OutputStream &) const override { return true; } 765 bool hasArraySlow(OutputBuffer &) const override { return true; }
662 766
663 void printLeft(OutputStream &S) const override { Base->printLeft(S); } 767 void printLeft(OutputBuffer &OB) const override { Base->printLeft(OB); }
664 768
665 void printRight(OutputStream &S) const override { 769 void printRight(OutputBuffer &OB) const override {
666 if (S.back() != ']') 770 if (OB.back() != ']')
667 S += " "; 771 OB += " ";
668 S += "["; 772 OB += "[";
669 if (Dimension.isString()) 773 if (Dimension)
670 S += Dimension.asString(); 774 Dimension->print(OB);
671 else if (Dimension.isNode()) 775 OB += "]";
672 Dimension.asNode()->print(S); 776 Base->printRight(OB);
673 S += "]";
674 Base->printRight(S);
675 } 777 }
676}; 778};
677 779
@@ -695,8 +797,8 @@ public:
695 F(Ret, Params, CVQuals, RefQual, ExceptionSpec); 797 F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
696 } 798 }
697 799
698 bool hasRHSComponentSlow(OutputStream &) const override { return true; } 800 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
699 bool hasFunctionSlow(OutputStream &) const override { return true; } 801 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
700 802
701 // Handle C++'s ... quirky decl grammar by using the left & right 803 // Handle C++'s ... quirky decl grammar by using the left & right
702 // distinction. Consider: 804 // distinction. Consider:
@@ -705,32 +807,32 @@ public:
705 // that takes a char and returns an int. If we're trying to print f, start 807 // that takes a char and returns an int. If we're trying to print f, start
706 // by printing out the return types's left, then print our parameters, then 808 // by printing out the return types's left, then print our parameters, then
707 // finally print right of the return type. 809 // finally print right of the return type.
708 void printLeft(OutputStream &S) const override { 810 void printLeft(OutputBuffer &OB) const override {
709 Ret->printLeft(S); 811 Ret->printLeft(OB);
710 S += " "; 812 OB += " ";
711 } 813 }
712 814
713 void printRight(OutputStream &S) const override { 815 void printRight(OutputBuffer &OB) const override {
714 S += "("; 816 OB.printOpen();
715 Params.printWithComma(S); 817 Params.printWithComma(OB);
716 S += ")"; 818 OB.printClose();
717 Ret->printRight(S); 819 Ret->printRight(OB);
718 820
719 if (CVQuals & QualConst) 821 if (CVQuals & QualConst)
720 S += " const"; 822 OB += " const";
721 if (CVQuals & QualVolatile) 823 if (CVQuals & QualVolatile)
722 S += " volatile"; 824 OB += " volatile";
723 if (CVQuals & QualRestrict) 825 if (CVQuals & QualRestrict)
724 S += " restrict"; 826 OB += " restrict";
725 827
726 if (RefQual == FrefQualLValue) 828 if (RefQual == FrefQualLValue)
727 S += " &"; 829 OB += " &";
728 else if (RefQual == FrefQualRValue) 830 else if (RefQual == FrefQualRValue)
729 S += " &&"; 831 OB += " &&";
730 832
731 if (ExceptionSpec != nullptr) { 833 if (ExceptionSpec != nullptr) {
732 S += ' '; 834 OB += ' ';
733 ExceptionSpec->print(S); 835 ExceptionSpec->print(OB);
734 } 836 }
735 } 837 }
736}; 838};
@@ -742,10 +844,11 @@ public:
742 844
743 template<typename Fn> void match(Fn F) const { F(E); } 845 template<typename Fn> void match(Fn F) const { F(E); }
744 846
745 void printLeft(OutputStream &S) const override { 847 void printLeft(OutputBuffer &OB) const override {
746 S += "noexcept("; 848 OB += "noexcept";
747 E->print(S); 849 OB.printOpen();
748 S += ")"; 850 E->printAsOperand(OB);
851 OB.printClose();
749 } 852 }
750}; 853};
751 854
@@ -757,10 +860,11 @@ public:
757 860
758 template<typename Fn> void match(Fn F) const { F(Types); } 861 template<typename Fn> void match(Fn F) const { F(Types); }
759 862
760 void printLeft(OutputStream &S) const override { 863 void printLeft(OutputBuffer &OB) const override {
761 S += "throw("; 864 OB += "throw";
762 Types.printWithComma(S); 865 OB.printOpen();
763 S += ')'; 866 Types.printWithComma(OB);
867 OB.printClose();
764 } 868 }
765}; 869};
766 870
@@ -791,41 +895,41 @@ public:
791 NodeArray getParams() const { return Params; } 895 NodeArray getParams() const { return Params; }
792 const Node *getReturnType() const { return Ret; } 896 const Node *getReturnType() const { return Ret; }
793 897
794 bool hasRHSComponentSlow(OutputStream &) const override { return true; } 898 bool hasRHSComponentSlow(OutputBuffer &) const override { return true; }
795 bool hasFunctionSlow(OutputStream &) const override { return true; } 899 bool hasFunctionSlow(OutputBuffer &) const override { return true; }
796 900
797 const Node *getName() const { return Name; } 901 const Node *getName() const { return Name; }
798 902
799 void printLeft(OutputStream &S) const override { 903 void printLeft(OutputBuffer &OB) const override {
800 if (Ret) { 904 if (Ret) {
801 Ret->printLeft(S); 905 Ret->printLeft(OB);
802 if (!Ret->hasRHSComponent(S)) 906 if (!Ret->hasRHSComponent(OB))
803 S += " "; 907 OB += " ";
804 } 908 }
805 Name->print(S); 909 Name->print(OB);
806 } 910 }
807 911
808 void printRight(OutputStream &S) const override { 912 void printRight(OutputBuffer &OB) const override {
809 S += "("; 913 OB.printOpen();
810 Params.printWithComma(S); 914 Params.printWithComma(OB);
811 S += ")"; 915 OB.printClose();
812 if (Ret) 916 if (Ret)
813 Ret->printRight(S); 917 Ret->printRight(OB);
814 918
815 if (CVQuals & QualConst) 919 if (CVQuals & QualConst)
816 S += " const"; 920 OB += " const";
817 if (CVQuals & QualVolatile) 921 if (CVQuals & QualVolatile)
818 S += " volatile"; 922 OB += " volatile";
819 if (CVQuals & QualRestrict) 923 if (CVQuals & QualRestrict)
820 S += " restrict"; 924 OB += " restrict";
821 925
822 if (RefQual == FrefQualLValue) 926 if (RefQual == FrefQualLValue)
823 S += " &"; 927 OB += " &";
824 else if (RefQual == FrefQualRValue) 928 else if (RefQual == FrefQualRValue)
825 S += " &&"; 929 OB += " &&";
826 930
827 if (Attrs != nullptr) 931 if (Attrs != nullptr)
828 Attrs->print(S); 932 Attrs->print(OB);
829 } 933 }
830}; 934};
831 935
@@ -838,25 +942,25 @@ public:
838 942
839 template<typename Fn> void match(Fn F) const { F(OpName); } 943 template<typename Fn> void match(Fn F) const { F(OpName); }
840 944
841 void printLeft(OutputStream &S) const override { 945 void printLeft(OutputBuffer &OB) const override {
842 S += "operator\"\" "; 946 OB += "operator\"\" ";
843 OpName->print(S); 947 OpName->print(OB);
844 } 948 }
845}; 949};
846 950
847class SpecialName final : public Node { 951class SpecialName final : public Node {
848 const StringView Special; 952 const std::string_view Special;
849 const Node *Child; 953 const Node *Child;
850 954
851public: 955public:
852 SpecialName(StringView Special_, const Node *Child_) 956 SpecialName(std::string_view Special_, const Node *Child_)
853 : Node(KSpecialName), Special(Special_), Child(Child_) {} 957 : Node(KSpecialName), Special(Special_), Child(Child_) {}
854 958
855 template<typename Fn> void match(Fn F) const { F(Special, Child); } 959 template<typename Fn> void match(Fn F) const { F(Special, Child); }
856 960
857 void printLeft(OutputStream &S) const override { 961 void printLeft(OutputBuffer &OB) const override {
858 S += Special; 962 OB += Special;
859 Child->print(S); 963 Child->print(OB);
860 } 964 }
861}; 965};
862 966
@@ -871,11 +975,11 @@ public:
871 975
872 template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); } 976 template<typename Fn> void match(Fn F) const { F(FirstType, SecondType); }
873 977
874 void printLeft(OutputStream &S) const override { 978 void printLeft(OutputBuffer &OB) const override {
875 S += "construction vtable for "; 979 OB += "construction vtable for ";
876 FirstType->print(S); 980 FirstType->print(OB);
877 S += "-in-"; 981 OB += "-in-";
878 SecondType->print(S); 982 SecondType->print(OB);
879 } 983 }
880}; 984};
881 985
@@ -888,12 +992,52 @@ struct NestedName : Node {
888 992
889 template<typename Fn> void match(Fn F) const { F(Qual, Name); } 993 template<typename Fn> void match(Fn F) const { F(Qual, Name); }
890 994
891 StringView getBaseName() const override { return Name->getBaseName(); } 995 std::string_view getBaseName() const override { return Name->getBaseName(); }
996
997 void printLeft(OutputBuffer &OB) const override {
998 Qual->print(OB);
999 OB += "::";
1000 Name->print(OB);
1001 }
1002};
1003
1004struct ModuleName : Node {
1005 ModuleName *Parent;
1006 Node *Name;
1007 bool IsPartition;
1008
1009 ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_ = false)
1010 : Node(KModuleName), Parent(Parent_), Name(Name_),
1011 IsPartition(IsPartition_) {}
1012
1013 template <typename Fn> void match(Fn F) const {
1014 F(Parent, Name, IsPartition);
1015 }
1016
1017 void printLeft(OutputBuffer &OB) const override {
1018 if (Parent)
1019 Parent->print(OB);
1020 if (Parent || IsPartition)
1021 OB += IsPartition ? ':' : '.';
1022 Name->print(OB);
1023 }
1024};
1025
1026struct ModuleEntity : Node {
1027 ModuleName *Module;
1028 Node *Name;
1029
1030 ModuleEntity(ModuleName *Module_, Node *Name_)
1031 : Node(KModuleEntity), Module(Module_), Name(Name_) {}
1032
1033 template <typename Fn> void match(Fn F) const { F(Module, Name); }
1034
1035 std::string_view getBaseName() const override { return Name->getBaseName(); }
892 1036
893 void printLeft(OutputStream &S) const override { 1037 void printLeft(OutputBuffer &OB) const override {
894 Qual->print(S); 1038 Name->print(OB);
895 S += "::"; 1039 OB += '@';
896 Name->print(S); 1040 Module->print(OB);
897 } 1041 }
898}; 1042};
899 1043
@@ -906,10 +1050,10 @@ struct LocalName : Node {
906 1050
907 template<typename Fn> void match(Fn F) const { F(Encoding, Entity); } 1051 template<typename Fn> void match(Fn F) const { F(Encoding, Entity); }
908 1052
909 void printLeft(OutputStream &S) const override { 1053 void printLeft(OutputBuffer &OB) const override {
910 Encoding->print(S); 1054 Encoding->print(OB);
911 S += "::"; 1055 OB += "::";
912 Entity->print(S); 1056 Entity->print(OB);
913 } 1057 }
914}; 1058};
915 1059
@@ -924,51 +1068,66 @@ public:
924 1068
925 template<typename Fn> void match(Fn F) const { F(Qualifier, Name); } 1069 template<typename Fn> void match(Fn F) const { F(Qualifier, Name); }
926 1070
927 StringView getBaseName() const override { return Name->getBaseName(); } 1071 std::string_view getBaseName() const override { return Name->getBaseName(); }
928 1072
929 void printLeft(OutputStream &S) const override { 1073 void printLeft(OutputBuffer &OB) const override {
930 Qualifier->print(S); 1074 Qualifier->print(OB);
931 S += "::"; 1075 OB += "::";
932 Name->print(S); 1076 Name->print(OB);
933 } 1077 }
934}; 1078};
935 1079
936class VectorType final : public Node { 1080class VectorType final : public Node {
937 const Node *BaseType; 1081 const Node *BaseType;
938 const NodeOrString Dimension; 1082 const Node *Dimension;
939 1083
940public: 1084public:
941 VectorType(const Node *BaseType_, NodeOrString Dimension_) 1085 VectorType(const Node *BaseType_, const Node *Dimension_)
942 : Node(KVectorType), BaseType(BaseType_), 1086 : Node(KVectorType), BaseType(BaseType_), Dimension(Dimension_) {}
943 Dimension(Dimension_) {} 1087
1088 const Node *getBaseType() const { return BaseType; }
1089 const Node *getDimension() const { return Dimension; }
944 1090
945 template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); } 1091 template<typename Fn> void match(Fn F) const { F(BaseType, Dimension); }
946 1092
947 void printLeft(OutputStream &S) const override { 1093 void printLeft(OutputBuffer &OB) const override {
948 BaseType->print(S); 1094 BaseType->print(OB);
949 S += " vector["; 1095 OB += " vector[";
950 if (Dimension.isNode()) 1096 if (Dimension)
951 Dimension.asNode()->print(S); 1097 Dimension->print(OB);
952 else if (Dimension.isString()) 1098 OB += "]";
953 S += Dimension.asString();
954 S += "]";
955 } 1099 }
956}; 1100};
957 1101
958class PixelVectorType final : public Node { 1102class PixelVectorType final : public Node {
959 const NodeOrString Dimension; 1103 const Node *Dimension;
960 1104
961public: 1105public:
962 PixelVectorType(NodeOrString Dimension_) 1106 PixelVectorType(const Node *Dimension_)
963 : Node(KPixelVectorType), Dimension(Dimension_) {} 1107 : Node(KPixelVectorType), Dimension(Dimension_) {}
964 1108
965 template<typename Fn> void match(Fn F) const { F(Dimension); } 1109 template<typename Fn> void match(Fn F) const { F(Dimension); }
966 1110
967 void printLeft(OutputStream &S) const override { 1111 void printLeft(OutputBuffer &OB) const override {
968 // FIXME: This should demangle as "vector pixel". 1112 // FIXME: This should demangle as "vector pixel".
969 S += "pixel vector["; 1113 OB += "pixel vector[";
970 S += Dimension.asString(); 1114 Dimension->print(OB);
971 S += "]"; 1115 OB += "]";
1116 }
1117};
1118
1119class BinaryFPType final : public Node {
1120 const Node *Dimension;
1121
1122public:
1123 BinaryFPType(const Node *Dimension_)
1124 : Node(KBinaryFPType), Dimension(Dimension_) {}
1125
1126 template<typename Fn> void match(Fn F) const { F(Dimension); }
1127
1128 void printLeft(OutputBuffer &OB) const override {
1129 OB += "_Float";
1130 Dimension->print(OB);
972 } 1131 }
973}; 1132};
974 1133
@@ -990,20 +1149,20 @@ public:
990 1149
991 template<typename Fn> void match(Fn F) const { F(Kind, Index); } 1150 template<typename Fn> void match(Fn F) const { F(Kind, Index); }
992 1151
993 void printLeft(OutputStream &S) const override { 1152 void printLeft(OutputBuffer &OB) const override {
994 switch (Kind) { 1153 switch (Kind) {
995 case TemplateParamKind::Type: 1154 case TemplateParamKind::Type:
996 S += "$T"; 1155 OB += "$T";
997 break; 1156 break;
998 case TemplateParamKind::NonType: 1157 case TemplateParamKind::NonType:
999 S += "$N"; 1158 OB += "$N";
1000 break; 1159 break;
1001 case TemplateParamKind::Template: 1160 case TemplateParamKind::Template:
1002 S += "$TT"; 1161 OB += "$TT";
1003 break; 1162 break;
1004 } 1163 }
1005 if (Index > 0) 1164 if (Index > 0)
1006 S << Index - 1; 1165 OB << Index - 1;
1007 } 1166 }
1008}; 1167};
1009 1168
@@ -1017,13 +1176,9 @@ public:
1017 1176
1018 template<typename Fn> void match(Fn F) const { F(Name); } 1177 template<typename Fn> void match(Fn F) const { F(Name); }
1019 1178
1020 void printLeft(OutputStream &S) const override { 1179 void printLeft(OutputBuffer &OB) const override { OB += "typename "; }
1021 S += "typename ";
1022 }
1023 1180
1024 void printRight(OutputStream &S) const override { 1181 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1025 Name->print(S);
1026 }
1027}; 1182};
1028 1183
1029/// A non-type template parameter declaration, 'int N'. 1184/// A non-type template parameter declaration, 'int N'.
@@ -1037,15 +1192,15 @@ public:
1037 1192
1038 template<typename Fn> void match(Fn F) const { F(Name, Type); } 1193 template<typename Fn> void match(Fn F) const { F(Name, Type); }
1039 1194
1040 void printLeft(OutputStream &S) const override { 1195 void printLeft(OutputBuffer &OB) const override {
1041 Type->printLeft(S); 1196 Type->printLeft(OB);
1042 if (!Type->hasRHSComponent(S)) 1197 if (!Type->hasRHSComponent(OB))
1043 S += " "; 1198 OB += " ";
1044 } 1199 }
1045 1200
1046 void printRight(OutputStream &S) const override { 1201 void printRight(OutputBuffer &OB) const override {
1047 Name->print(S); 1202 Name->print(OB);
1048 Type->printRight(S); 1203 Type->printRight(OB);
1049 } 1204 }
1050}; 1205};
1051 1206
@@ -1062,15 +1217,14 @@ public:
1062 1217
1063 template<typename Fn> void match(Fn F) const { F(Name, Params); } 1218 template<typename Fn> void match(Fn F) const { F(Name, Params); }
1064 1219
1065 void printLeft(OutputStream &S) const override { 1220 void printLeft(OutputBuffer &OB) const override {
1066 S += "template<"; 1221 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1067 Params.printWithComma(S); 1222 OB += "template<";
1068 S += "> typename "; 1223 Params.printWithComma(OB);
1224 OB += "> typename ";
1069 } 1225 }
1070 1226
1071 void printRight(OutputStream &S) const override { 1227 void printRight(OutputBuffer &OB) const override { Name->print(OB); }
1072 Name->print(S);
1073 }
1074}; 1228};
1075 1229
1076/// A template parameter pack declaration, 'typename ...T'. 1230/// A template parameter pack declaration, 'typename ...T'.
@@ -1083,14 +1237,12 @@ public:
1083 1237
1084 template<typename Fn> void match(Fn F) const { F(Param); } 1238 template<typename Fn> void match(Fn F) const { F(Param); }
1085 1239
1086 void printLeft(OutputStream &S) const override { 1240 void printLeft(OutputBuffer &OB) const override {
1087 Param->printLeft(S); 1241 Param->printLeft(OB);
1088 S += "..."; 1242 OB += "...";
1089 } 1243 }
1090 1244
1091 void printRight(OutputStream &S) const override { 1245 void printRight(OutputBuffer &OB) const override { Param->printRight(OB); }
1092 Param->printRight(S);
1093 }
1094}; 1246};
1095 1247
1096/// An unexpanded parameter pack (either in the expression or type context). If 1248/// An unexpanded parameter pack (either in the expression or type context). If
@@ -1104,11 +1256,12 @@ public:
1104class ParameterPack final : public Node { 1256class ParameterPack final : public Node {
1105 NodeArray Data; 1257 NodeArray Data;
1106 1258
1107 // Setup OutputStream for a pack expansion unless we're already expanding one. 1259 // Setup OutputBuffer for a pack expansion, unless we're already expanding
1108 void initializePackExpansion(OutputStream &S) const { 1260 // one.
1109 if (S.CurrentPackMax == std::numeric_limits<unsigned>::max()) { 1261 void initializePackExpansion(OutputBuffer &OB) const {
1110 S.CurrentPackMax = static_cast<unsigned>(Data.size()); 1262 if (OB.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
1111 S.CurrentPackIndex = 0; 1263 OB.CurrentPackMax = static_cast<unsigned>(Data.size());
1264 OB.CurrentPackIndex = 0;
1112 } 1265 }
1113 } 1266 }
1114 1267
@@ -1131,38 +1284,38 @@ public:
1131 1284
1132 template<typename Fn> void match(Fn F) const { F(Data); } 1285 template<typename Fn> void match(Fn F) const { F(Data); }
1133 1286
1134 bool hasRHSComponentSlow(OutputStream &S) const override { 1287 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1135 initializePackExpansion(S); 1288 initializePackExpansion(OB);
1136 size_t Idx = S.CurrentPackIndex; 1289 size_t Idx = OB.CurrentPackIndex;
1137 return Idx < Data.size() && Data[Idx]->hasRHSComponent(S); 1290 return Idx < Data.size() && Data[Idx]->hasRHSComponent(OB);
1138 } 1291 }
1139 bool hasArraySlow(OutputStream &S) const override { 1292 bool hasArraySlow(OutputBuffer &OB) const override {
1140 initializePackExpansion(S); 1293 initializePackExpansion(OB);
1141 size_t Idx = S.CurrentPackIndex; 1294 size_t Idx = OB.CurrentPackIndex;
1142 return Idx < Data.size() && Data[Idx]->hasArray(S); 1295 return Idx < Data.size() && Data[Idx]->hasArray(OB);
1143 } 1296 }
1144 bool hasFunctionSlow(OutputStream &S) const override { 1297 bool hasFunctionSlow(OutputBuffer &OB) const override {
1145 initializePackExpansion(S); 1298 initializePackExpansion(OB);
1146 size_t Idx = S.CurrentPackIndex; 1299 size_t Idx = OB.CurrentPackIndex;
1147 return Idx < Data.size() && Data[Idx]->hasFunction(S); 1300 return Idx < Data.size() && Data[Idx]->hasFunction(OB);
1148 } 1301 }
1149 const Node *getSyntaxNode(OutputStream &S) const override { 1302 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1150 initializePackExpansion(S); 1303 initializePackExpansion(OB);
1151 size_t Idx = S.CurrentPackIndex; 1304 size_t Idx = OB.CurrentPackIndex;
1152 return Idx < Data.size() ? Data[Idx]->getSyntaxNode(S) : this; 1305 return Idx < Data.size() ? Data[Idx]->getSyntaxNode(OB) : this;
1153 } 1306 }
1154 1307
1155 void printLeft(OutputStream &S) const override { 1308 void printLeft(OutputBuffer &OB) const override {
1156 initializePackExpansion(S); 1309 initializePackExpansion(OB);
1157 size_t Idx = S.CurrentPackIndex; 1310 size_t Idx = OB.CurrentPackIndex;
1158 if (Idx < Data.size()) 1311 if (Idx < Data.size())
1159 Data[Idx]->printLeft(S); 1312 Data[Idx]->printLeft(OB);
1160 } 1313 }
1161 void printRight(OutputStream &S) const override { 1314 void printRight(OutputBuffer &OB) const override {
1162 initializePackExpansion(S); 1315 initializePackExpansion(OB);
1163 size_t Idx = S.CurrentPackIndex; 1316 size_t Idx = OB.CurrentPackIndex;
1164 if (Idx < Data.size()) 1317 if (Idx < Data.size())
1165 Data[Idx]->printRight(S); 1318 Data[Idx]->printRight(OB);
1166 } 1319 }
1167}; 1320};
1168 1321
@@ -1181,8 +1334,8 @@ public:
1181 1334
1182 NodeArray getElements() const { return Elements; } 1335 NodeArray getElements() const { return Elements; }
1183 1336
1184 void printLeft(OutputStream &S) const override { 1337 void printLeft(OutputBuffer &OB) const override {
1185 Elements.printWithComma(S); 1338 Elements.printWithComma(OB);
1186 } 1339 }
1187}; 1340};
1188 1341
@@ -1199,35 +1352,35 @@ public:
1199 1352
1200 const Node *getChild() const { return Child; } 1353 const Node *getChild() const { return Child; }
1201 1354
1202 void printLeft(OutputStream &S) const override { 1355 void printLeft(OutputBuffer &OB) const override {
1203 constexpr unsigned Max = std::numeric_limits<unsigned>::max(); 1356 constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1204 SwapAndRestore<unsigned> SavePackIdx(S.CurrentPackIndex, Max); 1357 ScopedOverride<unsigned> SavePackIdx(OB.CurrentPackIndex, Max);
1205 SwapAndRestore<unsigned> SavePackMax(S.CurrentPackMax, Max); 1358 ScopedOverride<unsigned> SavePackMax(OB.CurrentPackMax, Max);
1206 size_t StreamPos = S.getCurrentPosition(); 1359 size_t StreamPos = OB.getCurrentPosition();
1207 1360
1208 // Print the first element in the pack. If Child contains a ParameterPack, 1361 // Print the first element in the pack. If Child contains a ParameterPack,
1209 // it will set up S.CurrentPackMax and print the first element. 1362 // it will set up S.CurrentPackMax and print the first element.
1210 Child->print(S); 1363 Child->print(OB);
1211 1364
1212 // No ParameterPack was found in Child. This can occur if we've found a pack 1365 // No ParameterPack was found in Child. This can occur if we've found a pack
1213 // expansion on a <function-param>. 1366 // expansion on a <function-param>.
1214 if (S.CurrentPackMax == Max) { 1367 if (OB.CurrentPackMax == Max) {
1215 S += "..."; 1368 OB += "...";
1216 return; 1369 return;
1217 } 1370 }
1218 1371
1219 // We found a ParameterPack, but it has no elements. Erase whatever we may 1372 // We found a ParameterPack, but it has no elements. Erase whatever we may
1220 // of printed. 1373 // of printed.
1221 if (S.CurrentPackMax == 0) { 1374 if (OB.CurrentPackMax == 0) {
1222 S.setCurrentPosition(StreamPos); 1375 OB.setCurrentPosition(StreamPos);
1223 return; 1376 return;
1224 } 1377 }
1225 1378
1226 // Else, iterate through the rest of the elements in the pack. 1379 // Else, iterate through the rest of the elements in the pack.
1227 for (unsigned I = 1, E = S.CurrentPackMax; I < E; ++I) { 1380 for (unsigned I = 1, E = OB.CurrentPackMax; I < E; ++I) {
1228 S += ", "; 1381 OB += ", ";
1229 S.CurrentPackIndex = I; 1382 OB.CurrentPackIndex = I;
1230 Child->print(S); 1383 Child->print(OB);
1231 } 1384 }
1232 } 1385 }
1233}; 1386};
@@ -1242,12 +1395,11 @@ public:
1242 1395
1243 NodeArray getParams() { return Params; } 1396 NodeArray getParams() { return Params; }
1244 1397
1245 void printLeft(OutputStream &S) const override { 1398 void printLeft(OutputBuffer &OB) const override {
1246 S += "<"; 1399 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1247 Params.printWithComma(S); 1400 OB += "<";
1248 if (S.back() == '>') 1401 Params.printWithComma(OB);
1249 S += " "; 1402 OB += ">";
1250 S += ">";
1251 } 1403 }
1252}; 1404};
1253 1405
@@ -1289,42 +1441,42 @@ struct ForwardTemplateReference : Node {
1289 // special handling. 1441 // special handling.
1290 template<typename Fn> void match(Fn F) const = delete; 1442 template<typename Fn> void match(Fn F) const = delete;
1291 1443
1292 bool hasRHSComponentSlow(OutputStream &S) const override { 1444 bool hasRHSComponentSlow(OutputBuffer &OB) const override {
1293 if (Printing) 1445 if (Printing)
1294 return false; 1446 return false;
1295 SwapAndRestore<bool> SavePrinting(Printing, true); 1447 ScopedOverride<bool> SavePrinting(Printing, true);
1296 return Ref->hasRHSComponent(S); 1448 return Ref->hasRHSComponent(OB);
1297 } 1449 }
1298 bool hasArraySlow(OutputStream &S) const override { 1450 bool hasArraySlow(OutputBuffer &OB) const override {
1299 if (Printing) 1451 if (Printing)
1300 return false; 1452 return false;
1301 SwapAndRestore<bool> SavePrinting(Printing, true); 1453 ScopedOverride<bool> SavePrinting(Printing, true);
1302 return Ref->hasArray(S); 1454 return Ref->hasArray(OB);
1303 } 1455 }
1304 bool hasFunctionSlow(OutputStream &S) const override { 1456 bool hasFunctionSlow(OutputBuffer &OB) const override {
1305 if (Printing) 1457 if (Printing)
1306 return false; 1458 return false;
1307 SwapAndRestore<bool> SavePrinting(Printing, true); 1459 ScopedOverride<bool> SavePrinting(Printing, true);
1308 return Ref->hasFunction(S); 1460 return Ref->hasFunction(OB);
1309 } 1461 }
1310 const Node *getSyntaxNode(OutputStream &S) const override { 1462 const Node *getSyntaxNode(OutputBuffer &OB) const override {
1311 if (Printing) 1463 if (Printing)
1312 return this; 1464 return this;
1313 SwapAndRestore<bool> SavePrinting(Printing, true); 1465 ScopedOverride<bool> SavePrinting(Printing, true);
1314 return Ref->getSyntaxNode(S); 1466 return Ref->getSyntaxNode(OB);
1315 } 1467 }
1316 1468
1317 void printLeft(OutputStream &S) const override { 1469 void printLeft(OutputBuffer &OB) const override {
1318 if (Printing) 1470 if (Printing)
1319 return; 1471 return;
1320 SwapAndRestore<bool> SavePrinting(Printing, true); 1472 ScopedOverride<bool> SavePrinting(Printing, true);
1321 Ref->printLeft(S); 1473 Ref->printLeft(OB);
1322 } 1474 }
1323 void printRight(OutputStream &S) const override { 1475 void printRight(OutputBuffer &OB) const override {
1324 if (Printing) 1476 if (Printing)
1325 return; 1477 return;
1326 SwapAndRestore<bool> SavePrinting(Printing, true); 1478 ScopedOverride<bool> SavePrinting(Printing, true);
1327 Ref->printRight(S); 1479 Ref->printRight(OB);
1328 } 1480 }
1329}; 1481};
1330 1482
@@ -1338,11 +1490,11 @@ struct NameWithTemplateArgs : Node {
1338 1490
1339 template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); } 1491 template<typename Fn> void match(Fn F) const { F(Name, TemplateArgs); }
1340 1492
1341 StringView getBaseName() const override { return Name->getBaseName(); } 1493 std::string_view getBaseName() const override { return Name->getBaseName(); }
1342 1494
1343 void printLeft(OutputStream &S) const override { 1495 void printLeft(OutputBuffer &OB) const override {
1344 Name->print(S); 1496 Name->print(OB);
1345 TemplateArgs->print(S); 1497 TemplateArgs->print(OB);
1346 } 1498 }
1347}; 1499};
1348 1500
@@ -1355,26 +1507,11 @@ public:
1355 1507
1356 template<typename Fn> void match(Fn F) const { F(Child); } 1508 template<typename Fn> void match(Fn F) const { F(Child); }
1357 1509
1358 StringView getBaseName() const override { return Child->getBaseName(); } 1510 std::string_view getBaseName() const override { return Child->getBaseName(); }
1359 1511
1360 void printLeft(OutputStream &S) const override { 1512 void printLeft(OutputBuffer &OB) const override {
1361 S += "::"; 1513 OB += "::";
1362 Child->print(S); 1514 Child->print(OB);
1363 }
1364};
1365
1366struct StdQualifiedName : Node {
1367 Node *Child;
1368
1369 StdQualifiedName(Node *Child_) : Node(KStdQualifiedName), Child(Child_) {}
1370
1371 template<typename Fn> void match(Fn F) const { F(Child); }
1372
1373 StringView getBaseName() const override { return Child->getBaseName(); }
1374
1375 void printLeft(OutputStream &S) const override {
1376 S += "std::";
1377 Child->print(S);
1378 } 1515 }
1379}; 1516};
1380 1517
@@ -1387,109 +1524,81 @@ enum class SpecialSubKind {
1387 iostream, 1524 iostream,
1388}; 1525};
1389 1526
1390class ExpandedSpecialSubstitution final : public Node { 1527class SpecialSubstitution;
1528class ExpandedSpecialSubstitution : public Node {
1529protected:
1391 SpecialSubKind SSK; 1530 SpecialSubKind SSK;
1392 1531
1532 ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
1533 : Node(K_), SSK(SSK_) {}
1393public: 1534public:
1394 ExpandedSpecialSubstitution(SpecialSubKind SSK_) 1535 ExpandedSpecialSubstitution(SpecialSubKind SSK_)
1395 : Node(KExpandedSpecialSubstitution), SSK(SSK_) {} 1536 : ExpandedSpecialSubstitution(SSK_, KExpandedSpecialSubstitution) {}
1537 inline ExpandedSpecialSubstitution(SpecialSubstitution const *);
1396 1538
1397 template<typename Fn> void match(Fn F) const { F(SSK); } 1539 template<typename Fn> void match(Fn F) const { F(SSK); }
1398 1540
1399 StringView getBaseName() const override { 1541protected:
1542 bool isInstantiation() const {
1543 return unsigned(SSK) >= unsigned(SpecialSubKind::string);
1544 }
1545
1546 std::string_view getBaseName() const override {
1400 switch (SSK) { 1547 switch (SSK) {
1401 case SpecialSubKind::allocator: 1548 case SpecialSubKind::allocator:
1402 return StringView("allocator"); 1549 return {"allocator"};
1403 case SpecialSubKind::basic_string: 1550 case SpecialSubKind::basic_string:
1404 return StringView("basic_string"); 1551 return {"basic_string"};
1405 case SpecialSubKind::string: 1552 case SpecialSubKind::string:
1406 return StringView("basic_string"); 1553 return {"basic_string"};
1407 case SpecialSubKind::istream: 1554 case SpecialSubKind::istream:
1408 return StringView("basic_istream"); 1555 return {"basic_istream"};
1409 case SpecialSubKind::ostream: 1556 case SpecialSubKind::ostream:
1410 return StringView("basic_ostream"); 1557 return {"basic_ostream"};
1411 case SpecialSubKind::iostream: 1558 case SpecialSubKind::iostream:
1412 return StringView("basic_iostream"); 1559 return {"basic_iostream"};
1413 } 1560 }
1414 DEMANGLE_UNREACHABLE; 1561 DEMANGLE_UNREACHABLE;
1415 } 1562 }
1416 1563
1417 void printLeft(OutputStream &S) const override { 1564private:
1418 switch (SSK) { 1565 void printLeft(OutputBuffer &OB) const override {
1419 case SpecialSubKind::allocator: 1566 OB << "std::" << getBaseName();
1420 S += "std::allocator"; 1567 if (isInstantiation()) {
1421 break; 1568 OB << "<char, std::char_traits<char>";
1422 case SpecialSubKind::basic_string: 1569 if (SSK == SpecialSubKind::string)
1423 S += "std::basic_string"; 1570 OB << ", std::allocator<char>";
1424 break; 1571 OB << ">";
1425 case SpecialSubKind::string:
1426 S += "std::basic_string<char, std::char_traits<char>, "
1427 "std::allocator<char> >";
1428 break;
1429 case SpecialSubKind::istream:
1430 S += "std::basic_istream<char, std::char_traits<char> >";
1431 break;
1432 case SpecialSubKind::ostream:
1433 S += "std::basic_ostream<char, std::char_traits<char> >";
1434 break;
1435 case SpecialSubKind::iostream:
1436 S += "std::basic_iostream<char, std::char_traits<char> >";
1437 break;
1438 } 1572 }
1439 } 1573 }
1440}; 1574};
1441 1575
1442class SpecialSubstitution final : public Node { 1576class SpecialSubstitution final : public ExpandedSpecialSubstitution {
1443public: 1577public:
1444 SpecialSubKind SSK;
1445
1446 SpecialSubstitution(SpecialSubKind SSK_) 1578 SpecialSubstitution(SpecialSubKind SSK_)
1447 : Node(KSpecialSubstitution), SSK(SSK_) {} 1579 : ExpandedSpecialSubstitution(SSK_, KSpecialSubstitution) {}
1448 1580
1449 template<typename Fn> void match(Fn F) const { F(SSK); } 1581 template<typename Fn> void match(Fn F) const { F(SSK); }
1450 1582
1451 StringView getBaseName() const override { 1583 std::string_view getBaseName() const override {
1452 switch (SSK) { 1584 std::string_view SV = ExpandedSpecialSubstitution::getBaseName();
1453 case SpecialSubKind::allocator: 1585 if (isInstantiation()) {
1454 return StringView("allocator"); 1586 // The instantiations are typedefs that drop the "basic_" prefix.
1455 case SpecialSubKind::basic_string: 1587 assert(llvm::itanium_demangle::starts_with(SV, "basic_"));
1456 return StringView("basic_string"); 1588 SV.remove_prefix(sizeof("basic_") - 1);
1457 case SpecialSubKind::string:
1458 return StringView("string");
1459 case SpecialSubKind::istream:
1460 return StringView("istream");
1461 case SpecialSubKind::ostream:
1462 return StringView("ostream");
1463 case SpecialSubKind::iostream:
1464 return StringView("iostream");
1465 } 1589 }
1466 DEMANGLE_UNREACHABLE; 1590 return SV;
1467 } 1591 }
1468 1592
1469 void printLeft(OutputStream &S) const override { 1593 void printLeft(OutputBuffer &OB) const override {
1470 switch (SSK) { 1594 OB << "std::" << getBaseName();
1471 case SpecialSubKind::allocator:
1472 S += "std::allocator";
1473 break;
1474 case SpecialSubKind::basic_string:
1475 S += "std::basic_string";
1476 break;
1477 case SpecialSubKind::string:
1478 S += "std::string";
1479 break;
1480 case SpecialSubKind::istream:
1481 S += "std::istream";
1482 break;
1483 case SpecialSubKind::ostream:
1484 S += "std::ostream";
1485 break;
1486 case SpecialSubKind::iostream:
1487 S += "std::iostream";
1488 break;
1489 }
1490 } 1595 }
1491}; 1596};
1492 1597
1598inline ExpandedSpecialSubstitution::ExpandedSpecialSubstitution(
1599 SpecialSubstitution const *SS)
1600 : ExpandedSpecialSubstitution(SS->SSK) {}
1601
1493class CtorDtorName final : public Node { 1602class CtorDtorName final : public Node {
1494 const Node *Basename; 1603 const Node *Basename;
1495 const bool IsDtor; 1604 const bool IsDtor;
@@ -1502,10 +1611,10 @@ public:
1502 1611
1503 template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); } 1612 template<typename Fn> void match(Fn F) const { F(Basename, IsDtor, Variant); }
1504 1613
1505 void printLeft(OutputStream &S) const override { 1614 void printLeft(OutputBuffer &OB) const override {
1506 if (IsDtor) 1615 if (IsDtor)
1507 S += "~"; 1616 OB += "~";
1508 S += Basename->getBaseName(); 1617 OB += Basename->getBaseName();
1509 } 1618 }
1510}; 1619};
1511 1620
@@ -1517,35 +1626,36 @@ public:
1517 1626
1518 template<typename Fn> void match(Fn F) const { F(Base); } 1627 template<typename Fn> void match(Fn F) const { F(Base); }
1519 1628
1520 void printLeft(OutputStream &S) const override { 1629 void printLeft(OutputBuffer &OB) const override {
1521 S += "~"; 1630 OB += "~";
1522 Base->printLeft(S); 1631 Base->printLeft(OB);
1523 } 1632 }
1524}; 1633};
1525 1634
1526class UnnamedTypeName : public Node { 1635class UnnamedTypeName : public Node {
1527 const StringView Count; 1636 const std::string_view Count;
1528 1637
1529public: 1638public:
1530 UnnamedTypeName(StringView Count_) : Node(KUnnamedTypeName), Count(Count_) {} 1639 UnnamedTypeName(std::string_view Count_)
1640 : Node(KUnnamedTypeName), Count(Count_) {}
1531 1641
1532 template<typename Fn> void match(Fn F) const { F(Count); } 1642 template<typename Fn> void match(Fn F) const { F(Count); }
1533 1643
1534 void printLeft(OutputStream &S) const override { 1644 void printLeft(OutputBuffer &OB) const override {
1535 S += "'unnamed"; 1645 OB += "'unnamed";
1536 S += Count; 1646 OB += Count;
1537 S += "\'"; 1647 OB += "\'";
1538 } 1648 }
1539}; 1649};
1540 1650
1541class ClosureTypeName : public Node { 1651class ClosureTypeName : public Node {
1542 NodeArray TemplateParams; 1652 NodeArray TemplateParams;
1543 NodeArray Params; 1653 NodeArray Params;
1544 StringView Count; 1654 std::string_view Count;
1545 1655
1546public: 1656public:
1547 ClosureTypeName(NodeArray TemplateParams_, NodeArray Params_, 1657 ClosureTypeName(NodeArray TemplateParams_, NodeArray Params_,
1548 StringView Count_) 1658 std::string_view Count_)
1549 : Node(KClosureTypeName), TemplateParams(TemplateParams_), 1659 : Node(KClosureTypeName), TemplateParams(TemplateParams_),
1550 Params(Params_), Count(Count_) {} 1660 Params(Params_), Count(Count_) {}
1551 1661
@@ -1553,22 +1663,23 @@ public:
1553 F(TemplateParams, Params, Count); 1663 F(TemplateParams, Params, Count);
1554 } 1664 }
1555 1665
1556 void printDeclarator(OutputStream &S) const { 1666 void printDeclarator(OutputBuffer &OB) const {
1557 if (!TemplateParams.empty()) { 1667 if (!TemplateParams.empty()) {
1558 S += "<"; 1668 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1559 TemplateParams.printWithComma(S); 1669 OB += "<";
1560 S += ">"; 1670 TemplateParams.printWithComma(OB);
1671 OB += ">";
1561 } 1672 }
1562 S += "("; 1673 OB.printOpen();
1563 Params.printWithComma(S); 1674 Params.printWithComma(OB);
1564 S += ")"; 1675 OB.printClose();
1565 } 1676 }
1566 1677
1567 void printLeft(OutputStream &S) const override { 1678 void printLeft(OutputBuffer &OB) const override {
1568 S += "\'lambda"; 1679 OB += "\'lambda";
1569 S += Count; 1680 OB += Count;
1570 S += "\'"; 1681 OB += "\'";
1571 printDeclarator(S); 1682 printDeclarator(OB);
1572 } 1683 }
1573}; 1684};
1574 1685
@@ -1580,10 +1691,10 @@ public:
1580 1691
1581 template<typename Fn> void match(Fn F) const { F(Bindings); } 1692 template<typename Fn> void match(Fn F) const { F(Bindings); }
1582 1693
1583 void printLeft(OutputStream &S) const override { 1694 void printLeft(OutputBuffer &OB) const override {
1584 S += '['; 1695 OB.printOpen('[');
1585 Bindings.printWithComma(S); 1696 Bindings.printWithComma(OB);
1586 S += ']'; 1697 OB.printClose(']');
1587 } 1698 }
1588}; 1699};
1589 1700
@@ -1591,32 +1702,35 @@ public:
1591 1702
1592class BinaryExpr : public Node { 1703class BinaryExpr : public Node {
1593 const Node *LHS; 1704 const Node *LHS;
1594 const StringView InfixOperator; 1705 const std::string_view InfixOperator;
1595 const Node *RHS; 1706 const Node *RHS;
1596 1707
1597public: 1708public:
1598 BinaryExpr(const Node *LHS_, StringView InfixOperator_, const Node *RHS_) 1709 BinaryExpr(const Node *LHS_, std::string_view InfixOperator_,
1599 : Node(KBinaryExpr), LHS(LHS_), InfixOperator(InfixOperator_), RHS(RHS_) { 1710 const Node *RHS_, Prec Prec_)
1600 } 1711 : Node(KBinaryExpr, Prec_), LHS(LHS_), InfixOperator(InfixOperator_),
1601 1712 RHS(RHS_) {}
1602 template<typename Fn> void match(Fn F) const { F(LHS, InfixOperator, RHS); } 1713
1603 1714 template <typename Fn> void match(Fn F) const {
1604 void printLeft(OutputStream &S) const override { 1715 F(LHS, InfixOperator, RHS, getPrecedence());
1605 // might be a template argument expression, then we need to disambiguate 1716 }
1606 // with parens. 1717
1607 if (InfixOperator == ">") 1718 void printLeft(OutputBuffer &OB) const override {
1608 S += "("; 1719 bool ParenAll = OB.isGtInsideTemplateArgs() &&
1609 1720 (InfixOperator == ">" || InfixOperator == ">>");
1610 S += "("; 1721 if (ParenAll)
1611 LHS->print(S); 1722 OB.printOpen();
1612 S += ") "; 1723 // Assignment is right associative, with special LHS precedence.
1613 S += InfixOperator; 1724 bool IsAssign = getPrecedence() == Prec::Assign;
1614 S += " ("; 1725 LHS->printAsOperand(OB, IsAssign ? Prec::OrIf : getPrecedence(), !IsAssign);
1615 RHS->print(S); 1726 // No space before comma operator
1616 S += ")"; 1727 if (!(InfixOperator == ","))
1617 1728 OB += " ";
1618 if (InfixOperator == ">") 1729 OB += InfixOperator;
1619 S += ")"; 1730 OB += " ";
1731 RHS->printAsOperand(OB, getPrecedence(), IsAssign);
1732 if (ParenAll)
1733 OB.printClose();
1620 } 1734 }
1621}; 1735};
1622 1736
@@ -1625,35 +1739,36 @@ class ArraySubscriptExpr : public Node {
1625 const Node *Op2; 1739 const Node *Op2;
1626 1740
1627public: 1741public:
1628 ArraySubscriptExpr(const Node *Op1_, const Node *Op2_) 1742 ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_)
1629 : Node(KArraySubscriptExpr), Op1(Op1_), Op2(Op2_) {} 1743 : Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {}
1630 1744
1631 template<typename Fn> void match(Fn F) const { F(Op1, Op2); } 1745 template <typename Fn> void match(Fn F) const {
1746 F(Op1, Op2, getPrecedence());
1747 }
1632 1748
1633 void printLeft(OutputStream &S) const override { 1749 void printLeft(OutputBuffer &OB) const override {
1634 S += "("; 1750 Op1->printAsOperand(OB, getPrecedence());
1635 Op1->print(S); 1751 OB.printOpen('[');
1636 S += ")["; 1752 Op2->printAsOperand(OB);
1637 Op2->print(S); 1753 OB.printClose(']');
1638 S += "]";
1639 } 1754 }
1640}; 1755};
1641 1756
1642class PostfixExpr : public Node { 1757class PostfixExpr : public Node {
1643 const Node *Child; 1758 const Node *Child;
1644 const StringView Operator; 1759 const std::string_view Operator;
1645 1760
1646public: 1761public:
1647 PostfixExpr(const Node *Child_, StringView Operator_) 1762 PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
1648 : Node(KPostfixExpr), Child(Child_), Operator(Operator_) {} 1763 : Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
1649 1764
1650 template<typename Fn> void match(Fn F) const { F(Child, Operator); } 1765 template <typename Fn> void match(Fn F) const {
1766 F(Child, Operator, getPrecedence());
1767 }
1651 1768
1652 void printLeft(OutputStream &S) const override { 1769 void printLeft(OutputBuffer &OB) const override {
1653 S += "("; 1770 Child->printAsOperand(OB, getPrecedence(), true);
1654 Child->print(S); 1771 OB += Operator;
1655 S += ")";
1656 S += Operator;
1657 } 1772 }
1658}; 1773};
1659 1774
@@ -1663,78 +1778,128 @@ class ConditionalExpr : public Node {
1663 const Node *Else; 1778 const Node *Else;
1664 1779
1665public: 1780public:
1666 ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_) 1781 ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_,
1667 : Node(KConditionalExpr), Cond(Cond_), Then(Then_), Else(Else_) {} 1782 Prec Prec_)
1783 : Node(KConditionalExpr, Prec_), Cond(Cond_), Then(Then_), Else(Else_) {}
1668 1784
1669 template<typename Fn> void match(Fn F) const { F(Cond, Then, Else); } 1785 template <typename Fn> void match(Fn F) const {
1786 F(Cond, Then, Else, getPrecedence());
1787 }
1670 1788
1671 void printLeft(OutputStream &S) const override { 1789 void printLeft(OutputBuffer &OB) const override {
1672 S += "("; 1790 Cond->printAsOperand(OB, getPrecedence());
1673 Cond->print(S); 1791 OB += " ? ";
1674 S += ") ? ("; 1792 Then->printAsOperand(OB);
1675 Then->print(S); 1793 OB += " : ";
1676 S += ") : ("; 1794 Else->printAsOperand(OB, Prec::Assign, true);
1677 Else->print(S);
1678 S += ")";
1679 } 1795 }
1680}; 1796};
1681 1797
1682class MemberExpr : public Node { 1798class MemberExpr : public Node {
1683 const Node *LHS; 1799 const Node *LHS;
1684 const StringView Kind; 1800 const std::string_view Kind;
1685 const Node *RHS; 1801 const Node *RHS;
1686 1802
1687public: 1803public:
1688 MemberExpr(const Node *LHS_, StringView Kind_, const Node *RHS_) 1804 MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_,
1689 : Node(KMemberExpr), LHS(LHS_), Kind(Kind_), RHS(RHS_) {} 1805 Prec Prec_)
1806 : Node(KMemberExpr, Prec_), LHS(LHS_), Kind(Kind_), RHS(RHS_) {}
1807
1808 template <typename Fn> void match(Fn F) const {
1809 F(LHS, Kind, RHS, getPrecedence());
1810 }
1811
1812 void printLeft(OutputBuffer &OB) const override {
1813 LHS->printAsOperand(OB, getPrecedence(), true);
1814 OB += Kind;
1815 RHS->printAsOperand(OB, getPrecedence(), false);
1816 }
1817};
1818
1819class SubobjectExpr : public Node {
1820 const Node *Type;
1821 const Node *SubExpr;
1822 std::string_view Offset;
1823 NodeArray UnionSelectors;
1824 bool OnePastTheEnd;
1690 1825
1691 template<typename Fn> void match(Fn F) const { F(LHS, Kind, RHS); } 1826public:
1827 SubobjectExpr(const Node *Type_, const Node *SubExpr_,
1828 std::string_view Offset_, NodeArray UnionSelectors_,
1829 bool OnePastTheEnd_)
1830 : Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
1831 UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
1692 1832
1693 void printLeft(OutputStream &S) const override { 1833 template<typename Fn> void match(Fn F) const {
1694 LHS->print(S); 1834 F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
1695 S += Kind; 1835 }
1696 RHS->print(S); 1836
1837 void printLeft(OutputBuffer &OB) const override {
1838 SubExpr->print(OB);
1839 OB += ".<";
1840 Type->print(OB);
1841 OB += " at offset ";
1842 if (Offset.empty()) {
1843 OB += "0";
1844 } else if (Offset[0] == 'n') {
1845 OB += "-";
1846 OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
1847 } else {
1848 OB += Offset;
1849 }
1850 OB += ">";
1697 } 1851 }
1698}; 1852};
1699 1853
1700class EnclosingExpr : public Node { 1854class EnclosingExpr : public Node {
1701 const StringView Prefix; 1855 const std::string_view Prefix;
1702 const Node *Infix; 1856 const Node *Infix;
1703 const StringView Postfix; 1857 const std::string_view Postfix;
1704 1858
1705public: 1859public:
1706 EnclosingExpr(StringView Prefix_, Node *Infix_, StringView Postfix_) 1860 EnclosingExpr(std::string_view Prefix_, const Node *Infix_,
1707 : Node(KEnclosingExpr), Prefix(Prefix_), Infix(Infix_), 1861 Prec Prec_ = Prec::Primary)
1708 Postfix(Postfix_) {} 1862 : Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
1709 1863
1710 template<typename Fn> void match(Fn F) const { F(Prefix, Infix, Postfix); } 1864 template <typename Fn> void match(Fn F) const {
1865 F(Prefix, Infix, getPrecedence());
1866 }
1711 1867
1712 void printLeft(OutputStream &S) const override { 1868 void printLeft(OutputBuffer &OB) const override {
1713 S += Prefix; 1869 OB += Prefix;
1714 Infix->print(S); 1870 OB.printOpen();
1715 S += Postfix; 1871 Infix->print(OB);
1872 OB.printClose();
1873 OB += Postfix;
1716 } 1874 }
1717}; 1875};
1718 1876
1719class CastExpr : public Node { 1877class CastExpr : public Node {
1720 // cast_kind<to>(from) 1878 // cast_kind<to>(from)
1721 const StringView CastKind; 1879 const std::string_view CastKind;
1722 const Node *To; 1880 const Node *To;
1723 const Node *From; 1881 const Node *From;
1724 1882
1725public: 1883public:
1726 CastExpr(StringView CastKind_, const Node *To_, const Node *From_) 1884 CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_,
1727 : Node(KCastExpr), CastKind(CastKind_), To(To_), From(From_) {} 1885 Prec Prec_)
1886 : Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_), From(From_) {}
1728 1887
1729 template<typename Fn> void match(Fn F) const { F(CastKind, To, From); } 1888 template <typename Fn> void match(Fn F) const {
1889 F(CastKind, To, From, getPrecedence());
1890 }
1730 1891
1731 void printLeft(OutputStream &S) const override { 1892 void printLeft(OutputBuffer &OB) const override {
1732 S += CastKind; 1893 OB += CastKind;
1733 S += "<"; 1894 {
1734 To->printLeft(S); 1895 ScopedOverride<unsigned> LT(OB.GtIsGt, 0);
1735 S += ">("; 1896 OB += "<";
1736 From->printLeft(S); 1897 To->printLeft(OB);
1737 S += ")"; 1898 OB += ">";
1899 }
1900 OB.printOpen();
1901 From->printAsOperand(OB);
1902 OB.printClose();
1738 } 1903 }
1739}; 1904};
1740 1905
@@ -1747,11 +1912,12 @@ public:
1747 1912
1748 template<typename Fn> void match(Fn F) const { F(Pack); } 1913 template<typename Fn> void match(Fn F) const { F(Pack); }
1749 1914
1750 void printLeft(OutputStream &S) const override { 1915 void printLeft(OutputBuffer &OB) const override {
1751 S += "sizeof...("; 1916 OB += "sizeof...";
1917 OB.printOpen();
1752 ParameterPackExpansion PPE(Pack); 1918 ParameterPackExpansion PPE(Pack);
1753 PPE.printLeft(S); 1919 PPE.printLeft(OB);
1754 S += ")"; 1920 OB.printClose();
1755 } 1921 }
1756}; 1922};
1757 1923
@@ -1760,16 +1926,18 @@ class CallExpr : public Node {
1760 NodeArray Args; 1926 NodeArray Args;
1761 1927
1762public: 1928public:
1763 CallExpr(const Node *Callee_, NodeArray Args_) 1929 CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_)
1764 : Node(KCallExpr), Callee(Callee_), Args(Args_) {} 1930 : Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {}
1765 1931
1766 template<typename Fn> void match(Fn F) const { F(Callee, Args); } 1932 template <typename Fn> void match(Fn F) const {
1933 F(Callee, Args, getPrecedence());
1934 }
1767 1935
1768 void printLeft(OutputStream &S) const override { 1936 void printLeft(OutputBuffer &OB) const override {
1769 Callee->print(S); 1937 Callee->print(OB);
1770 S += "("; 1938 OB.printOpen();
1771 Args.printWithComma(S); 1939 Args.printWithComma(OB);
1772 S += ")"; 1940 OB.printClose();
1773 } 1941 }
1774}; 1942};
1775 1943
@@ -1782,33 +1950,32 @@ class NewExpr : public Node {
1782 bool IsArray; // new[] ? 1950 bool IsArray; // new[] ?
1783public: 1951public:
1784 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_, 1952 NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_,
1785 bool IsArray_) 1953 bool IsArray_, Prec Prec_)
1786 : Node(KNewExpr), ExprList(ExprList_), Type(Type_), InitList(InitList_), 1954 : Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_),
1787 IsGlobal(IsGlobal_), IsArray(IsArray_) {} 1955 InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
1788 1956
1789 template<typename Fn> void match(Fn F) const { 1957 template<typename Fn> void match(Fn F) const {
1790 F(ExprList, Type, InitList, IsGlobal, IsArray); 1958 F(ExprList, Type, InitList, IsGlobal, IsArray, getPrecedence());
1791 } 1959 }
1792 1960
1793 void printLeft(OutputStream &S) const override { 1961 void printLeft(OutputBuffer &OB) const override {
1794 if (IsGlobal) 1962 if (IsGlobal)
1795 S += "::operator "; 1963 OB += "::";
1796 S += "new"; 1964 OB += "new";
1797 if (IsArray) 1965 if (IsArray)
1798 S += "[]"; 1966 OB += "[]";
1799 S += ' ';
1800 if (!ExprList.empty()) { 1967 if (!ExprList.empty()) {
1801 S += "("; 1968 OB.printOpen();
1802 ExprList.printWithComma(S); 1969 ExprList.printWithComma(OB);
1803 S += ")"; 1970 OB.printClose();
1804 } 1971 }
1805 Type->print(S); 1972 OB += " ";
1973 Type->print(OB);
1806 if (!InitList.empty()) { 1974 if (!InitList.empty()) {
1807 S += "("; 1975 OB.printOpen();
1808 InitList.printWithComma(S); 1976 InitList.printWithComma(OB);
1809 S += ")"; 1977 OB.printClose();
1810 } 1978 }
1811
1812 } 1979 }
1813}; 1980};
1814 1981
@@ -1818,50 +1985,55 @@ class DeleteExpr : public Node {
1818 bool IsArray; 1985 bool IsArray;
1819 1986
1820public: 1987public:
1821 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_) 1988 DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_)
1822 : Node(KDeleteExpr), Op(Op_), IsGlobal(IsGlobal_), IsArray(IsArray_) {} 1989 : Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_),
1990 IsArray(IsArray_) {}
1823 1991
1824 template<typename Fn> void match(Fn F) const { F(Op, IsGlobal, IsArray); } 1992 template <typename Fn> void match(Fn F) const {
1993 F(Op, IsGlobal, IsArray, getPrecedence());
1994 }
1825 1995
1826 void printLeft(OutputStream &S) const override { 1996 void printLeft(OutputBuffer &OB) const override {
1827 if (IsGlobal) 1997 if (IsGlobal)
1828 S += "::"; 1998 OB += "::";
1829 S += "delete"; 1999 OB += "delete";
1830 if (IsArray) 2000 if (IsArray)
1831 S += "[] "; 2001 OB += "[]";
1832 Op->print(S); 2002 OB += ' ';
2003 Op->print(OB);
1833 } 2004 }
1834}; 2005};
1835 2006
1836class PrefixExpr : public Node { 2007class PrefixExpr : public Node {
1837 StringView Prefix; 2008 std::string_view Prefix;
1838 Node *Child; 2009 Node *Child;
1839 2010
1840public: 2011public:
1841 PrefixExpr(StringView Prefix_, Node *Child_) 2012 PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
1842 : Node(KPrefixExpr), Prefix(Prefix_), Child(Child_) {} 2013 : Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
1843 2014
1844 template<typename Fn> void match(Fn F) const { F(Prefix, Child); } 2015 template <typename Fn> void match(Fn F) const {
2016 F(Prefix, Child, getPrecedence());
2017 }
1845 2018
1846 void printLeft(OutputStream &S) const override { 2019 void printLeft(OutputBuffer &OB) const override {
1847 S += Prefix; 2020 OB += Prefix;
1848 S += "("; 2021 Child->printAsOperand(OB, getPrecedence());
1849 Child->print(S);
1850 S += ")";
1851 } 2022 }
1852}; 2023};
1853 2024
1854class FunctionParam : public Node { 2025class FunctionParam : public Node {
1855 StringView Number; 2026 std::string_view Number;
1856 2027
1857public: 2028public:
1858 FunctionParam(StringView Number_) : Node(KFunctionParam), Number(Number_) {} 2029 FunctionParam(std::string_view Number_)
2030 : Node(KFunctionParam), Number(Number_) {}
1859 2031
1860 template<typename Fn> void match(Fn F) const { F(Number); } 2032 template<typename Fn> void match(Fn F) const { F(Number); }
1861 2033
1862 void printLeft(OutputStream &S) const override { 2034 void printLeft(OutputBuffer &OB) const override {
1863 S += "fp"; 2035 OB += "fp";
1864 S += Number; 2036 OB += Number;
1865 } 2037 }
1866}; 2038};
1867 2039
@@ -1870,17 +2042,45 @@ class ConversionExpr : public Node {
1870 NodeArray Expressions; 2042 NodeArray Expressions;
1871 2043
1872public: 2044public:
1873 ConversionExpr(const Node *Type_, NodeArray Expressions_) 2045 ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_)
1874 : Node(KConversionExpr), Type(Type_), Expressions(Expressions_) {} 2046 : Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {}
2047
2048 template <typename Fn> void match(Fn F) const {
2049 F(Type, Expressions, getPrecedence());
2050 }
2051
2052 void printLeft(OutputBuffer &OB) const override {
2053 OB.printOpen();
2054 Type->print(OB);
2055 OB.printClose();
2056 OB.printOpen();
2057 Expressions.printWithComma(OB);
2058 OB.printClose();
2059 }
2060};
2061
2062class PointerToMemberConversionExpr : public Node {
2063 const Node *Type;
2064 const Node *SubExpr;
2065 std::string_view Offset;
2066
2067public:
2068 PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_,
2069 std::string_view Offset_, Prec Prec_)
2070 : Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
2071 SubExpr(SubExpr_), Offset(Offset_) {}
1875 2072
1876 template<typename Fn> void match(Fn F) const { F(Type, Expressions); } 2073 template <typename Fn> void match(Fn F) const {
2074 F(Type, SubExpr, Offset, getPrecedence());
2075 }
1877 2076
1878 void printLeft(OutputStream &S) const override { 2077 void printLeft(OutputBuffer &OB) const override {
1879 S += "("; 2078 OB.printOpen();
1880 Type->print(S); 2079 Type->print(OB);
1881 S += ")("; 2080 OB.printClose();
1882 Expressions.printWithComma(S); 2081 OB.printOpen();
1883 S += ")"; 2082 SubExpr->print(OB);
2083 OB.printClose();
1884 } 2084 }
1885}; 2085};
1886 2086
@@ -1893,12 +2093,12 @@ public:
1893 2093
1894 template<typename Fn> void match(Fn F) const { F(Ty, Inits); } 2094 template<typename Fn> void match(Fn F) const { F(Ty, Inits); }
1895 2095
1896 void printLeft(OutputStream &S) const override { 2096 void printLeft(OutputBuffer &OB) const override {
1897 if (Ty) 2097 if (Ty)
1898 Ty->print(S); 2098 Ty->print(OB);
1899 S += '{'; 2099 OB += '{';
1900 Inits.printWithComma(S); 2100 Inits.printWithComma(OB);
1901 S += '}'; 2101 OB += '}';
1902 } 2102 }
1903}; 2103};
1904 2104
@@ -1912,18 +2112,18 @@ public:
1912 2112
1913 template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); } 2113 template<typename Fn> void match(Fn F) const { F(Elem, Init, IsArray); }
1914 2114
1915 void printLeft(OutputStream &S) const override { 2115 void printLeft(OutputBuffer &OB) const override {
1916 if (IsArray) { 2116 if (IsArray) {
1917 S += '['; 2117 OB += '[';
1918 Elem->print(S); 2118 Elem->print(OB);
1919 S += ']'; 2119 OB += ']';
1920 } else { 2120 } else {
1921 S += '.'; 2121 OB += '.';
1922 Elem->print(S); 2122 Elem->print(OB);
1923 } 2123 }
1924 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) 2124 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1925 S += " = "; 2125 OB += " = ";
1926 Init->print(S); 2126 Init->print(OB);
1927 } 2127 }
1928}; 2128};
1929 2129
@@ -1937,25 +2137,25 @@ public:
1937 2137
1938 template<typename Fn> void match(Fn F) const { F(First, Last, Init); } 2138 template<typename Fn> void match(Fn F) const { F(First, Last, Init); }
1939 2139
1940 void printLeft(OutputStream &S) const override { 2140 void printLeft(OutputBuffer &OB) const override {
1941 S += '['; 2141 OB += '[';
1942 First->print(S); 2142 First->print(OB);
1943 S += " ... "; 2143 OB += " ... ";
1944 Last->print(S); 2144 Last->print(OB);
1945 S += ']'; 2145 OB += ']';
1946 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr) 2146 if (Init->getKind() != KBracedExpr && Init->getKind() != KBracedRangeExpr)
1947 S += " = "; 2147 OB += " = ";
1948 Init->print(S); 2148 Init->print(OB);
1949 } 2149 }
1950}; 2150};
1951 2151
1952class FoldExpr : public Node { 2152class FoldExpr : public Node {
1953 const Node *Pack, *Init; 2153 const Node *Pack, *Init;
1954 StringView OperatorName; 2154 std::string_view OperatorName;
1955 bool IsLeftFold; 2155 bool IsLeftFold;
1956 2156
1957public: 2157public:
1958 FoldExpr(bool IsLeftFold_, StringView OperatorName_, const Node *Pack_, 2158 FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_,
1959 const Node *Init_) 2159 const Node *Init_)
1960 : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_), 2160 : Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
1961 IsLeftFold(IsLeftFold_) {} 2161 IsLeftFold(IsLeftFold_) {}
@@ -1964,43 +2164,35 @@ public:
1964 F(IsLeftFold, OperatorName, Pack, Init); 2164 F(IsLeftFold, OperatorName, Pack, Init);
1965 } 2165 }
1966 2166
1967 void printLeft(OutputStream &S) const override { 2167 void printLeft(OutputBuffer &OB) const override {
1968 auto PrintPack = [&] { 2168 auto PrintPack = [&] {
1969 S += '('; 2169 OB.printOpen();
1970 ParameterPackExpansion(Pack).print(S); 2170 ParameterPackExpansion(Pack).print(OB);
1971 S += ')'; 2171 OB.printClose();
1972 }; 2172 };
1973 2173
1974 S += '('; 2174 OB.printOpen();
1975 2175 // Either '[init op ]... op pack' or 'pack op ...[ op init]'
1976 if (IsLeftFold) { 2176 // Refactored to '[(init|pack) op ]...[ op (pack|init)]'
1977 // init op ... op pack 2177 // Fold expr operands are cast-expressions
1978 if (Init != nullptr) { 2178 if (!IsLeftFold || Init != nullptr) {
1979 Init->print(S); 2179 // '(init|pack) op '
1980 S += ' '; 2180 if (IsLeftFold)
1981 S += OperatorName; 2181 Init->printAsOperand(OB, Prec::Cast, true);
1982 S += ' '; 2182 else
1983 } 2183 PrintPack();
1984 // ... op pack 2184 OB << " " << OperatorName << " ";
1985 S += "... "; 2185 }
1986 S += OperatorName; 2186 OB << "...";
1987 S += ' '; 2187 if (IsLeftFold || Init != nullptr) {
1988 PrintPack(); 2188 // ' op (init|pack)'
1989 } else { // !IsLeftFold 2189 OB << " " << OperatorName << " ";
1990 // pack op ... 2190 if (IsLeftFold)
1991 PrintPack(); 2191 PrintPack();
1992 S += ' '; 2192 else
1993 S += OperatorName; 2193 Init->printAsOperand(OB, Prec::Cast, true);
1994 S += " ...";
1995 // pack op ... op init
1996 if (Init != nullptr) {
1997 S += ' ';
1998 S += OperatorName;
1999 S += ' ';
2000 Init->print(S);
2001 }
2002 } 2194 }
2003 S += ')'; 2195 OB.printClose();
2004 } 2196 }
2005}; 2197};
2006 2198
@@ -2012,24 +2204,9 @@ public:
2012 2204
2013 template<typename Fn> void match(Fn F) const { F(Op); } 2205 template<typename Fn> void match(Fn F) const { F(Op); }
2014 2206
2015 void printLeft(OutputStream &S) const override { 2207 void printLeft(OutputBuffer &OB) const override {
2016 S += "throw "; 2208 OB += "throw ";
2017 Op->print(S); 2209 Op->print(OB);
2018 }
2019};
2020
2021// MSVC __uuidof extension, generated by clang in -fms-extensions mode.
2022class UUIDOfExpr : public Node {
2023 Node *Operand;
2024public:
2025 UUIDOfExpr(Node *Operand_) : Node(KUUIDOfExpr), Operand(Operand_) {}
2026
2027 template<typename Fn> void match(Fn F) const { F(Operand); }
2028
2029 void printLeft(OutputStream &S) const override {
2030 S << "__uuidof(";
2031 Operand->print(S);
2032 S << ")";
2033 } 2210 }
2034}; 2211};
2035 2212
@@ -2041,8 +2218,8 @@ public:
2041 2218
2042 template<typename Fn> void match(Fn F) const { F(Value); } 2219 template<typename Fn> void match(Fn F) const { F(Value); }
2043 2220
2044 void printLeft(OutputStream &S) const override { 2221 void printLeft(OutputBuffer &OB) const override {
2045 S += Value ? StringView("true") : StringView("false"); 2222 OB += Value ? std::string_view("true") : std::string_view("false");
2046 } 2223 }
2047}; 2224};
2048 2225
@@ -2054,10 +2231,10 @@ public:
2054 2231
2055 template<typename Fn> void match(Fn F) const { F(Type); } 2232 template<typename Fn> void match(Fn F) const { F(Type); }
2056 2233
2057 void printLeft(OutputStream &S) const override { 2234 void printLeft(OutputBuffer &OB) const override {
2058 S += "\"<"; 2235 OB += "\"<";
2059 Type->print(S); 2236 Type->print(OB);
2060 S += ">\""; 2237 OB += ">\"";
2061 } 2238 }
2062}; 2239};
2063 2240
@@ -2069,58 +2246,61 @@ public:
2069 2246
2070 template<typename Fn> void match(Fn F) const { F(Type); } 2247 template<typename Fn> void match(Fn F) const { F(Type); }
2071 2248
2072 void printLeft(OutputStream &S) const override { 2249 void printLeft(OutputBuffer &OB) const override {
2073 S += "[]"; 2250 OB += "[]";
2074 if (Type->getKind() == KClosureTypeName) 2251 if (Type->getKind() == KClosureTypeName)
2075 static_cast<const ClosureTypeName *>(Type)->printDeclarator(S); 2252 static_cast<const ClosureTypeName *>(Type)->printDeclarator(OB);
2076 S += "{...}"; 2253 OB += "{...}";
2077 } 2254 }
2078}; 2255};
2079 2256
2080class IntegerCastExpr : public Node { 2257class EnumLiteral : public Node {
2081 // ty(integer) 2258 // ty(integer)
2082 const Node *Ty; 2259 const Node *Ty;
2083 StringView Integer; 2260 std::string_view Integer;
2084 2261
2085public: 2262public:
2086 IntegerCastExpr(const Node *Ty_, StringView Integer_) 2263 EnumLiteral(const Node *Ty_, std::string_view Integer_)
2087 : Node(KIntegerCastExpr), Ty(Ty_), Integer(Integer_) {} 2264 : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
2088 2265
2089 template<typename Fn> void match(Fn F) const { F(Ty, Integer); } 2266 template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
2090 2267
2091 void printLeft(OutputStream &S) const override { 2268 void printLeft(OutputBuffer &OB) const override {
2092 S += "("; 2269 OB.printOpen();
2093 Ty->print(S); 2270 Ty->print(OB);
2094 S += ")"; 2271 OB.printClose();
2095 S += Integer; 2272
2273 if (Integer[0] == 'n')
2274 OB << '-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
2275 else
2276 OB << Integer;
2096 } 2277 }
2097}; 2278};
2098 2279
2099class IntegerLiteral : public Node { 2280class IntegerLiteral : public Node {
2100 StringView Type; 2281 std::string_view Type;
2101 StringView Value; 2282 std::string_view Value;
2102 2283
2103public: 2284public:
2104 IntegerLiteral(StringView Type_, StringView Value_) 2285 IntegerLiteral(std::string_view Type_, std::string_view Value_)
2105 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {} 2286 : Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
2106 2287
2107 template<typename Fn> void match(Fn F) const { F(Type, Value); } 2288 template<typename Fn> void match(Fn F) const { F(Type, Value); }
2108 2289
2109 void printLeft(OutputStream &S) const override { 2290 void printLeft(OutputBuffer &OB) const override {
2110 if (Type.size() > 3) { 2291 if (Type.size() > 3) {
2111 S += "("; 2292 OB.printOpen();
2112 S += Type; 2293 OB += Type;
2113 S += ")"; 2294 OB.printClose();
2114 } 2295 }
2115 2296
2116 if (Value[0] == 'n') { 2297 if (Value[0] == 'n')
2117 S += "-"; 2298 OB << '-' << std::string_view(Value.data() + 1, Value.size() - 1);
2118 S += Value.dropFront(1); 2299 else
2119 } else 2300 OB += Value;
2120 S += Value;
2121 2301
2122 if (Type.size() <= 3) 2302 if (Type.size() <= 3)
2123 S += Type; 2303 OB += Type;
2124 } 2304 }
2125}; 2305};
2126 2306
@@ -2139,29 +2319,26 @@ constexpr Node::Kind getFloatLiteralKind(long double *) {
2139} 2319}
2140 2320
2141template <class Float> class FloatLiteralImpl : public Node { 2321template <class Float> class FloatLiteralImpl : public Node {
2142 const StringView Contents; 2322 const std::string_view Contents;
2143 2323
2144 static constexpr Kind KindForClass = 2324 static constexpr Kind KindForClass =
2145 float_literal_impl::getFloatLiteralKind((Float *)nullptr); 2325 float_literal_impl::getFloatLiteralKind((Float *)nullptr);
2146 2326
2147public: 2327public:
2148 FloatLiteralImpl(StringView Contents_) 2328 FloatLiteralImpl(std::string_view Contents_)
2149 : Node(KindForClass), Contents(Contents_) {} 2329 : Node(KindForClass), Contents(Contents_) {}
2150 2330
2151 template<typename Fn> void match(Fn F) const { F(Contents); } 2331 template<typename Fn> void match(Fn F) const { F(Contents); }
2152 2332
2153 void printLeft(OutputStream &s) const override { 2333 void printLeft(OutputBuffer &OB) const override {
2154 const char *first = Contents.begin();
2155 const char *last = Contents.end() + 1;
2156
2157 const size_t N = FloatData<Float>::mangled_size; 2334 const size_t N = FloatData<Float>::mangled_size;
2158 if (static_cast<std::size_t>(last - first) > N) { 2335 if (Contents.size() >= N) {
2159 last = first + N;
2160 union { 2336 union {
2161 Float value; 2337 Float value;
2162 char buf[sizeof(Float)]; 2338 char buf[sizeof(Float)];
2163 }; 2339 };
2164 const char *t = first; 2340 const char *t = Contents.data();
2341 const char *last = t + N;
2165 char *e = buf; 2342 char *e = buf;
2166 for (; t != last; ++t, ++e) { 2343 for (; t != last; ++t, ++e) {
2167 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0') 2344 unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0')
@@ -2176,7 +2353,7 @@ public:
2176#endif 2353#endif
2177 char num[FloatData<Float>::max_demangled_size] = {0}; 2354 char num[FloatData<Float>::max_demangled_size] = {0};
2178 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value); 2355 int n = snprintf(num, sizeof(num), FloatData<Float>::spec, value);
2179 s += StringView(num, num + n); 2356 OB += std::string_view(num, n);
2180 } 2357 }
2181 } 2358 }
2182}; 2359};
@@ -2190,143 +2367,22 @@ using LongDoubleLiteral = FloatLiteralImpl<long double>;
2190template<typename Fn> 2367template<typename Fn>
2191void Node::visit(Fn F) const { 2368void Node::visit(Fn F) const {
2192 switch (K) { 2369 switch (K) {
2193#define CASE(X) case K ## X: return F(static_cast<const X*>(this)); 2370#define NODE(X) \
2194 FOR_EACH_NODE_KIND(CASE) 2371 case K##X: \
2195#undef CASE 2372 return F(static_cast<const X *>(this));
2373#include "ItaniumNodes.def"
2196 } 2374 }
2197 assert(0 && "unknown mangling node kind"); 2375 assert(0 && "unknown mangling node kind");
2198} 2376}
2199 2377
2200/// Determine the kind of a node from its type. 2378/// Determine the kind of a node from its type.
2201template<typename NodeT> struct NodeKind; 2379template<typename NodeT> struct NodeKind;
2202#define SPECIALIZATION(X) \ 2380#define NODE(X) \
2203 template<> struct NodeKind<X> { \ 2381 template <> struct NodeKind<X> { \
2204 static constexpr Node::Kind Kind = Node::K##X; \ 2382 static constexpr Node::Kind Kind = Node::K##X; \
2205 static constexpr const char *name() { return #X; } \ 2383 static constexpr const char *name() { return #X; } \
2206 }; 2384 };
2207FOR_EACH_NODE_KIND(SPECIALIZATION) 2385#include "ItaniumNodes.def"
2208#undef SPECIALIZATION
2209
2210#undef FOR_EACH_NODE_KIND
2211
2212template <class T, size_t N>
2213class PODSmallVector {
2214 static_assert(std::is_pod<T>::value,
2215 "T is required to be a plain old data type");
2216
2217 T* First;
2218 T* Last;
2219 T* Cap;
2220 T Inline[N];
2221
2222 bool isInline() const { return First == Inline; }
2223
2224 void clearInline() {
2225 First = Inline;
2226 Last = Inline;
2227 Cap = Inline + N;
2228 }
2229
2230 void reserve(size_t NewCap) {
2231 size_t S = size();
2232 if (isInline()) {
2233 auto* Tmp = static_cast<T*>(std::malloc(NewCap * sizeof(T)));
2234 if (Tmp == nullptr)
2235 std::terminate();
2236 std::copy(First, Last, Tmp);
2237 First = Tmp;
2238 } else {
2239 First = static_cast<T*>(std::realloc(First, NewCap * sizeof(T)));
2240 if (First == nullptr)
2241 std::terminate();
2242 }
2243 Last = First + S;
2244 Cap = First + NewCap;
2245 }
2246
2247public:
2248 PODSmallVector() : First(Inline), Last(First), Cap(Inline + N) {}
2249
2250 PODSmallVector(const PODSmallVector&) = delete;
2251 PODSmallVector& operator=(const PODSmallVector&) = delete;
2252
2253 PODSmallVector(PODSmallVector&& Other) : PODSmallVector() {
2254 if (Other.isInline()) {
2255 std::copy(Other.begin(), Other.end(), First);
2256 Last = First + Other.size();
2257 Other.clear();
2258 return;
2259 }
2260
2261 First = Other.First;
2262 Last = Other.Last;
2263 Cap = Other.Cap;
2264 Other.clearInline();
2265 }
2266
2267 PODSmallVector& operator=(PODSmallVector&& Other) {
2268 if (Other.isInline()) {
2269 if (!isInline()) {
2270 std::free(First);
2271 clearInline();
2272 }
2273 std::copy(Other.begin(), Other.end(), First);
2274 Last = First + Other.size();
2275 Other.clear();
2276 return *this;
2277 }
2278
2279 if (isInline()) {
2280 First = Other.First;
2281 Last = Other.Last;
2282 Cap = Other.Cap;
2283 Other.clearInline();
2284 return *this;
2285 }
2286
2287 std::swap(First, Other.First);
2288 std::swap(Last, Other.Last);
2289 std::swap(Cap, Other.Cap);
2290 Other.clear();
2291 return *this;
2292 }
2293
2294 void push_back(const T& Elem) {
2295 if (Last == Cap)
2296 reserve(size() * 2);
2297 *Last++ = Elem;
2298 }
2299
2300 void pop_back() {
2301 assert(Last != First && "Popping empty vector!");
2302 --Last;
2303 }
2304
2305 void dropBack(size_t Index) {
2306 assert(Index <= size() && "dropBack() can't expand!");
2307 Last = First + Index;
2308 }
2309
2310 T* begin() { return First; }
2311 T* end() { return Last; }
2312
2313 bool empty() const { return First == Last; }
2314 size_t size() const { return static_cast<size_t>(Last - First); }
2315 T& back() {
2316 assert(Last != First && "Calling back() on empty vector!");
2317 return *(Last - 1);
2318 }
2319 T& operator[](size_t Index) {
2320 assert(Index < size() && "Invalid access!");
2321 return *(begin() + Index);
2322 }
2323 void clear() { Last = First; }
2324
2325 ~PODSmallVector() {
2326 if (!isInline())
2327 std::free(First);
2328 }
2329};
2330 2386
2331template <typename Derived, typename Alloc> struct AbstractManglingParser { 2387template <typename Derived, typename Alloc> struct AbstractManglingParser {
2332 const char *First; 2388 const char *First;
@@ -2350,9 +2406,9 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
2350 TemplateParamList Params; 2406 TemplateParamList Params;
2351 2407
2352 public: 2408 public:
2353 ScopedTemplateParamList(AbstractManglingParser *Parser) 2409 ScopedTemplateParamList(AbstractManglingParser *TheParser)
2354 : Parser(Parser), 2410 : Parser(TheParser),
2355 OldNumTemplateParamLists(Parser->TemplateParams.size()) { 2411 OldNumTemplateParamLists(TheParser->TemplateParams.size()) {
2356 Parser->TemplateParams.push_back(&Params); 2412 Parser->TemplateParams.push_back(&Params);
2357 } 2413 }
2358 ~ScopedTemplateParamList() { 2414 ~ScopedTemplateParamList() {
@@ -2424,8 +2480,9 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
2424 return res; 2480 return res;
2425 } 2481 }
2426 2482
2427 bool consumeIf(StringView S) { 2483 bool consumeIf(std::string_view S) {
2428 if (StringView(First, Last).startsWith(S)) { 2484 if (llvm::itanium_demangle::starts_with(
2485 std::string_view(First, Last - First), S)) {
2429 First += S.size(); 2486 First += S.size();
2430 return true; 2487 return true;
2431 } 2488 }
@@ -2442,7 +2499,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
2442 2499
2443 char consume() { return First != Last ? *First++ : '\0'; } 2500 char consume() { return First != Last ? *First++ : '\0'; }
2444 2501
2445 char look(unsigned Lookahead = 0) { 2502 char look(unsigned Lookahead = 0) const {
2446 if (static_cast<size_t>(Last - First) <= Lookahead) 2503 if (static_cast<size_t>(Last - First) <= Lookahead)
2447 return '\0'; 2504 return '\0';
2448 return First[Lookahead]; 2505 return First[Lookahead];
@@ -2450,10 +2507,10 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
2450 2507
2451 size_t numLeft() const { return static_cast<size_t>(Last - First); } 2508 size_t numLeft() const { return static_cast<size_t>(Last - First); }
2452 2509
2453 StringView parseNumber(bool AllowNegative = false); 2510 std::string_view parseNumber(bool AllowNegative = false);
2454 Qualifiers parseCVQualifiers(); 2511 Qualifiers parseCVQualifiers();
2455 bool parsePositiveInteger(size_t *Out); 2512 bool parsePositiveInteger(size_t *Out);
2456 StringView parseBareSourceName(); 2513 std::string_view parseBareSourceName();
2457 2514
2458 bool parseSeqId(size_t *Out); 2515 bool parseSeqId(size_t *Out);
2459 Node *parseSubstitution(); 2516 Node *parseSubstitution();
@@ -2464,16 +2521,17 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
2464 2521
2465 /// Parse the <expr> production. 2522 /// Parse the <expr> production.
2466 Node *parseExpr(); 2523 Node *parseExpr();
2467 Node *parsePrefixExpr(StringView Kind); 2524 Node *parsePrefixExpr(std::string_view Kind, Node::Prec Prec);
2468 Node *parseBinaryExpr(StringView Kind); 2525 Node *parseBinaryExpr(std::string_view Kind, Node::Prec Prec);
2469 Node *parseIntegerLiteral(StringView Lit); 2526 Node *parseIntegerLiteral(std::string_view Lit);
2470 Node *parseExprPrimary(); 2527 Node *parseExprPrimary();
2471 template <class Float> Node *parseFloatingLiteral(); 2528 template <class Float> Node *parseFloatingLiteral();
2472 Node *parseFunctionParam(); 2529 Node *parseFunctionParam();
2473 Node *parseNewExpr();
2474 Node *parseConversionExpr(); 2530 Node *parseConversionExpr();
2475 Node *parseBracedExpr(); 2531 Node *parseBracedExpr();
2476 Node *parseFoldExpr(); 2532 Node *parseFoldExpr();
2533 Node *parsePointerToMemberConversionExpr(Node::Prec Prec);
2534 Node *parseSubobjectExpr();
2477 2535
2478 /// Parse the <type> production. 2536 /// Parse the <type> production.
2479 Node *parseType(); 2537 Node *parseType();
@@ -2520,17 +2578,81 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
2520 Node *parseName(NameState *State = nullptr); 2578 Node *parseName(NameState *State = nullptr);
2521 Node *parseLocalName(NameState *State); 2579 Node *parseLocalName(NameState *State);
2522 Node *parseOperatorName(NameState *State); 2580 Node *parseOperatorName(NameState *State);
2523 Node *parseUnqualifiedName(NameState *State); 2581 bool parseModuleNameOpt(ModuleName *&Module);
2582 Node *parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module);
2524 Node *parseUnnamedTypeName(NameState *State); 2583 Node *parseUnnamedTypeName(NameState *State);
2525 Node *parseSourceName(NameState *State); 2584 Node *parseSourceName(NameState *State);
2526 Node *parseUnscopedName(NameState *State); 2585 Node *parseUnscopedName(NameState *State, bool *isSubstName);
2527 Node *parseNestedName(NameState *State); 2586 Node *parseNestedName(NameState *State);
2528 Node *parseCtorDtorName(Node *&SoFar, NameState *State); 2587 Node *parseCtorDtorName(Node *&SoFar, NameState *State);
2529 2588
2530 Node *parseAbiTags(Node *N); 2589 Node *parseAbiTags(Node *N);
2531 2590
2591 struct OperatorInfo {
2592 enum OIKind : unsigned char {
2593 Prefix, // Prefix unary: @ expr
2594 Postfix, // Postfix unary: expr @
2595 Binary, // Binary: lhs @ rhs
2596 Array, // Array index: lhs [ rhs ]
2597 Member, // Member access: lhs @ rhs
2598 New, // New
2599 Del, // Delete
2600 Call, // Function call: expr (expr*)
2601 CCast, // C cast: (type)expr
2602 Conditional, // Conditional: expr ? expr : expr
2603 NameOnly, // Overload only, not allowed in expression.
2604 // Below do not have operator names
2605 NamedCast, // Named cast, @<type>(expr)
2606 OfIdOp, // alignof, sizeof, typeid
2607
2608 Unnameable = NamedCast,
2609 };
2610 char Enc[2]; // Encoding
2611 OIKind Kind; // Kind of operator
2612 bool Flag : 1; // Entry-specific flag
2613 Node::Prec Prec : 7; // Precedence
2614 const char *Name; // Spelling
2615
2616 public:
2617 constexpr OperatorInfo(const char (&E)[3], OIKind K, bool F, Node::Prec P,
2618 const char *N)
2619 : Enc{E[0], E[1]}, Kind{K}, Flag{F}, Prec{P}, Name{N} {}
2620
2621 public:
2622 bool operator<(const OperatorInfo &Other) const {
2623 return *this < Other.Enc;
2624 }
2625 bool operator<(const char *Peek) const {
2626 return Enc[0] < Peek[0] || (Enc[0] == Peek[0] && Enc[1] < Peek[1]);
2627 }
2628 bool operator==(const char *Peek) const {
2629 return Enc[0] == Peek[0] && Enc[1] == Peek[1];
2630 }
2631 bool operator!=(const char *Peek) const { return !this->operator==(Peek); }
2632
2633 public:
2634 std::string_view getSymbol() const {
2635 std::string_view Res = Name;
2636 if (Kind < Unnameable) {
2637 assert(llvm::itanium_demangle::starts_with(Res, "operator") &&
2638 "operator name does not start with 'operator'");
2639 Res.remove_prefix(sizeof("operator") - 1);
2640 if (llvm::itanium_demangle::starts_with(Res, ' '))
2641 Res.remove_prefix(1);
2642 }
2643 return Res;
2644 }
2645 std::string_view getName() const { return Name; }
2646 OIKind getKind() const { return Kind; }
2647 bool getFlag() const { return Flag; }
2648 Node::Prec getPrecedence() const { return Prec; }
2649 };
2650 static const OperatorInfo Ops[];
2651 static const size_t NumOps;
2652 const OperatorInfo *parseOperatorEncoding();
2653
2532 /// Parse the <unresolved-name> production. 2654 /// Parse the <unresolved-name> production.
2533 Node *parseUnresolvedName(); 2655 Node *parseUnresolvedName(bool Global);
2534 Node *parseSimpleId(); 2656 Node *parseSimpleId();
2535 Node *parseBaseUnresolvedName(); 2657 Node *parseBaseUnresolvedName();
2536 Node *parseUnresolvedType(); 2658 Node *parseUnresolvedType();
@@ -2551,41 +2673,35 @@ const char* parse_discriminator(const char* first, const char* last);
2551// ::= <substitution> 2673// ::= <substitution>
2552template <typename Derived, typename Alloc> 2674template <typename Derived, typename Alloc>
2553Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) { 2675Node *AbstractManglingParser<Derived, Alloc>::parseName(NameState *State) {
2554 consumeIf('L'); // extension
2555
2556 if (look() == 'N') 2676 if (look() == 'N')
2557 return getDerived().parseNestedName(State); 2677 return getDerived().parseNestedName(State);
2558 if (look() == 'Z') 2678 if (look() == 'Z')
2559 return getDerived().parseLocalName(State); 2679 return getDerived().parseLocalName(State);
2560 2680
2561 // ::= <unscoped-template-name> <template-args> 2681 Node *Result = nullptr;
2562 if (look() == 'S' && look(1) != 't') { 2682 bool IsSubst = false;
2563 Node *S = getDerived().parseSubstitution();
2564 if (S == nullptr)
2565 return nullptr;
2566 if (look() != 'I')
2567 return nullptr;
2568 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
2569 if (TA == nullptr)
2570 return nullptr;
2571 if (State) State->EndsWithTemplateArgs = true;
2572 return make<NameWithTemplateArgs>(S, TA);
2573 }
2574 2683
2575 Node *N = getDerived().parseUnscopedName(State); 2684 Result = getDerived().parseUnscopedName(State, &IsSubst);
2576 if (N == nullptr) 2685 if (!Result)
2577 return nullptr; 2686 return nullptr;
2578 // ::= <unscoped-template-name> <template-args> 2687
2579 if (look() == 'I') { 2688 if (look() == 'I') {
2580 Subs.push_back(N); 2689 // ::= <unscoped-template-name> <template-args>
2690 if (!IsSubst)
2691 // An unscoped-template-name is substitutable.
2692 Subs.push_back(Result);
2581 Node *TA = getDerived().parseTemplateArgs(State != nullptr); 2693 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
2582 if (TA == nullptr) 2694 if (TA == nullptr)
2583 return nullptr; 2695 return nullptr;
2584 if (State) State->EndsWithTemplateArgs = true; 2696 if (State)
2585 return make<NameWithTemplateArgs>(N, TA); 2697 State->EndsWithTemplateArgs = true;
2698 Result = make<NameWithTemplateArgs>(Result, TA);
2699 } else if (IsSubst) {
2700 // The substitution case must be followed by <template-args>.
2701 return nullptr;
2586 } 2702 }
2587 // ::= <unscoped-name> 2703
2588 return N; 2704 return Result;
2589} 2705}
2590 2706
2591// <local-name> := Z <function encoding> E <entity name> [<discriminator>] 2707// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
@@ -2626,34 +2742,63 @@ Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
2626 2742
2627// <unscoped-name> ::= <unqualified-name> 2743// <unscoped-name> ::= <unqualified-name>
2628// ::= St <unqualified-name> # ::std:: 2744// ::= St <unqualified-name> # ::std::
2629// extension ::= StL<unqualified-name> 2745// [*] extension
2630template <typename Derived, typename Alloc> 2746template <typename Derived, typename Alloc>
2631Node * 2747Node *
2632AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State) { 2748AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
2633 if (consumeIf("StL") || consumeIf("St")) { 2749 bool *IsSubst) {
2634 Node *R = getDerived().parseUnqualifiedName(State); 2750
2635 if (R == nullptr) 2751 Node *Std = nullptr;
2752 if (consumeIf("St")) {
2753 Std = make<NameType>("std");
2754 if (Std == nullptr)
2636 return nullptr; 2755 return nullptr;
2637 return make<StdQualifiedName>(R);
2638 } 2756 }
2639 return getDerived().parseUnqualifiedName(State); 2757
2758 Node *Res = nullptr;
2759 ModuleName *Module = nullptr;
2760 if (look() == 'S') {
2761 Node *S = getDerived().parseSubstitution();
2762 if (!S)
2763 return nullptr;
2764 if (S->getKind() == Node::KModuleName)
2765 Module = static_cast<ModuleName *>(S);
2766 else if (IsSubst && Std == nullptr) {
2767 Res = S;
2768 *IsSubst = true;
2769 } else {
2770 return nullptr;
2771 }
2772 }
2773
2774 if (Res == nullptr || Std != nullptr) {
2775 Res = getDerived().parseUnqualifiedName(State, Std, Module);
2776 }
2777
2778 return Res;
2640} 2779}
2641 2780
2642// <unqualified-name> ::= <operator-name> [abi-tags] 2781// <unqualified-name> ::= [<module-name>] L? <operator-name> [<abi-tags>]
2643// ::= <ctor-dtor-name> 2782// ::= [<module-name>] <ctor-dtor-name> [<abi-tags>]
2644// ::= <source-name> 2783// ::= [<module-name>] L? <source-name> [<abi-tags>]
2645// ::= <unnamed-type-name> 2784// ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>]
2646// ::= DC <source-name>+ E # structured binding declaration 2785// # structured binding declaration
2786// ::= [<module-name>] L? DC <source-name>+ E
2647template <typename Derived, typename Alloc> 2787template <typename Derived, typename Alloc>
2648Node * 2788Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
2649AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(NameState *State) { 2789 NameState *State, Node *Scope, ModuleName *Module) {
2650 // <ctor-dtor-name>s are special-cased in parseNestedName(). 2790 if (getDerived().parseModuleNameOpt(Module))
2791 return nullptr;
2792
2793 consumeIf('L');
2794
2651 Node *Result; 2795 Node *Result;
2652 if (look() == 'U') 2796 if (look() >= '1' && look() <= '9') {
2653 Result = getDerived().parseUnnamedTypeName(State);
2654 else if (look() >= '1' && look() <= '9')
2655 Result = getDerived().parseSourceName(State); 2797 Result = getDerived().parseSourceName(State);
2656 else if (consumeIf("DC")) { 2798 } else if (look() == 'U') {
2799 Result = getDerived().parseUnnamedTypeName(State);
2800 } else if (consumeIf("DC")) {
2801 // Structured binding
2657 size_t BindingsBegin = Names.size(); 2802 size_t BindingsBegin = Names.size();
2658 do { 2803 do {
2659 Node *Binding = getDerived().parseSourceName(State); 2804 Node *Binding = getDerived().parseSourceName(State);
@@ -2662,13 +2807,46 @@ AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(NameState *State) {
2662 Names.push_back(Binding); 2807 Names.push_back(Binding);
2663 } while (!consumeIf('E')); 2808 } while (!consumeIf('E'));
2664 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin)); 2809 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
2665 } else 2810 } else if (look() == 'C' || look() == 'D') {
2811 // A <ctor-dtor-name>.
2812 if (Scope == nullptr || Module != nullptr)
2813 return nullptr;
2814 Result = getDerived().parseCtorDtorName(Scope, State);
2815 } else {
2666 Result = getDerived().parseOperatorName(State); 2816 Result = getDerived().parseOperatorName(State);
2817 }
2818
2819 if (Result != nullptr && Module != nullptr)
2820 Result = make<ModuleEntity>(Module, Result);
2667 if (Result != nullptr) 2821 if (Result != nullptr)
2668 Result = getDerived().parseAbiTags(Result); 2822 Result = getDerived().parseAbiTags(Result);
2823 if (Result != nullptr && Scope != nullptr)
2824 Result = make<NestedName>(Scope, Result);
2825
2669 return Result; 2826 return Result;
2670} 2827}
2671 2828
2829// <module-name> ::= <module-subname>
2830// ::= <module-name> <module-subname>
2831// ::= <substitution> # passed in by caller
2832// <module-subname> ::= W <source-name>
2833// ::= W P <source-name>
2834template <typename Derived, typename Alloc>
2835bool AbstractManglingParser<Derived, Alloc>::parseModuleNameOpt(
2836 ModuleName *&Module) {
2837 while (consumeIf('W')) {
2838 bool IsPartition = consumeIf('P');
2839 Node *Sub = getDerived().parseSourceName(nullptr);
2840 if (!Sub)
2841 return true;
2842 Module =
2843 static_cast<ModuleName *>(make<ModuleName>(Module, Sub, IsPartition));
2844 Subs.push_back(Module);
2845 }
2846
2847 return false;
2848}
2849
2672// <unnamed-type-name> ::= Ut [<nonnegative number>] _ 2850// <unnamed-type-name> ::= Ut [<nonnegative number>] _
2673// ::= <closure-type-name> 2851// ::= <closure-type-name>
2674// 2852//
@@ -2684,19 +2862,19 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
2684 TemplateParams.clear(); 2862 TemplateParams.clear();
2685 2863
2686 if (consumeIf("Ut")) { 2864 if (consumeIf("Ut")) {
2687 StringView Count = parseNumber(); 2865 std::string_view Count = parseNumber();
2688 if (!consumeIf('_')) 2866 if (!consumeIf('_'))
2689 return nullptr; 2867 return nullptr;
2690 return make<UnnamedTypeName>(Count); 2868 return make<UnnamedTypeName>(Count);
2691 } 2869 }
2692 if (consumeIf("Ul")) { 2870 if (consumeIf("Ul")) {
2693 SwapAndRestore<size_t> SwapParams(ParsingLambdaParamsAtLevel, 2871 ScopedOverride<size_t> SwapParams(ParsingLambdaParamsAtLevel,
2694 TemplateParams.size()); 2872 TemplateParams.size());
2695 ScopedTemplateParamList LambdaTemplateParams(this); 2873 ScopedTemplateParamList LambdaTemplateParams(this);
2696 2874
2697 size_t ParamsBegin = Names.size(); 2875 size_t ParamsBegin = Names.size();
2698 while (look() == 'T' && 2876 while (look() == 'T' &&
2699 StringView("yptn").find(look(1)) != StringView::npos) { 2877 std::string_view("yptn").find(look(1)) != std::string_view::npos) {
2700 Node *T = parseTemplateParamDecl(); 2878 Node *T = parseTemplateParamDecl();
2701 if (!T) 2879 if (!T)
2702 return nullptr; 2880 return nullptr;
@@ -2739,7 +2917,7 @@ AbstractManglingParser<Derived, Alloc>::parseUnnamedTypeName(NameState *State) {
2739 } 2917 }
2740 NodeArray Params = popTrailingNodeArray(ParamsBegin); 2918 NodeArray Params = popTrailingNodeArray(ParamsBegin);
2741 2919
2742 StringView Count = parseNumber(); 2920 std::string_view Count = parseNumber();
2743 if (!consumeIf('_')) 2921 if (!consumeIf('_'))
2744 return nullptr; 2922 return nullptr;
2745 return make<ClosureTypeName>(TempParams, Params, Count); 2923 return make<ClosureTypeName>(TempParams, Params, Count);
@@ -2761,104 +2939,138 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSourceName(NameState *) {
2761 return nullptr; 2939 return nullptr;
2762 if (numLeft() < Length || Length == 0) 2940 if (numLeft() < Length || Length == 0)
2763 return nullptr; 2941 return nullptr;
2764 StringView Name(First, First + Length); 2942 std::string_view Name(First, Length);
2765 First += Length; 2943 First += Length;
2766 if (Name.startsWith("_GLOBAL__N")) 2944 if (llvm::itanium_demangle::starts_with(Name, "_GLOBAL__N"))
2767 return make<NameType>("(anonymous namespace)"); 2945 return make<NameType>("(anonymous namespace)");
2768 return make<NameType>(Name); 2946 return make<NameType>(Name);
2769} 2947}
2770 2948
2771// <operator-name> ::= aa # && 2949// Operator encodings
2772// ::= ad # & (unary) 2950template <typename Derived, typename Alloc>
2773// ::= an # & 2951const typename AbstractManglingParser<
2774// ::= aN # &= 2952 Derived, Alloc>::OperatorInfo AbstractManglingParser<Derived,
2775// ::= aS # = 2953 Alloc>::Ops[] = {
2776// ::= cl # () 2954 // Keep ordered by encoding
2777// ::= cm # , 2955 {"aN", OperatorInfo::Binary, false, Node::Prec::Assign, "operator&="},
2778// ::= co # ~ 2956 {"aS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator="},
2779// ::= cv <type> # (cast) 2957 {"aa", OperatorInfo::Binary, false, Node::Prec::AndIf, "operator&&"},
2780// ::= da # delete[] 2958 {"ad", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator&"},
2781// ::= de # * (unary) 2959 {"an", OperatorInfo::Binary, false, Node::Prec::And, "operator&"},
2782// ::= dl # delete 2960 {"at", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "alignof "},
2783// ::= dv # / 2961 {"aw", OperatorInfo::NameOnly, false, Node::Prec::Primary,
2784// ::= dV # /= 2962 "operator co_await"},
2785// ::= eo # ^ 2963 {"az", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "alignof "},
2786// ::= eO # ^= 2964 {"cc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "const_cast"},
2787// ::= eq # == 2965 {"cl", OperatorInfo::Call, false, Node::Prec::Postfix, "operator()"},
2788// ::= ge # >= 2966 {"cm", OperatorInfo::Binary, false, Node::Prec::Comma, "operator,"},
2789// ::= gt # > 2967 {"co", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator~"},
2790// ::= ix # [] 2968 {"cv", OperatorInfo::CCast, false, Node::Prec::Cast, "operator"}, // C Cast
2791// ::= le # <= 2969 {"dV", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/="},
2970 {"da", OperatorInfo::Del, /*Ary*/ true, Node::Prec::Unary,
2971 "operator delete[]"},
2972 {"dc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "dynamic_cast"},
2973 {"de", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator*"},
2974 {"dl", OperatorInfo::Del, /*Ary*/ false, Node::Prec::Unary,
2975 "operator delete"},
2976 {"ds", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
2977 "operator.*"},
2978 {"dt", OperatorInfo::Member, /*Named*/ false, Node::Prec::Postfix,
2979 "operator."},
2980 {"dv", OperatorInfo::Binary, false, Node::Prec::Assign, "operator/"},
2981 {"eO", OperatorInfo::Binary, false, Node::Prec::Assign, "operator^="},
2982 {"eo", OperatorInfo::Binary, false, Node::Prec::Xor, "operator^"},
2983 {"eq", OperatorInfo::Binary, false, Node::Prec::Equality, "operator=="},
2984 {"ge", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>="},
2985 {"gt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator>"},
2986 {"ix", OperatorInfo::Array, false, Node::Prec::Postfix, "operator[]"},
2987 {"lS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator<<="},
2988 {"le", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<="},
2989 {"ls", OperatorInfo::Binary, false, Node::Prec::Shift, "operator<<"},
2990 {"lt", OperatorInfo::Binary, false, Node::Prec::Relational, "operator<"},
2991 {"mI", OperatorInfo::Binary, false, Node::Prec::Assign, "operator-="},
2992 {"mL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator*="},
2993 {"mi", OperatorInfo::Binary, false, Node::Prec::Additive, "operator-"},
2994 {"ml", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
2995 "operator*"},
2996 {"mm", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator--"},
2997 {"na", OperatorInfo::New, /*Ary*/ true, Node::Prec::Unary,
2998 "operator new[]"},
2999 {"ne", OperatorInfo::Binary, false, Node::Prec::Equality, "operator!="},
3000 {"ng", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator-"},
3001 {"nt", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator!"},
3002 {"nw", OperatorInfo::New, /*Ary*/ false, Node::Prec::Unary, "operator new"},
3003 {"oR", OperatorInfo::Binary, false, Node::Prec::Assign, "operator|="},
3004 {"oo", OperatorInfo::Binary, false, Node::Prec::OrIf, "operator||"},
3005 {"or", OperatorInfo::Binary, false, Node::Prec::Ior, "operator|"},
3006 {"pL", OperatorInfo::Binary, false, Node::Prec::Assign, "operator+="},
3007 {"pl", OperatorInfo::Binary, false, Node::Prec::Additive, "operator+"},
3008 {"pm", OperatorInfo::Member, /*Named*/ false, Node::Prec::PtrMem,
3009 "operator->*"},
3010 {"pp", OperatorInfo::Postfix, false, Node::Prec::Postfix, "operator++"},
3011 {"ps", OperatorInfo::Prefix, false, Node::Prec::Unary, "operator+"},
3012 {"pt", OperatorInfo::Member, /*Named*/ true, Node::Prec::Postfix,
3013 "operator->"},
3014 {"qu", OperatorInfo::Conditional, false, Node::Prec::Conditional,
3015 "operator?"},
3016 {"rM", OperatorInfo::Binary, false, Node::Prec::Assign, "operator%="},
3017 {"rS", OperatorInfo::Binary, false, Node::Prec::Assign, "operator>>="},
3018 {"rc", OperatorInfo::NamedCast, false, Node::Prec::Postfix,
3019 "reinterpret_cast"},
3020 {"rm", OperatorInfo::Binary, false, Node::Prec::Multiplicative,
3021 "operator%"},
3022 {"rs", OperatorInfo::Binary, false, Node::Prec::Shift, "operator>>"},
3023 {"sc", OperatorInfo::NamedCast, false, Node::Prec::Postfix, "static_cast"},
3024 {"ss", OperatorInfo::Binary, false, Node::Prec::Spaceship, "operator<=>"},
3025 {"st", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Unary, "sizeof "},
3026 {"sz", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Unary, "sizeof "},
3027 {"te", OperatorInfo::OfIdOp, /*Type*/ false, Node::Prec::Postfix,
3028 "typeid "},
3029 {"ti", OperatorInfo::OfIdOp, /*Type*/ true, Node::Prec::Postfix, "typeid "},
3030};
3031template <typename Derived, typename Alloc>
3032const size_t AbstractManglingParser<Derived, Alloc>::NumOps = sizeof(Ops) /
3033 sizeof(Ops[0]);
3034
3035// If the next 2 chars are an operator encoding, consume them and return their
3036// OperatorInfo. Otherwise return nullptr.
3037template <typename Derived, typename Alloc>
3038const typename AbstractManglingParser<Derived, Alloc>::OperatorInfo *
3039AbstractManglingParser<Derived, Alloc>::parseOperatorEncoding() {
3040 if (numLeft() < 2)
3041 return nullptr;
3042
3043 // We can't use lower_bound as that can link to symbols in the C++ library,
3044 // and this must remain independant of that.
3045 size_t lower = 0u, upper = NumOps - 1; // Inclusive bounds.
3046 while (upper != lower) {
3047 size_t middle = (upper + lower) / 2;
3048 if (Ops[middle] < First)
3049 lower = middle + 1;
3050 else
3051 upper = middle;
3052 }
3053 if (Ops[lower] != First)
3054 return nullptr;
3055
3056 First += 2;
3057 return &Ops[lower];
3058}
3059
3060// <operator-name> ::= See parseOperatorEncoding()
2792// ::= li <source-name> # operator "" 3061// ::= li <source-name> # operator ""
2793// ::= ls # << 3062// ::= v <digit> <source-name> # vendor extended operator
2794// ::= lS # <<=
2795// ::= lt # <
2796// ::= mi # -
2797// ::= mI # -=
2798// ::= ml # *
2799// ::= mL # *=
2800// ::= mm # -- (postfix in <expression> context)
2801// ::= na # new[]
2802// ::= ne # !=
2803// ::= ng # - (unary)
2804// ::= nt # !
2805// ::= nw # new
2806// ::= oo # ||
2807// ::= or # |
2808// ::= oR # |=
2809// ::= pm # ->*
2810// ::= pl # +
2811// ::= pL # +=
2812// ::= pp # ++ (postfix in <expression> context)
2813// ::= ps # + (unary)
2814// ::= pt # ->
2815// ::= qu # ?
2816// ::= rm # %
2817// ::= rM # %=
2818// ::= rs # >>
2819// ::= rS # >>=
2820// ::= ss # <=> C++2a
2821// ::= v <digit> <source-name> # vendor extended operator
2822template <typename Derived, typename Alloc> 3063template <typename Derived, typename Alloc>
2823Node * 3064Node *
2824AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) { 3065AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
2825 switch (look()) { 3066 if (const auto *Op = parseOperatorEncoding()) {
2826 case 'a': 3067 if (Op->getKind() == OperatorInfo::CCast) {
2827 switch (look(1)) { 3068 // ::= cv <type> # (cast)
2828 case 'a': 3069 ScopedOverride<bool> SaveTemplate(TryToParseTemplateArgs, false);
2829 First += 2;
2830 return make<NameType>("operator&&");
2831 case 'd':
2832 case 'n':
2833 First += 2;
2834 return make<NameType>("operator&");
2835 case 'N':
2836 First += 2;
2837 return make<NameType>("operator&=");
2838 case 'S':
2839 First += 2;
2840 return make<NameType>("operator=");
2841 }
2842 return nullptr;
2843 case 'c':
2844 switch (look(1)) {
2845 case 'l':
2846 First += 2;
2847 return make<NameType>("operator()");
2848 case 'm':
2849 First += 2;
2850 return make<NameType>("operator,");
2851 case 'o':
2852 First += 2;
2853 return make<NameType>("operator~");
2854 // ::= cv <type> # (cast)
2855 case 'v': {
2856 First += 2;
2857 SwapAndRestore<bool> SaveTemplate(TryToParseTemplateArgs, false);
2858 // If we're parsing an encoding, State != nullptr and the conversion 3070 // If we're parsing an encoding, State != nullptr and the conversion
2859 // operators' <type> could have a <template-param> that refers to some 3071 // operators' <type> could have a <template-param> that refers to some
2860 // <template-arg>s further ahead in the mangled name. 3072 // <template-arg>s further ahead in the mangled name.
2861 SwapAndRestore<bool> SavePermit(PermitForwardTemplateReferences, 3073 ScopedOverride<bool> SavePermit(PermitForwardTemplateReferences,
2862 PermitForwardTemplateReferences || 3074 PermitForwardTemplateReferences ||
2863 State != nullptr); 3075 State != nullptr);
2864 Node *Ty = getDerived().parseType(); 3076 Node *Ty = getDerived().parseType();
@@ -2867,185 +3079,29 @@ AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
2867 if (State) State->CtorDtorConversion = true; 3079 if (State) State->CtorDtorConversion = true;
2868 return make<ConversionOperatorType>(Ty); 3080 return make<ConversionOperatorType>(Ty);
2869 } 3081 }
2870 } 3082
2871 return nullptr; 3083 if (Op->getKind() >= OperatorInfo::Unnameable)
2872 case 'd': 3084 /* Not a nameable operator. */
2873 switch (look(1)) { 3085 return nullptr;
2874 case 'a': 3086 if (Op->getKind() == OperatorInfo::Member && !Op->getFlag())
2875 First += 2; 3087 /* Not a nameable MemberExpr */
2876 return make<NameType>("operator delete[]"); 3088 return nullptr;
2877 case 'e': 3089
2878 First += 2; 3090 return make<NameType>(Op->getName());
2879 return make<NameType>("operator*"); 3091 }
2880 case 'l': 3092
2881 First += 2; 3093 if (consumeIf("li")) {
2882 return make<NameType>("operator delete");
2883 case 'v':
2884 First += 2;
2885 return make<NameType>("operator/");
2886 case 'V':
2887 First += 2;
2888 return make<NameType>("operator/=");
2889 }
2890 return nullptr;
2891 case 'e':
2892 switch (look(1)) {
2893 case 'o':
2894 First += 2;
2895 return make<NameType>("operator^");
2896 case 'O':
2897 First += 2;
2898 return make<NameType>("operator^=");
2899 case 'q':
2900 First += 2;
2901 return make<NameType>("operator==");
2902 }
2903 return nullptr;
2904 case 'g':
2905 switch (look(1)) {
2906 case 'e':
2907 First += 2;
2908 return make<NameType>("operator>=");
2909 case 't':
2910 First += 2;
2911 return make<NameType>("operator>");
2912 }
2913 return nullptr;
2914 case 'i':
2915 if (look(1) == 'x') {
2916 First += 2;
2917 return make<NameType>("operator[]");
2918 }
2919 return nullptr;
2920 case 'l':
2921 switch (look(1)) {
2922 case 'e':
2923 First += 2;
2924 return make<NameType>("operator<=");
2925 // ::= li <source-name> # operator "" 3094 // ::= li <source-name> # operator ""
2926 case 'i': { 3095 Node *SN = getDerived().parseSourceName(State);
2927 First += 2; 3096 if (SN == nullptr)
2928 Node *SN = getDerived().parseSourceName(State); 3097 return nullptr;
2929 if (SN == nullptr) 3098 return make<LiteralOperator>(SN);
2930 return nullptr; 3099 }
2931 return make<LiteralOperator>(SN); 3100
2932 } 3101 if (consumeIf('v')) {
2933 case 's': 3102 // ::= v <digit> <source-name> # vendor extended operator
2934 First += 2; 3103 if (look() >= '0' && look() <= '9') {
2935 return make<NameType>("operator<<"); 3104 First++;
2936 case 'S':
2937 First += 2;
2938 return make<NameType>("operator<<=");
2939 case 't':
2940 First += 2;
2941 return make<NameType>("operator<");
2942 }
2943 return nullptr;
2944 case 'm':
2945 switch (look(1)) {
2946 case 'i':
2947 First += 2;
2948 return make<NameType>("operator-");
2949 case 'I':
2950 First += 2;
2951 return make<NameType>("operator-=");
2952 case 'l':
2953 First += 2;
2954 return make<NameType>("operator*");
2955 case 'L':
2956 First += 2;
2957 return make<NameType>("operator*=");
2958 case 'm':
2959 First += 2;
2960 return make<NameType>("operator--");
2961 }
2962 return nullptr;
2963 case 'n':
2964 switch (look(1)) {
2965 case 'a':
2966 First += 2;
2967 return make<NameType>("operator new[]");
2968 case 'e':
2969 First += 2;
2970 return make<NameType>("operator!=");
2971 case 'g':
2972 First += 2;
2973 return make<NameType>("operator-");
2974 case 't':
2975 First += 2;
2976 return make<NameType>("operator!");
2977 case 'w':
2978 First += 2;
2979 return make<NameType>("operator new");
2980 }
2981 return nullptr;
2982 case 'o':
2983 switch (look(1)) {
2984 case 'o':
2985 First += 2;
2986 return make<NameType>("operator||");
2987 case 'r':
2988 First += 2;
2989 return make<NameType>("operator|");
2990 case 'R':
2991 First += 2;
2992 return make<NameType>("operator|=");
2993 }
2994 return nullptr;
2995 case 'p':
2996 switch (look(1)) {
2997 case 'm':
2998 First += 2;
2999 return make<NameType>("operator->*");
3000 case 'l':
3001 First += 2;
3002 return make<NameType>("operator+");
3003 case 'L':
3004 First += 2;
3005 return make<NameType>("operator+=");
3006 case 'p':
3007 First += 2;
3008 return make<NameType>("operator++");
3009 case 's':
3010 First += 2;
3011 return make<NameType>("operator+");
3012 case 't':
3013 First += 2;
3014 return make<NameType>("operator->");
3015 }
3016 return nullptr;
3017 case 'q':
3018 if (look(1) == 'u') {
3019 First += 2;
3020 return make<NameType>("operator?");
3021 }
3022 return nullptr;
3023 case 'r':
3024 switch (look(1)) {
3025 case 'm':
3026 First += 2;
3027 return make<NameType>("operator%");
3028 case 'M':
3029 First += 2;
3030 return make<NameType>("operator%=");
3031 case 's':
3032 First += 2;
3033 return make<NameType>("operator>>");
3034 case 'S':
3035 First += 2;
3036 return make<NameType>("operator>>=");
3037 }
3038 return nullptr;
3039 case 's':
3040 if (look(1) == 's') {
3041 First += 2;
3042 return make<NameType>("operator<=>");
3043 }
3044 return nullptr;
3045 // ::= v <digit> <source-name> # vendor extended operator
3046 case 'v':
3047 if (std::isdigit(look(1))) {
3048 First += 2;
3049 Node *SN = getDerived().parseSourceName(State); 3105 Node *SN = getDerived().parseSourceName(State);
3050 if (SN == nullptr) 3106 if (SN == nullptr)
3051 return nullptr; 3107 return nullptr;
@@ -3053,6 +3109,7 @@ AbstractManglingParser<Derived, Alloc>::parseOperatorName(NameState *State) {
3053 } 3109 }
3054 return nullptr; 3110 return nullptr;
3055 } 3111 }
3112
3056 return nullptr; 3113 return nullptr;
3057} 3114}
3058 3115
@@ -3071,19 +3128,11 @@ Node *
3071AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar, 3128AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3072 NameState *State) { 3129 NameState *State) {
3073 if (SoFar->getKind() == Node::KSpecialSubstitution) { 3130 if (SoFar->getKind() == Node::KSpecialSubstitution) {
3074 auto SSK = static_cast<SpecialSubstitution *>(SoFar)->SSK; 3131 // Expand the special substitution.
3075 switch (SSK) { 3132 SoFar = make<ExpandedSpecialSubstitution>(
3076 case SpecialSubKind::string: 3133 static_cast<SpecialSubstitution *>(SoFar));
3077 case SpecialSubKind::istream: 3134 if (!SoFar)
3078 case SpecialSubKind::ostream: 3135 return nullptr;
3079 case SpecialSubKind::iostream:
3080 SoFar = make<ExpandedSpecialSubstitution>(SSK);
3081 if (!SoFar)
3082 return nullptr;
3083 break;
3084 default:
3085 break;
3086 }
3087 } 3136 }
3088 3137
3089 if (consumeIf('C')) { 3138 if (consumeIf('C')) {
@@ -3112,8 +3161,10 @@ AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3112 return nullptr; 3161 return nullptr;
3113} 3162}
3114 3163
3115// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E 3164// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix>
3116// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E 3165// <unqualified-name> E
3166// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix>
3167// <template-args> E
3117// 3168//
3118// <prefix> ::= <prefix> <unqualified-name> 3169// <prefix> ::= <prefix> <unqualified-name>
3119// ::= <template-prefix> <template-args> 3170// ::= <template-prefix> <template-args>
@@ -3122,7 +3173,7 @@ AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
3122// ::= # empty 3173// ::= # empty
3123// ::= <substitution> 3174// ::= <substitution>
3124// ::= <prefix> <data-member-prefix> 3175// ::= <prefix> <data-member-prefix>
3125// extension ::= L 3176// [*] extension
3126// 3177//
3127// <data-member-prefix> := <member source-name> [<template-args>] M 3178// <data-member-prefix> := <member source-name> [<template-args>] M
3128// 3179//
@@ -3142,90 +3193,76 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
3142 if (State) State->ReferenceQualifier = FrefQualRValue; 3193 if (State) State->ReferenceQualifier = FrefQualRValue;
3143 } else if (consumeIf('R')) { 3194 } else if (consumeIf('R')) {
3144 if (State) State->ReferenceQualifier = FrefQualLValue; 3195 if (State) State->ReferenceQualifier = FrefQualLValue;
3145 } else 3196 } else {
3146 if (State) State->ReferenceQualifier = FrefQualNone; 3197 if (State) State->ReferenceQualifier = FrefQualNone;
3147
3148 Node *SoFar = nullptr;
3149 auto PushComponent = [&](Node *Comp) {
3150 if (!Comp) return false;
3151 if (SoFar) SoFar = make<NestedName>(SoFar, Comp);
3152 else SoFar = Comp;
3153 if (State) State->EndsWithTemplateArgs = false;
3154 return SoFar != nullptr;
3155 };
3156
3157 if (consumeIf("St")) {
3158 SoFar = make<NameType>("std");
3159 if (!SoFar)
3160 return nullptr;
3161 } 3198 }
3162 3199
3200 Node *SoFar = nullptr;
3163 while (!consumeIf('E')) { 3201 while (!consumeIf('E')) {
3164 consumeIf('L'); // extension 3202 if (State)
3203 // Only set end-with-template on the case that does that.
3204 State->EndsWithTemplateArgs = false;
3165 3205
3166 // <data-member-prefix> := <member source-name> [<template-args>] M
3167 if (consumeIf('M')) {
3168 if (SoFar == nullptr)
3169 return nullptr;
3170 continue;
3171 }
3172
3173 // ::= <template-param>
3174 if (look() == 'T') { 3206 if (look() == 'T') {
3175 if (!PushComponent(getDerived().parseTemplateParam())) 3207 // ::= <template-param>
3176 return nullptr; 3208 if (SoFar != nullptr)
3177 Subs.push_back(SoFar); 3209 return nullptr; // Cannot have a prefix.
3178 continue; 3210 SoFar = getDerived().parseTemplateParam();
3179 } 3211 } else if (look() == 'I') {
3180 3212 // ::= <template-prefix> <template-args>
3181 // ::= <template-prefix> <template-args> 3213 if (SoFar == nullptr)
3182 if (look() == 'I') { 3214 return nullptr; // Must have a prefix.
3183 Node *TA = getDerived().parseTemplateArgs(State != nullptr); 3215 Node *TA = getDerived().parseTemplateArgs(State != nullptr);
3184 if (TA == nullptr || SoFar == nullptr) 3216 if (TA == nullptr)
3185 return nullptr;
3186 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3187 if (!SoFar)
3188 return nullptr;
3189 if (State) State->EndsWithTemplateArgs = true;
3190 Subs.push_back(SoFar);
3191 continue;
3192 }
3193
3194 // ::= <decltype>
3195 if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
3196 if (!PushComponent(getDerived().parseDecltype()))
3197 return nullptr; 3217 return nullptr;
3198 Subs.push_back(SoFar); 3218 if (SoFar->getKind() == Node::KNameWithTemplateArgs)
3199 continue; 3219 // Semantically <template-args> <template-args> cannot be generated by a
3200 } 3220 // C++ entity. There will always be [something like] a name between
3201 3221 // them.
3202 // ::= <substitution>
3203 if (look() == 'S' && look(1) != 't') {
3204 Node *S = getDerived().parseSubstitution();
3205 if (!PushComponent(S))
3206 return nullptr; 3222 return nullptr;
3207 if (SoFar != S) 3223 if (State)
3208 Subs.push_back(S); 3224 State->EndsWithTemplateArgs = true;
3209 continue; 3225 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3210 } 3226 } else if (look() == 'D' && (look(1) == 't' || look(1) == 'T')) {
3227 // ::= <decltype>
3228 if (SoFar != nullptr)
3229 return nullptr; // Cannot have a prefix.
3230 SoFar = getDerived().parseDecltype();
3231 } else {
3232 ModuleName *Module = nullptr;
3233
3234 if (look() == 'S') {
3235 // ::= <substitution>
3236 Node *S = nullptr;
3237 if (look(1) == 't') {
3238 First += 2;
3239 S = make<NameType>("std");
3240 } else {
3241 S = getDerived().parseSubstitution();
3242 }
3243 if (!S)
3244 return nullptr;
3245 if (S->getKind() == Node::KModuleName) {
3246 Module = static_cast<ModuleName *>(S);
3247 } else if (SoFar != nullptr) {
3248 return nullptr; // Cannot have a prefix.
3249 } else {
3250 SoFar = S;
3251 continue; // Do not push a new substitution.
3252 }
3253 }
3211 3254
3212 // Parse an <unqualified-name> thats actually a <ctor-dtor-name>. 3255 // ::= [<prefix>] <unqualified-name>
3213 if (look() == 'C' || (look() == 'D' && look(1) != 'C')) { 3256 SoFar = getDerived().parseUnqualifiedName(State, SoFar, Module);
3214 if (SoFar == nullptr)
3215 return nullptr;
3216 if (!PushComponent(getDerived().parseCtorDtorName(SoFar, State)))
3217 return nullptr;
3218 SoFar = getDerived().parseAbiTags(SoFar);
3219 if (SoFar == nullptr)
3220 return nullptr;
3221 Subs.push_back(SoFar);
3222 continue;
3223 } 3257 }
3224 3258
3225 // ::= <prefix> <unqualified-name> 3259 if (SoFar == nullptr)
3226 if (!PushComponent(getDerived().parseUnqualifiedName(State)))
3227 return nullptr; 3260 return nullptr;
3228 Subs.push_back(SoFar); 3261 Subs.push_back(SoFar);
3262
3263 // No longer used.
3264 // <data-member-prefix> := <member source-name> [<template-args>] M
3265 consumeIf('M');
3229 } 3266 }
3230 3267
3231 if (SoFar == nullptr || Subs.empty()) 3268 if (SoFar == nullptr || Subs.empty())
@@ -3320,6 +3357,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3320// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x 3357// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
3321// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name> 3358// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
3322// # A::x, N::y, A<T>::z; "gs" means leading "::" 3359// # A::x, N::y, A<T>::z; "gs" means leading "::"
3360// [gs] has been parsed by caller.
3323// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x 3361// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
3324// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name> 3362// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
3325// # T::N::x /decltype(p)::N::x 3363// # T::N::x /decltype(p)::N::x
@@ -3327,7 +3365,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseBaseUnresolvedName() {
3327// 3365//
3328// <unresolved-qualifier-level> ::= <simple-id> 3366// <unresolved-qualifier-level> ::= <simple-id>
3329template <typename Derived, typename Alloc> 3367template <typename Derived, typename Alloc>
3330Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName() { 3368Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName(bool Global) {
3331 Node *SoFar = nullptr; 3369 Node *SoFar = nullptr;
3332 3370
3333 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name> 3371 // srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
@@ -3361,8 +3399,6 @@ Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName() {
3361 return make<QualifiedName>(SoFar, Base); 3399 return make<QualifiedName>(SoFar, Base);
3362 } 3400 }
3363 3401
3364 bool Global = consumeIf("gs");
3365
3366 // [gs] <base-unresolved-name> # x or (with "gs") ::x 3402 // [gs] <base-unresolved-name> # x or (with "gs") ::x
3367 if (!consumeIf("sr")) { 3403 if (!consumeIf("sr")) {
3368 SoFar = getDerived().parseBaseUnresolvedName(); 3404 SoFar = getDerived().parseBaseUnresolvedName();
@@ -3419,7 +3455,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseUnresolvedName() {
3419template <typename Derived, typename Alloc> 3455template <typename Derived, typename Alloc>
3420Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) { 3456Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3421 while (consumeIf('B')) { 3457 while (consumeIf('B')) {
3422 StringView SN = parseBareSourceName(); 3458 std::string_view SN = parseBareSourceName();
3423 if (SN.empty()) 3459 if (SN.empty())
3424 return nullptr; 3460 return nullptr;
3425 N = make<AbiTagAttr>(N, SN); 3461 N = make<AbiTagAttr>(N, SN);
@@ -3431,16 +3467,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseAbiTags(Node *N) {
3431 3467
3432// <number> ::= [n] <non-negative decimal integer> 3468// <number> ::= [n] <non-negative decimal integer>
3433template <typename Alloc, typename Derived> 3469template <typename Alloc, typename Derived>
3434StringView 3470std::string_view
3435AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) { 3471AbstractManglingParser<Alloc, Derived>::parseNumber(bool AllowNegative) {
3436 const char *Tmp = First; 3472 const char *Tmp = First;
3437 if (AllowNegative) 3473 if (AllowNegative)
3438 consumeIf('n'); 3474 consumeIf('n');
3439 if (numLeft() == 0 || !std::isdigit(*First)) 3475 if (numLeft() == 0 || !std::isdigit(*First))
3440 return StringView(); 3476 return std::string_view();
3441 while (numLeft() != 0 && std::isdigit(*First)) 3477 while (numLeft() != 0 && std::isdigit(*First))
3442 ++First; 3478 ++First;
3443 return StringView(Tmp, First); 3479 return std::string_view(Tmp, First - Tmp);
3444} 3480}
3445 3481
3446// <positive length number> ::= [0-9]* 3482// <positive length number> ::= [0-9]*
@@ -3457,11 +3493,11 @@ bool AbstractManglingParser<Alloc, Derived>::parsePositiveInteger(size_t *Out) {
3457} 3493}
3458 3494
3459template <typename Alloc, typename Derived> 3495template <typename Alloc, typename Derived>
3460StringView AbstractManglingParser<Alloc, Derived>::parseBareSourceName() { 3496std::string_view AbstractManglingParser<Alloc, Derived>::parseBareSourceName() {
3461 size_t Int = 0; 3497 size_t Int = 0;
3462 if (parsePositiveInteger(&Int) || numLeft() < Int) 3498 if (parsePositiveInteger(&Int) || numLeft() < Int)
3463 return StringView(); 3499 return {};
3464 StringView R(First, First + Int); 3500 std::string_view R(First, Int);
3465 First += Int; 3501 First += Int;
3466 return R; 3502 return R;
3467} 3503}
@@ -3549,7 +3585,9 @@ Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
3549 if (!consumeIf("Dv")) 3585 if (!consumeIf("Dv"))
3550 return nullptr; 3586 return nullptr;
3551 if (look() >= '1' && look() <= '9') { 3587 if (look() >= '1' && look() <= '9') {
3552 StringView DimensionNumber = parseNumber(); 3588 Node *DimensionNumber = make<NameType>(parseNumber());
3589 if (!DimensionNumber)
3590 return nullptr;
3553 if (!consumeIf('_')) 3591 if (!consumeIf('_'))
3554 return nullptr; 3592 return nullptr;
3555 if (consumeIf('p')) 3593 if (consumeIf('p'))
@@ -3574,7 +3612,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseVectorType() {
3574 Node *ElemType = getDerived().parseType(); 3612 Node *ElemType = getDerived().parseType();
3575 if (!ElemType) 3613 if (!ElemType)
3576 return nullptr; 3614 return nullptr;
3577 return make<VectorType>(ElemType, StringView()); 3615 return make<VectorType>(ElemType, /*Dimension=*/nullptr);
3578} 3616}
3579 3617
3580// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x) 3618// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
@@ -3590,7 +3628,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseDecltype() {
3590 return nullptr; 3628 return nullptr;
3591 if (!consumeIf('E')) 3629 if (!consumeIf('E'))
3592 return nullptr; 3630 return nullptr;
3593 return make<EnclosingExpr>("decltype(", E, ")"); 3631 return make<EnclosingExpr>("decltype", E);
3594} 3632}
3595 3633
3596// <array-type> ::= A <positive dimension number> _ <element type> 3634// <array-type> ::= A <positive dimension number> _ <element type>
@@ -3600,10 +3638,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseArrayType() {
3600 if (!consumeIf('A')) 3638 if (!consumeIf('A'))
3601 return nullptr; 3639 return nullptr;
3602 3640
3603 NodeOrString Dimension; 3641 Node *Dimension = nullptr;
3604 3642
3605 if (std::isdigit(look())) { 3643 if (std::isdigit(look())) {
3606 Dimension = parseNumber(); 3644 Dimension = make<NameType>(parseNumber());
3645 if (!Dimension)
3646 return nullptr;
3607 if (!consumeIf('_')) 3647 if (!consumeIf('_'))
3608 return nullptr; 3648 return nullptr;
3609 } else if (!consumeIf('_')) { 3649 } else if (!consumeIf('_')) {
@@ -3641,7 +3681,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parsePointerToMemberType() {
3641// ::= Te <name> # dependent elaborated type specifier using 'enum' 3681// ::= Te <name> # dependent elaborated type specifier using 'enum'
3642template <typename Derived, typename Alloc> 3682template <typename Derived, typename Alloc>
3643Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() { 3683Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
3644 StringView ElabSpef; 3684 std::string_view ElabSpef;
3645 if (consumeIf("Ts")) 3685 if (consumeIf("Ts"))
3646 ElabSpef = "struct"; 3686 ElabSpef = "struct";
3647 else if (consumeIf("Tu")) 3687 else if (consumeIf("Tu"))
@@ -3665,19 +3705,18 @@ Node *AbstractManglingParser<Derived, Alloc>::parseClassEnumType() {
3665template <typename Derived, typename Alloc> 3705template <typename Derived, typename Alloc>
3666Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() { 3706Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
3667 if (consumeIf('U')) { 3707 if (consumeIf('U')) {
3668 StringView Qual = parseBareSourceName(); 3708 std::string_view Qual = parseBareSourceName();
3669 if (Qual.empty()) 3709 if (Qual.empty())
3670 return nullptr; 3710 return nullptr;
3671 3711
3672 // FIXME parse the optional <template-args> here!
3673
3674 // extension ::= U <objc-name> <objc-type> # objc-type<identifier> 3712 // extension ::= U <objc-name> <objc-type> # objc-type<identifier>
3675 if (Qual.startsWith("objcproto")) { 3713 if (llvm::itanium_demangle::starts_with(Qual, "objcproto")) {
3676 StringView ProtoSourceName = Qual.dropFront(std::strlen("objcproto")); 3714 constexpr size_t Len = sizeof("objcproto") - 1;
3677 StringView Proto; 3715 std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
3716 std::string_view Proto;
3678 { 3717 {
3679 SwapAndRestore<const char *> SaveFirst(First, ProtoSourceName.begin()), 3718 ScopedOverride<const char *> SaveFirst(First, ProtoSourceName.data()),
3680 SaveLast(Last, ProtoSourceName.end()); 3719 SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
3681 Proto = parseBareSourceName(); 3720 Proto = parseBareSourceName();
3682 } 3721 }
3683 if (Proto.empty()) 3722 if (Proto.empty())
@@ -3688,10 +3727,17 @@ Node *AbstractManglingParser<Derived, Alloc>::parseQualifiedType() {
3688 return make<ObjCProtoName>(Child, Proto); 3727 return make<ObjCProtoName>(Child, Proto);
3689 } 3728 }
3690 3729
3730 Node *TA = nullptr;
3731 if (look() == 'I') {
3732 TA = getDerived().parseTemplateArgs();
3733 if (TA == nullptr)
3734 return nullptr;
3735 }
3736
3691 Node *Child = getDerived().parseQualifiedType(); 3737 Node *Child = getDerived().parseQualifiedType();
3692 if (Child == nullptr) 3738 if (Child == nullptr)
3693 return nullptr; 3739 return nullptr;
3694 return make<VendorExtQualType>(Child, Qual); 3740 return make<VendorExtQualType>(Child, Qual, TA);
3695 } 3741 }
3696 3742
3697 Qualifiers Quals = parseCVQualifiers(); 3743 Qualifiers Quals = parseCVQualifiers();
@@ -3838,7 +3884,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
3838 // <builtin-type> ::= u <source-name> # vendor extended type 3884 // <builtin-type> ::= u <source-name> # vendor extended type
3839 case 'u': { 3885 case 'u': {
3840 ++First; 3886 ++First;
3841 StringView Res = parseBareSourceName(); 3887 std::string_view Res = parseBareSourceName();
3842 if (Res.empty()) 3888 if (Res.empty())
3843 return nullptr; 3889 return nullptr;
3844 // Typically, <builtin-type>s are not considered substitution candidates, 3890 // Typically, <builtin-type>s are not considered substitution candidates,
@@ -3864,7 +3910,33 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
3864 // ::= Dh # IEEE 754r half-precision floating point (16 bits) 3910 // ::= Dh # IEEE 754r half-precision floating point (16 bits)
3865 case 'h': 3911 case 'h':
3866 First += 2; 3912 First += 2;
3867 return make<NameType>("decimal16"); 3913 return make<NameType>("half");
3914 // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point (N bits)
3915 case 'F': {
3916 First += 2;
3917 Node *DimensionNumber = make<NameType>(parseNumber());
3918 if (!DimensionNumber)
3919 return nullptr;
3920 if (!consumeIf('_'))
3921 return nullptr;
3922 return make<BinaryFPType>(DimensionNumber);
3923 }
3924 // ::= DB <number> _ # C23 signed _BitInt(N)
3925 // ::= DB <instantiation-dependent expression> _ # C23 signed _BitInt(N)
3926 // ::= DU <number> _ # C23 unsigned _BitInt(N)
3927 // ::= DU <instantiation-dependent expression> _ # C23 unsigned _BitInt(N)
3928 case 'B':
3929 case 'U': {
3930 bool Signed = look(1) == 'B';
3931 First += 2;
3932 Node *Size = std::isdigit(look()) ? make<NameType>(parseNumber())
3933 : getDerived().parseExpr();
3934 if (!Size)
3935 return nullptr;
3936 if (!consumeIf('_'))
3937 return nullptr;
3938 return make<BitIntType>(Size, Signed);
3939 }
3868 // ::= Di # char32_t 3940 // ::= Di # char32_t
3869 case 'i': 3941 case 'i':
3870 First += 2; 3942 First += 2;
@@ -4012,9 +4084,10 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4012 } 4084 }
4013 // ::= <substitution> # See Compression below 4085 // ::= <substitution> # See Compression below
4014 case 'S': { 4086 case 'S': {
4015 if (look(1) && look(1) != 't') { 4087 if (look(1) != 't') {
4016 Node *Sub = getDerived().parseSubstitution(); 4088 bool IsSubst = false;
4017 if (Sub == nullptr) 4089 Result = getDerived().parseUnscopedName(nullptr, &IsSubst);
4090 if (!Result)
4018 return nullptr; 4091 return nullptr;
4019 4092
4020 // Sub could be either of: 4093 // Sub could be either of:
@@ -4027,17 +4100,19 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4027 // If this is followed by some <template-args>, and we're permitted to 4100 // If this is followed by some <template-args>, and we're permitted to
4028 // parse them, take the second production. 4101 // parse them, take the second production.
4029 4102
4030 if (TryToParseTemplateArgs && look() == 'I') { 4103 if (look() == 'I' && (!IsSubst || TryToParseTemplateArgs)) {
4104 if (!IsSubst)
4105 Subs.push_back(Result);
4031 Node *TA = getDerived().parseTemplateArgs(); 4106 Node *TA = getDerived().parseTemplateArgs();
4032 if (TA == nullptr) 4107 if (TA == nullptr)
4033 return nullptr; 4108 return nullptr;
4034 Result = make<NameWithTemplateArgs>(Sub, TA); 4109 Result = make<NameWithTemplateArgs>(Result, TA);
4035 break; 4110 } else if (IsSubst) {
4111 // If all we parsed was a substitution, don't re-insert into the
4112 // substitution table.
4113 return Result;
4036 } 4114 }
4037 4115 break;
4038 // If all we parsed was a substitution, don't re-insert into the
4039 // substitution table.
4040 return Sub;
4041 } 4116 }
4042 DEMANGLE_FALLTHROUGH; 4117 DEMANGLE_FALLTHROUGH;
4043 } 4118 }
@@ -4057,28 +4132,32 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
4057} 4132}
4058 4133
4059template <typename Derived, typename Alloc> 4134template <typename Derived, typename Alloc>
4060Node *AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(StringView Kind) { 4135Node *
4136AbstractManglingParser<Derived, Alloc>::parsePrefixExpr(std::string_view Kind,
4137 Node::Prec Prec) {
4061 Node *E = getDerived().parseExpr(); 4138 Node *E = getDerived().parseExpr();
4062 if (E == nullptr) 4139 if (E == nullptr)
4063 return nullptr; 4140 return nullptr;
4064 return make<PrefixExpr>(Kind, E); 4141 return make<PrefixExpr>(Kind, E, Prec);
4065} 4142}
4066 4143
4067template <typename Derived, typename Alloc> 4144template <typename Derived, typename Alloc>
4068Node *AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(StringView Kind) { 4145Node *
4146AbstractManglingParser<Derived, Alloc>::parseBinaryExpr(std::string_view Kind,
4147 Node::Prec Prec) {
4069 Node *LHS = getDerived().parseExpr(); 4148 Node *LHS = getDerived().parseExpr();
4070 if (LHS == nullptr) 4149 if (LHS == nullptr)
4071 return nullptr; 4150 return nullptr;
4072 Node *RHS = getDerived().parseExpr(); 4151 Node *RHS = getDerived().parseExpr();
4073 if (RHS == nullptr) 4152 if (RHS == nullptr)
4074 return nullptr; 4153 return nullptr;
4075 return make<BinaryExpr>(LHS, Kind, RHS); 4154 return make<BinaryExpr>(LHS, Kind, RHS, Prec);
4076} 4155}
4077 4156
4078template <typename Derived, typename Alloc> 4157template <typename Derived, typename Alloc>
4079Node * 4158Node *AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(
4080AbstractManglingParser<Derived, Alloc>::parseIntegerLiteral(StringView Lit) { 4159 std::string_view Lit) {
4081 StringView Tmp = parseNumber(true); 4160 std::string_view Tmp = parseNumber(true);
4082 if (!Tmp.empty() && consumeIf('E')) 4161 if (!Tmp.empty() && consumeIf('E'))
4083 return make<IntegerLiteral>(Lit, Tmp); 4162 return make<IntegerLiteral>(Lit, Tmp);
4084 return nullptr; 4163 return nullptr;
@@ -4101,11 +4180,14 @@ Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
4101// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters 4180// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
4102// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter 4181// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
4103// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters 4182// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
4183// ::= fpT # 'this' expression (not part of standard?)
4104template <typename Derived, typename Alloc> 4184template <typename Derived, typename Alloc>
4105Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() { 4185Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4186 if (consumeIf("fpT"))
4187 return make<NameType>("this");
4106 if (consumeIf("fp")) { 4188 if (consumeIf("fp")) {
4107 parseCVQualifiers(); 4189 parseCVQualifiers();
4108 StringView Num = parseNumber(); 4190 std::string_view Num = parseNumber();
4109 if (!consumeIf('_')) 4191 if (!consumeIf('_'))
4110 return nullptr; 4192 return nullptr;
4111 return make<FunctionParam>(Num); 4193 return make<FunctionParam>(Num);
@@ -4116,7 +4198,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4116 if (!consumeIf('p')) 4198 if (!consumeIf('p'))
4117 return nullptr; 4199 return nullptr;
4118 parseCVQualifiers(); 4200 parseCVQualifiers();
4119 StringView Num = parseNumber(); 4201 std::string_view Num = parseNumber();
4120 if (!consumeIf('_')) 4202 if (!consumeIf('_'))
4121 return nullptr; 4203 return nullptr;
4122 return make<FunctionParam>(Num); 4204 return make<FunctionParam>(Num);
@@ -4124,43 +4206,6 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
4124 return nullptr; 4206 return nullptr;
4125} 4207}
4126 4208
4127// [gs] nw <expression>* _ <type> E # new (expr-list) type
4128// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
4129// [gs] na <expression>* _ <type> E # new[] (expr-list) type
4130// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
4131// <initializer> ::= pi <expression>* E # parenthesized initialization
4132template <typename Derived, typename Alloc>
4133Node *AbstractManglingParser<Derived, Alloc>::parseNewExpr() {
4134 bool Global = consumeIf("gs");
4135 bool IsArray = look(1) == 'a';
4136 if (!consumeIf("nw") && !consumeIf("na"))
4137 return nullptr;
4138 size_t Exprs = Names.size();
4139 while (!consumeIf('_')) {
4140 Node *Ex = getDerived().parseExpr();
4141 if (Ex == nullptr)
4142 return nullptr;
4143 Names.push_back(Ex);
4144 }
4145 NodeArray ExprList = popTrailingNodeArray(Exprs);
4146 Node *Ty = getDerived().parseType();
4147 if (Ty == nullptr)
4148 return Ty;
4149 if (consumeIf("pi")) {
4150 size_t InitsBegin = Names.size();
4151 while (!consumeIf('E')) {
4152 Node *Init = getDerived().parseExpr();
4153 if (Init == nullptr)
4154 return Init;
4155 Names.push_back(Init);
4156 }
4157 NodeArray Inits = popTrailingNodeArray(InitsBegin);
4158 return make<NewExpr>(ExprList, Ty, Inits, Global, IsArray);
4159 } else if (!consumeIf('E'))
4160 return nullptr;
4161 return make<NewExpr>(ExprList, Ty, NodeArray(), Global, IsArray);
4162}
4163
4164// cv <type> <expression> # conversion with one argument 4209// cv <type> <expression> # conversion with one argument
4165// cv <type> _ <expression>* E # conversion with a different number of arguments 4210// cv <type> _ <expression>* E # conversion with a different number of arguments
4166template <typename Derived, typename Alloc> 4211template <typename Derived, typename Alloc>
@@ -4169,7 +4214,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseConversionExpr() {
4169 return nullptr; 4214 return nullptr;
4170 Node *Ty; 4215 Node *Ty;
4171 { 4216 {
4172 SwapAndRestore<bool> SaveTemp(TryToParseTemplateArgs, false); 4217 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4173 Ty = getDerived().parseType(); 4218 Ty = getDerived().parseType();
4174 } 4219 }
4175 4220
@@ -4262,7 +4307,13 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4262 return getDerived().template parseFloatingLiteral<double>(); 4307 return getDerived().template parseFloatingLiteral<double>();
4263 case 'e': 4308 case 'e':
4264 ++First; 4309 ++First;
4310#if defined(__powerpc__) || defined(__s390__)
4311 // Handle cases where long doubles encoded with e have the same size
4312 // and representation as doubles.
4313 return getDerived().template parseFloatingLiteral<double>();
4314#else
4265 return getDerived().template parseFloatingLiteral<long double>(); 4315 return getDerived().template parseFloatingLiteral<long double>();
4316#endif
4266 case '_': 4317 case '_':
4267 if (consumeIf("_Z")) { 4318 if (consumeIf("_Z")) {
4268 Node *R = getDerived().parseEncoding(); 4319 Node *R = getDerived().parseEncoding();
@@ -4280,7 +4331,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4280 return nullptr; 4331 return nullptr;
4281 } 4332 }
4282 case 'D': 4333 case 'D':
4283 if (consumeIf("DnE")) 4334 if (consumeIf("Dn") && (consumeIf('0'), consumeIf('E')))
4284 return make<NameType>("nullptr"); 4335 return make<NameType>("nullptr");
4285 return nullptr; 4336 return nullptr;
4286 case 'T': 4337 case 'T':
@@ -4301,12 +4352,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
4301 Node *T = getDerived().parseType(); 4352 Node *T = getDerived().parseType();
4302 if (T == nullptr) 4353 if (T == nullptr)
4303 return nullptr; 4354 return nullptr;
4304 StringView N = parseNumber(); 4355 std::string_view N = parseNumber(/*AllowNegative=*/true);
4305 if (N.empty()) 4356 if (N.empty())
4306 return nullptr; 4357 return nullptr;
4307 if (!consumeIf('E')) 4358 if (!consumeIf('E'))
4308 return nullptr; 4359 return nullptr;
4309 return make<IntegerCastExpr>(T, N); 4360 return make<EnumLiteral>(T, N);
4310 } 4361 }
4311 } 4362 }
4312} 4363}
@@ -4367,55 +4418,38 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
4367 if (!consumeIf('f')) 4418 if (!consumeIf('f'))
4368 return nullptr; 4419 return nullptr;
4369 4420
4370 char FoldKind = look(); 4421 bool IsLeftFold = false, HasInitializer = false;
4371 bool IsLeftFold, HasInitializer; 4422 switch (look()) {
4372 HasInitializer = FoldKind == 'L' || FoldKind == 'R'; 4423 default:
4373 if (FoldKind == 'l' || FoldKind == 'L')
4374 IsLeftFold = true;
4375 else if (FoldKind == 'r' || FoldKind == 'R')
4376 IsLeftFold = false;
4377 else
4378 return nullptr; 4424 return nullptr;
4425 case 'L':
4426 IsLeftFold = true;
4427 HasInitializer = true;
4428 break;
4429 case 'R':
4430 HasInitializer = true;
4431 break;
4432 case 'l':
4433 IsLeftFold = true;
4434 break;
4435 case 'r':
4436 break;
4437 }
4379 ++First; 4438 ++First;
4380 4439
4381 // FIXME: This map is duplicated in parseOperatorName and parseExpr. 4440 const auto *Op = parseOperatorEncoding();
4382 StringView OperatorName; 4441 if (!Op)
4383 if (consumeIf("aa")) OperatorName = "&&"; 4442 return nullptr;
4384 else if (consumeIf("an")) OperatorName = "&"; 4443 if (!(Op->getKind() == OperatorInfo::Binary
4385 else if (consumeIf("aN")) OperatorName = "&="; 4444 || (Op->getKind() == OperatorInfo::Member
4386 else if (consumeIf("aS")) OperatorName = "="; 4445 && Op->getName().back() == '*')))
4387 else if (consumeIf("cm")) OperatorName = ","; 4446 return nullptr;
4388 else if (consumeIf("ds")) OperatorName = ".*"; 4447
4389 else if (consumeIf("dv")) OperatorName = "/"; 4448 Node *Pack = getDerived().parseExpr();
4390 else if (consumeIf("dV")) OperatorName = "/=";
4391 else if (consumeIf("eo")) OperatorName = "^";
4392 else if (consumeIf("eO")) OperatorName = "^=";
4393 else if (consumeIf("eq")) OperatorName = "==";
4394 else if (consumeIf("ge")) OperatorName = ">=";
4395 else if (consumeIf("gt")) OperatorName = ">";
4396 else if (consumeIf("le")) OperatorName = "<=";
4397 else if (consumeIf("ls")) OperatorName = "<<";
4398 else if (consumeIf("lS")) OperatorName = "<<=";
4399 else if (consumeIf("lt")) OperatorName = "<";
4400 else if (consumeIf("mi")) OperatorName = "-";
4401 else if (consumeIf("mI")) OperatorName = "-=";
4402 else if (consumeIf("ml")) OperatorName = "*";
4403 else if (consumeIf("mL")) OperatorName = "*=";
4404 else if (consumeIf("ne")) OperatorName = "!=";
4405 else if (consumeIf("oo")) OperatorName = "||";
4406 else if (consumeIf("or")) OperatorName = "|";
4407 else if (consumeIf("oR")) OperatorName = "|=";
4408 else if (consumeIf("pl")) OperatorName = "+";
4409 else if (consumeIf("pL")) OperatorName = "+=";
4410 else if (consumeIf("rm")) OperatorName = "%";
4411 else if (consumeIf("rM")) OperatorName = "%=";
4412 else if (consumeIf("rs")) OperatorName = ">>";
4413 else if (consumeIf("rS")) OperatorName = ">>=";
4414 else return nullptr;
4415
4416 Node *Pack = getDerived().parseExpr(), *Init = nullptr;
4417 if (Pack == nullptr) 4449 if (Pack == nullptr)
4418 return nullptr; 4450 return nullptr;
4451
4452 Node *Init = nullptr;
4419 if (HasInitializer) { 4453 if (HasInitializer) {
4420 Init = getDerived().parseExpr(); 4454 Init = getDerived().parseExpr();
4421 if (Init == nullptr) 4455 if (Init == nullptr)
@@ -4425,7 +4459,53 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
4425 if (IsLeftFold && Init) 4459 if (IsLeftFold && Init)
4426 std::swap(Pack, Init); 4460 std::swap(Pack, Init);
4427 4461
4428 return make<FoldExpr>(IsLeftFold, OperatorName, Pack, Init); 4462 return make<FoldExpr>(IsLeftFold, Op->getSymbol(), Pack, Init);
4463}
4464
4465// <expression> ::= mc <parameter type> <expr> [<offset number>] E
4466//
4467// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
4468template <typename Derived, typename Alloc>
4469Node *
4470AbstractManglingParser<Derived, Alloc>::parsePointerToMemberConversionExpr(
4471 Node::Prec Prec) {
4472 Node *Ty = getDerived().parseType();
4473 if (!Ty)
4474 return nullptr;
4475 Node *Expr = getDerived().parseExpr();
4476 if (!Expr)
4477 return nullptr;
4478 std::string_view Offset = getDerived().parseNumber(true);
4479 if (!consumeIf('E'))
4480 return nullptr;
4481 return make<PointerToMemberConversionExpr>(Ty, Expr, Offset, Prec);
4482}
4483
4484// <expression> ::= so <referent type> <expr> [<offset number>] <union-selector>* [p] E
4485// <union-selector> ::= _ [<number>]
4486//
4487// Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/47
4488template <typename Derived, typename Alloc>
4489Node *AbstractManglingParser<Derived, Alloc>::parseSubobjectExpr() {
4490 Node *Ty = getDerived().parseType();
4491 if (!Ty)
4492 return nullptr;
4493 Node *Expr = getDerived().parseExpr();
4494 if (!Expr)
4495 return nullptr;
4496 std::string_view Offset = getDerived().parseNumber(true);
4497 size_t SelectorsBegin = Names.size();
4498 while (consumeIf('_')) {
4499 Node *Selector = make<NameType>(parseNumber());
4500 if (!Selector)
4501 return nullptr;
4502 Names.push_back(Selector);
4503 }
4504 bool OnePastTheEnd = consumeIf('p');
4505 if (!consumeIf('E'))
4506 return nullptr;
4507 return make<SubobjectExpr>(
4508 Ty, Expr, Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
4429} 4509}
4430 4510
4431// <expression> ::= <unary operator-name> <expression> 4511// <expression> ::= <unary operator-name> <expression>
@@ -4475,313 +4555,127 @@ Node *AbstractManglingParser<Derived, Alloc>::parseFoldExpr() {
4475template <typename Derived, typename Alloc> 4555template <typename Derived, typename Alloc>
4476Node *AbstractManglingParser<Derived, Alloc>::parseExpr() { 4556Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
4477 bool Global = consumeIf("gs"); 4557 bool Global = consumeIf("gs");
4478 if (numLeft() < 2)
4479 return nullptr;
4480 4558
4481 switch (*First) { 4559 const auto *Op = parseOperatorEncoding();
4482 case 'L': 4560 if (Op) {
4483 return getDerived().parseExprPrimary(); 4561 auto Sym = Op->getSymbol();
4484 case 'T': 4562 switch (Op->getKind()) {
4485 return getDerived().parseTemplateParam(); 4563 case OperatorInfo::Binary:
4486 case 'f': { 4564 // Binary operator: lhs @ rhs
4487 // Disambiguate a fold expression from a <function-param>. 4565 return getDerived().parseBinaryExpr(Sym, Op->getPrecedence());
4488 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2)))) 4566 case OperatorInfo::Prefix:
4489 return getDerived().parseFunctionParam(); 4567 // Prefix unary operator: @ expr
4490 return getDerived().parseFoldExpr(); 4568 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
4491 } 4569 case OperatorInfo::Postfix: {
4492 case 'a': 4570 // Postfix unary operator: expr @
4493 switch (First[1]) { 4571 if (consumeIf('_'))
4494 case 'a': 4572 return getDerived().parsePrefixExpr(Sym, Op->getPrecedence());
4495 First += 2;
4496 return getDerived().parseBinaryExpr("&&");
4497 case 'd':
4498 First += 2;
4499 return getDerived().parsePrefixExpr("&");
4500 case 'n':
4501 First += 2;
4502 return getDerived().parseBinaryExpr("&");
4503 case 'N':
4504 First += 2;
4505 return getDerived().parseBinaryExpr("&=");
4506 case 'S':
4507 First += 2;
4508 return getDerived().parseBinaryExpr("=");
4509 case 't': {
4510 First += 2;
4511 Node *Ty = getDerived().parseType();
4512 if (Ty == nullptr)
4513 return nullptr;
4514 return make<EnclosingExpr>("alignof (", Ty, ")");
4515 }
4516 case 'z': {
4517 First += 2;
4518 Node *Ty = getDerived().parseExpr();
4519 if (Ty == nullptr)
4520 return nullptr;
4521 return make<EnclosingExpr>("alignof (", Ty, ")");
4522 }
4523 }
4524 return nullptr;
4525 case 'c':
4526 switch (First[1]) {
4527 // cc <type> <expression> # const_cast<type>(expression)
4528 case 'c': {
4529 First += 2;
4530 Node *Ty = getDerived().parseType();
4531 if (Ty == nullptr)
4532 return Ty;
4533 Node *Ex = getDerived().parseExpr();
4534 if (Ex == nullptr)
4535 return Ex;
4536 return make<CastExpr>("const_cast", Ty, Ex);
4537 }
4538 // cl <expression>+ E # call
4539 case 'l': {
4540 First += 2;
4541 Node *Callee = getDerived().parseExpr();
4542 if (Callee == nullptr)
4543 return Callee;
4544 size_t ExprsBegin = Names.size();
4545 while (!consumeIf('E')) {
4546 Node *E = getDerived().parseExpr();
4547 if (E == nullptr)
4548 return E;
4549 Names.push_back(E);
4550 }
4551 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin));
4552 }
4553 case 'm':
4554 First += 2;
4555 return getDerived().parseBinaryExpr(",");
4556 case 'o':
4557 First += 2;
4558 return getDerived().parsePrefixExpr("~");
4559 case 'v':
4560 return getDerived().parseConversionExpr();
4561 }
4562 return nullptr;
4563 case 'd':
4564 switch (First[1]) {
4565 case 'a': {
4566 First += 2;
4567 Node *Ex = getDerived().parseExpr();
4568 if (Ex == nullptr)
4569 return Ex;
4570 return make<DeleteExpr>(Ex, Global, /*is_array=*/true);
4571 }
4572 case 'c': {
4573 First += 2;
4574 Node *T = getDerived().parseType();
4575 if (T == nullptr)
4576 return T;
4577 Node *Ex = getDerived().parseExpr(); 4573 Node *Ex = getDerived().parseExpr();
4578 if (Ex == nullptr) 4574 if (Ex == nullptr)
4579 return Ex; 4575 return nullptr;
4580 return make<CastExpr>("dynamic_cast", T, Ex); 4576 return make<PostfixExpr>(Ex, Sym, Op->getPrecedence());
4581 }
4582 case 'e':
4583 First += 2;
4584 return getDerived().parsePrefixExpr("*");
4585 case 'l': {
4586 First += 2;
4587 Node *E = getDerived().parseExpr();
4588 if (E == nullptr)
4589 return E;
4590 return make<DeleteExpr>(E, Global, /*is_array=*/false);
4591 } 4577 }
4592 case 'n': 4578 case OperatorInfo::Array: {
4593 return getDerived().parseUnresolvedName(); 4579 // Array Index: lhs [ rhs ]
4594 case 's': { 4580 Node *Base = getDerived().parseExpr();
4595 First += 2; 4581 if (Base == nullptr)
4596 Node *LHS = getDerived().parseExpr();
4597 if (LHS == nullptr)
4598 return nullptr; 4582 return nullptr;
4599 Node *RHS = getDerived().parseExpr(); 4583 Node *Index = getDerived().parseExpr();
4600 if (RHS == nullptr) 4584 if (Index == nullptr)
4601 return nullptr; 4585 return nullptr;
4602 return make<MemberExpr>(LHS, ".*", RHS); 4586 return make<ArraySubscriptExpr>(Base, Index, Op->getPrecedence());
4603 } 4587 }
4604 case 't': { 4588 case OperatorInfo::Member: {
4605 First += 2; 4589 // Member access lhs @ rhs
4606 Node *LHS = getDerived().parseExpr(); 4590 Node *LHS = getDerived().parseExpr();
4607 if (LHS == nullptr) 4591 if (LHS == nullptr)
4608 return LHS; 4592 return nullptr;
4609 Node *RHS = getDerived().parseExpr(); 4593 Node *RHS = getDerived().parseExpr();
4610 if (RHS == nullptr) 4594 if (RHS == nullptr)
4611 return nullptr; 4595 return nullptr;
4612 return make<MemberExpr>(LHS, ".", RHS); 4596 return make<MemberExpr>(LHS, Sym, RHS, Op->getPrecedence());
4613 } 4597 }
4614 case 'v': 4598 case OperatorInfo::New: {
4615 First += 2; 4599 // New
4616 return getDerived().parseBinaryExpr("/"); 4600 // # new (expr-list) type [(init)]
4617 case 'V': 4601 // [gs] nw <expression>* _ <type> [pi <expression>*] E
4618 First += 2; 4602 // # new[] (expr-list) type [(init)]
4619 return getDerived().parseBinaryExpr("/="); 4603 // [gs] na <expression>* _ <type> [pi <expression>*] E
4620 } 4604 size_t Exprs = Names.size();
4621 return nullptr; 4605 while (!consumeIf('_')) {
4622 case 'e': 4606 Node *Ex = getDerived().parseExpr();
4623 switch (First[1]) { 4607 if (Ex == nullptr)
4624 case 'o': 4608 return nullptr;
4625 First += 2; 4609 Names.push_back(Ex);
4626 return getDerived().parseBinaryExpr("^"); 4610 }
4627 case 'O': 4611 NodeArray ExprList = popTrailingNodeArray(Exprs);
4628 First += 2; 4612 Node *Ty = getDerived().parseType();
4629 return getDerived().parseBinaryExpr("^="); 4613 if (Ty == nullptr)
4630 case 'q':
4631 First += 2;
4632 return getDerived().parseBinaryExpr("==");
4633 }
4634 return nullptr;
4635 case 'g':
4636 switch (First[1]) {
4637 case 'e':
4638 First += 2;
4639 return getDerived().parseBinaryExpr(">=");
4640 case 't':
4641 First += 2;
4642 return getDerived().parseBinaryExpr(">");
4643 }
4644 return nullptr;
4645 case 'i':
4646 switch (First[1]) {
4647 case 'x': {
4648 First += 2;
4649 Node *Base = getDerived().parseExpr();
4650 if (Base == nullptr)
4651 return nullptr; 4614 return nullptr;
4652 Node *Index = getDerived().parseExpr(); 4615 bool HaveInits = consumeIf("pi");
4653 if (Index == nullptr)
4654 return Index;
4655 return make<ArraySubscriptExpr>(Base, Index);
4656 }
4657 case 'l': {
4658 First += 2;
4659 size_t InitsBegin = Names.size(); 4616 size_t InitsBegin = Names.size();
4660 while (!consumeIf('E')) { 4617 while (!consumeIf('E')) {
4661 Node *E = getDerived().parseBracedExpr(); 4618 if (!HaveInits)
4662 if (E == nullptr)
4663 return nullptr; 4619 return nullptr;
4664 Names.push_back(E); 4620 Node *Init = getDerived().parseExpr();
4621 if (Init == nullptr)
4622 return Init;
4623 Names.push_back(Init);
4665 } 4624 }
4666 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin)); 4625 NodeArray Inits = popTrailingNodeArray(InitsBegin);
4667 } 4626 return make<NewExpr>(ExprList, Ty, Inits, Global,
4627 /*IsArray=*/Op->getFlag(), Op->getPrecedence());
4668 } 4628 }
4669 return nullptr; 4629 case OperatorInfo::Del: {
4670 case 'l': 4630 // Delete
4671 switch (First[1]) {
4672 case 'e':
4673 First += 2;
4674 return getDerived().parseBinaryExpr("<=");
4675 case 's':
4676 First += 2;
4677 return getDerived().parseBinaryExpr("<<");
4678 case 'S':
4679 First += 2;
4680 return getDerived().parseBinaryExpr("<<=");
4681 case 't':
4682 First += 2;
4683 return getDerived().parseBinaryExpr("<");
4684 }
4685 return nullptr;
4686 case 'm':
4687 switch (First[1]) {
4688 case 'i':
4689 First += 2;
4690 return getDerived().parseBinaryExpr("-");
4691 case 'I':
4692 First += 2;
4693 return getDerived().parseBinaryExpr("-=");
4694 case 'l':
4695 First += 2;
4696 return getDerived().parseBinaryExpr("*");
4697 case 'L':
4698 First += 2;
4699 return getDerived().parseBinaryExpr("*=");
4700 case 'm':
4701 First += 2;
4702 if (consumeIf('_'))
4703 return getDerived().parsePrefixExpr("--");
4704 Node *Ex = getDerived().parseExpr(); 4631 Node *Ex = getDerived().parseExpr();
4705 if (Ex == nullptr) 4632 if (Ex == nullptr)
4706 return nullptr; 4633 return nullptr;
4707 return make<PostfixExpr>(Ex, "--"); 4634 return make<DeleteExpr>(Ex, Global, /*IsArray=*/Op->getFlag(),
4708 } 4635 Op->getPrecedence());
4709 return nullptr;
4710 case 'n':
4711 switch (First[1]) {
4712 case 'a':
4713 case 'w':
4714 return getDerived().parseNewExpr();
4715 case 'e':
4716 First += 2;
4717 return getDerived().parseBinaryExpr("!=");
4718 case 'g':
4719 First += 2;
4720 return getDerived().parsePrefixExpr("-");
4721 case 't':
4722 First += 2;
4723 return getDerived().parsePrefixExpr("!");
4724 case 'x':
4725 First += 2;
4726 Node *Ex = getDerived().parseExpr();
4727 if (Ex == nullptr)
4728 return Ex;
4729 return make<EnclosingExpr>("noexcept (", Ex, ")");
4730 }
4731 return nullptr;
4732 case 'o':
4733 switch (First[1]) {
4734 case 'n':
4735 return getDerived().parseUnresolvedName();
4736 case 'o':
4737 First += 2;
4738 return getDerived().parseBinaryExpr("||");
4739 case 'r':
4740 First += 2;
4741 return getDerived().parseBinaryExpr("|");
4742 case 'R':
4743 First += 2;
4744 return getDerived().parseBinaryExpr("|=");
4745 } 4636 }
4746 return nullptr; 4637 case OperatorInfo::Call: {
4747 case 'p': 4638 // Function Call
4748 switch (First[1]) { 4639 Node *Callee = getDerived().parseExpr();
4749 case 'm': 4640 if (Callee == nullptr)
4750 First += 2; 4641 return nullptr;
4751 return getDerived().parseBinaryExpr("->*"); 4642 size_t ExprsBegin = Names.size();
4752 case 'l': 4643 while (!consumeIf('E')) {
4753 First += 2; 4644 Node *E = getDerived().parseExpr();
4754 return getDerived().parseBinaryExpr("+"); 4645 if (E == nullptr)
4755 case 'L': 4646 return nullptr;
4756 First += 2; 4647 Names.push_back(E);
4757 return getDerived().parseBinaryExpr("+="); 4648 }
4758 case 'p': { 4649 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
4759 First += 2; 4650 Op->getPrecedence());
4760 if (consumeIf('_'))
4761 return getDerived().parsePrefixExpr("++");
4762 Node *Ex = getDerived().parseExpr();
4763 if (Ex == nullptr)
4764 return Ex;
4765 return make<PostfixExpr>(Ex, "++");
4766 } 4651 }
4767 case 's': 4652 case OperatorInfo::CCast: {
4768 First += 2; 4653 // C Cast: (type)expr
4769 return getDerived().parsePrefixExpr("+"); 4654 Node *Ty;
4770 case 't': { 4655 {
4771 First += 2; 4656 ScopedOverride<bool> SaveTemp(TryToParseTemplateArgs, false);
4772 Node *L = getDerived().parseExpr(); 4657 Ty = getDerived().parseType();
4773 if (L == nullptr) 4658 }
4659 if (Ty == nullptr)
4774 return nullptr; 4660 return nullptr;
4775 Node *R = getDerived().parseExpr(); 4661
4776 if (R == nullptr) 4662 size_t ExprsBegin = Names.size();
4663 bool IsMany = consumeIf('_');
4664 while (!consumeIf('E')) {
4665 Node *E = getDerived().parseExpr();
4666 if (E == nullptr)
4667 return E;
4668 Names.push_back(E);
4669 if (!IsMany)
4670 break;
4671 }
4672 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
4673 if (!IsMany && Exprs.size() != 1)
4777 return nullptr; 4674 return nullptr;
4778 return make<MemberExpr>(L, "->", R); 4675 return make<ConversionExpr>(Ty, Exprs, Op->getPrecedence());
4779 } 4676 }
4780 } 4677 case OperatorInfo::Conditional: {
4781 return nullptr; 4678 // Conditional operator: expr ? expr : expr
4782 case 'q':
4783 if (First[1] == 'u') {
4784 First += 2;
4785 Node *Cond = getDerived().parseExpr(); 4679 Node *Cond = getDerived().parseExpr();
4786 if (Cond == nullptr) 4680 if (Cond == nullptr)
4787 return nullptr; 4681 return nullptr;
@@ -4791,169 +4685,158 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
4791 Node *RHS = getDerived().parseExpr(); 4685 Node *RHS = getDerived().parseExpr();
4792 if (RHS == nullptr) 4686 if (RHS == nullptr)
4793 return nullptr; 4687 return nullptr;
4794 return make<ConditionalExpr>(Cond, LHS, RHS); 4688 return make<ConditionalExpr>(Cond, LHS, RHS, Op->getPrecedence());
4795 }
4796 return nullptr;
4797 case 'r':
4798 switch (First[1]) {
4799 case 'c': {
4800 First += 2;
4801 Node *T = getDerived().parseType();
4802 if (T == nullptr)
4803 return T;
4804 Node *Ex = getDerived().parseExpr();
4805 if (Ex == nullptr)
4806 return Ex;
4807 return make<CastExpr>("reinterpret_cast", T, Ex);
4808 } 4689 }
4809 case 'm': 4690 case OperatorInfo::NamedCast: {
4810 First += 2; 4691 // Named cast operation, @<type>(expr)
4811 return getDerived().parseBinaryExpr("%");
4812 case 'M':
4813 First += 2;
4814 return getDerived().parseBinaryExpr("%=");
4815 case 's':
4816 First += 2;
4817 return getDerived().parseBinaryExpr(">>");
4818 case 'S':
4819 First += 2;
4820 return getDerived().parseBinaryExpr(">>=");
4821 }
4822 return nullptr;
4823 case 's':
4824 switch (First[1]) {
4825 case 'c': {
4826 First += 2;
4827 Node *T = getDerived().parseType();
4828 if (T == nullptr)
4829 return T;
4830 Node *Ex = getDerived().parseExpr();
4831 if (Ex == nullptr)
4832 return Ex;
4833 return make<CastExpr>("static_cast", T, Ex);
4834 }
4835 case 'p': {
4836 First += 2;
4837 Node *Child = getDerived().parseExpr();
4838 if (Child == nullptr)
4839 return nullptr;
4840 return make<ParameterPackExpansion>(Child);
4841 }
4842 case 'r':
4843 return getDerived().parseUnresolvedName();
4844 case 't': {
4845 First += 2;
4846 Node *Ty = getDerived().parseType(); 4692 Node *Ty = getDerived().parseType();
4847 if (Ty == nullptr) 4693 if (Ty == nullptr)
4848 return Ty; 4694 return nullptr;
4849 return make<EnclosingExpr>("sizeof (", Ty, ")");
4850 }
4851 case 'z': {
4852 First += 2;
4853 Node *Ex = getDerived().parseExpr(); 4695 Node *Ex = getDerived().parseExpr();
4854 if (Ex == nullptr) 4696 if (Ex == nullptr)
4855 return Ex;
4856 return make<EnclosingExpr>("sizeof (", Ex, ")");
4857 }
4858 case 'Z':
4859 First += 2;
4860 if (look() == 'T') {
4861 Node *R = getDerived().parseTemplateParam();
4862 if (R == nullptr)
4863 return nullptr;
4864 return make<SizeofParamPackExpr>(R);
4865 } else if (look() == 'f') {
4866 Node *FP = getDerived().parseFunctionParam();
4867 if (FP == nullptr)
4868 return nullptr;
4869 return make<EnclosingExpr>("sizeof... (", FP, ")");
4870 }
4871 return nullptr;
4872 case 'P': {
4873 First += 2;
4874 size_t ArgsBegin = Names.size();
4875 while (!consumeIf('E')) {
4876 Node *Arg = getDerived().parseTemplateArg();
4877 if (Arg == nullptr)
4878 return nullptr;
4879 Names.push_back(Arg);
4880 }
4881 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
4882 if (!Pack)
4883 return nullptr; 4697 return nullptr;
4884 return make<EnclosingExpr>("sizeof... (", Pack, ")"); 4698 return make<CastExpr>(Sym, Ty, Ex, Op->getPrecedence());
4885 } 4699 }
4700 case OperatorInfo::OfIdOp: {
4701 // [sizeof/alignof/typeid] ( <type>|<expr> )
4702 Node *Arg =
4703 Op->getFlag() ? getDerived().parseType() : getDerived().parseExpr();
4704 if (!Arg)
4705 return nullptr;
4706 return make<EnclosingExpr>(Sym, Arg, Op->getPrecedence());
4886 } 4707 }
4887 return nullptr; 4708 case OperatorInfo::NameOnly: {
4888 case 't': 4709 // Not valid as an expression operand.
4889 switch (First[1]) { 4710 return nullptr;
4890 case 'e': {
4891 First += 2;
4892 Node *Ex = getDerived().parseExpr();
4893 if (Ex == nullptr)
4894 return Ex;
4895 return make<EnclosingExpr>("typeid (", Ex, ")");
4896 } 4711 }
4897 case 'i': {
4898 First += 2;
4899 Node *Ty = getDerived().parseType();
4900 if (Ty == nullptr)
4901 return Ty;
4902 return make<EnclosingExpr>("typeid (", Ty, ")");
4903 } 4712 }
4904 case 'l': { 4713 DEMANGLE_UNREACHABLE;
4905 First += 2; 4714 }
4906 Node *Ty = getDerived().parseType(); 4715
4907 if (Ty == nullptr) 4716 if (numLeft() < 2)
4717 return nullptr;
4718
4719 if (look() == 'L')
4720 return getDerived().parseExprPrimary();
4721 if (look() == 'T')
4722 return getDerived().parseTemplateParam();
4723 if (look() == 'f') {
4724 // Disambiguate a fold expression from a <function-param>.
4725 if (look(1) == 'p' || (look(1) == 'L' && std::isdigit(look(2))))
4726 return getDerived().parseFunctionParam();
4727 return getDerived().parseFoldExpr();
4728 }
4729 if (consumeIf("il")) {
4730 size_t InitsBegin = Names.size();
4731 while (!consumeIf('E')) {
4732 Node *E = getDerived().parseBracedExpr();
4733 if (E == nullptr)
4908 return nullptr; 4734 return nullptr;
4909 size_t InitsBegin = Names.size(); 4735 Names.push_back(E);
4910 while (!consumeIf('E')) {
4911 Node *E = getDerived().parseBracedExpr();
4912 if (E == nullptr)
4913 return nullptr;
4914 Names.push_back(E);
4915 }
4916 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
4917 } 4736 }
4918 case 'r': 4737 return make<InitListExpr>(nullptr, popTrailingNodeArray(InitsBegin));
4919 First += 2; 4738 }
4920 return make<NameType>("throw"); 4739 if (consumeIf("mc"))
4921 case 'w': { 4740 return parsePointerToMemberConversionExpr(Node::Prec::Unary);
4922 First += 2; 4741 if (consumeIf("nx")) {
4923 Node *Ex = getDerived().parseExpr(); 4742 Node *Ex = getDerived().parseExpr();
4924 if (Ex == nullptr) 4743 if (Ex == nullptr)
4744 return Ex;
4745 return make<EnclosingExpr>("noexcept ", Ex, Node::Prec::Unary);
4746 }
4747 if (consumeIf("so"))
4748 return parseSubobjectExpr();
4749 if (consumeIf("sp")) {
4750 Node *Child = getDerived().parseExpr();
4751 if (Child == nullptr)
4752 return nullptr;
4753 return make<ParameterPackExpansion>(Child);
4754 }
4755 if (consumeIf("sZ")) {
4756 if (look() == 'T') {
4757 Node *R = getDerived().parseTemplateParam();
4758 if (R == nullptr)
4925 return nullptr; 4759 return nullptr;
4926 return make<ThrowExpr>(Ex); 4760 return make<SizeofParamPackExpr>(R);
4927 } 4761 }
4762 Node *FP = getDerived().parseFunctionParam();
4763 if (FP == nullptr)
4764 return nullptr;
4765 return make<EnclosingExpr>("sizeof... ", FP);
4766 }
4767 if (consumeIf("sP")) {
4768 size_t ArgsBegin = Names.size();
4769 while (!consumeIf('E')) {
4770 Node *Arg = getDerived().parseTemplateArg();
4771 if (Arg == nullptr)
4772 return nullptr;
4773 Names.push_back(Arg);
4928 } 4774 }
4929 return nullptr; 4775 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
4930 case '1': 4776 if (!Pack)
4931 case '2': 4777 return nullptr;
4932 case '3': 4778 return make<EnclosingExpr>("sizeof... ", Pack);
4933 case '4': 4779 }
4934 case '5': 4780 if (consumeIf("tl")) {
4935 case '6':
4936 case '7':
4937 case '8':
4938 case '9':
4939 return getDerived().parseUnresolvedName();
4940 }
4941
4942 if (consumeIf("u8__uuidoft")) {
4943 Node *Ty = getDerived().parseType(); 4781 Node *Ty = getDerived().parseType();
4944 if (!Ty) 4782 if (Ty == nullptr)
4945 return nullptr; 4783 return nullptr;
4946 return make<UUIDOfExpr>(Ty); 4784 size_t InitsBegin = Names.size();
4785 while (!consumeIf('E')) {
4786 Node *E = getDerived().parseBracedExpr();
4787 if (E == nullptr)
4788 return nullptr;
4789 Names.push_back(E);
4790 }
4791 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
4947 } 4792 }
4948 4793 if (consumeIf("tr"))
4949 if (consumeIf("u8__uuidofz")) { 4794 return make<NameType>("throw");
4795 if (consumeIf("tw")) {
4950 Node *Ex = getDerived().parseExpr(); 4796 Node *Ex = getDerived().parseExpr();
4951 if (!Ex) 4797 if (Ex == nullptr)
4952 return nullptr; 4798 return nullptr;
4953 return make<UUIDOfExpr>(Ex); 4799 return make<ThrowExpr>(Ex);
4800 }
4801 if (consumeIf('u')) {
4802 Node *Name = getDerived().parseSourceName(/*NameState=*/nullptr);
4803 if (!Name)
4804 return nullptr;
4805 // Special case legacy __uuidof mangling. The 't' and 'z' appear where the
4806 // standard encoding expects a <template-arg>, and would be otherwise be
4807 // interpreted as <type> node 'short' or 'ellipsis'. However, neither
4808 // __uuidof(short) nor __uuidof(...) can actually appear, so there is no
4809 // actual conflict here.
4810 bool IsUUID = false;
4811 Node *UUID = nullptr;
4812 if (Name->getBaseName() == "__uuidof") {
4813 if (consumeIf('t')) {
4814 UUID = getDerived().parseType();
4815 IsUUID = true;
4816 } else if (consumeIf('z')) {
4817 UUID = getDerived().parseExpr();
4818 IsUUID = true;
4819 }
4820 }
4821 size_t ExprsBegin = Names.size();
4822 if (IsUUID) {
4823 if (UUID == nullptr)
4824 return nullptr;
4825 Names.push_back(UUID);
4826 } else {
4827 while (!consumeIf('E')) {
4828 Node *E = getDerived().parseTemplateArg();
4829 if (E == nullptr)
4830 return E;
4831 Names.push_back(E);
4832 }
4833 }
4834 return make<CallExpr>(Name, popTrailingNodeArray(ExprsBegin),
4835 Node::Prec::Postfix);
4954 } 4836 }
4955 4837
4956 return nullptr; 4838 // Only unresolved names remain.
4839 return getDerived().parseUnresolvedName(Global);
4957} 4840}
4958 4841
4959// <call-offset> ::= h <nv-offset> _ 4842// <call-offset> ::= h <nv-offset> _
@@ -4986,19 +4869,32 @@ bool AbstractManglingParser<Alloc, Derived>::parseCallOffset() {
4986// # second call-offset is result adjustment 4869// # second call-offset is result adjustment
4987// ::= T <call-offset> <base encoding> 4870// ::= T <call-offset> <base encoding>
4988// # base is the nominal target function of thunk 4871// # base is the nominal target function of thunk
4989// ::= GV <object name> # Guard variable for one-time initialization 4872// # Guard variable for one-time initialization
4873// ::= GV <object name>
4990// # No <type> 4874// # No <type>
4991// ::= TW <object name> # Thread-local wrapper 4875// ::= TW <object name> # Thread-local wrapper
4992// ::= TH <object name> # Thread-local initialization 4876// ::= TH <object name> # Thread-local initialization
4993// ::= GR <object name> _ # First temporary 4877// ::= GR <object name> _ # First temporary
4994// ::= GR <object name> <seq-id> _ # Subsequent temporaries 4878// ::= GR <object name> <seq-id> _ # Subsequent temporaries
4995// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first 4879// # construction vtable for second-in-first
4880// extension ::= TC <first type> <number> _ <second type>
4996// extension ::= GR <object name> # reference temporary for object 4881// extension ::= GR <object name> # reference temporary for object
4882// extension ::= GI <module name> # module global initializer
4997template <typename Derived, typename Alloc> 4883template <typename Derived, typename Alloc>
4998Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() { 4884Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
4999 switch (look()) { 4885 switch (look()) {
5000 case 'T': 4886 case 'T':
5001 switch (look(1)) { 4887 switch (look(1)) {
4888 // TA <template-arg> # template parameter object
4889 //
4890 // Not yet in the spec: https://github.com/itanium-cxx-abi/cxx-abi/issues/63
4891 case 'A': {
4892 First += 2;
4893 Node *Arg = getDerived().parseTemplateArg();
4894 if (Arg == nullptr)
4895 return nullptr;
4896 return make<SpecialName>("template parameter object for ", Arg);
4897 }
5002 // TV <type> # virtual table 4898 // TV <type> # virtual table
5003 case 'V': { 4899 case 'V': {
5004 First += 2; 4900 First += 2;
@@ -5110,6 +5006,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
5110 return nullptr; 5006 return nullptr;
5111 return make<SpecialName>("reference temporary for ", Name); 5007 return make<SpecialName>("reference temporary for ", Name);
5112 } 5008 }
5009 // GI <module-name> v
5010 case 'I': {
5011 First += 2;
5012 ModuleName *Module = nullptr;
5013 if (getDerived().parseModuleNameOpt(Module))
5014 return nullptr;
5015 if (Module == nullptr)
5016 return nullptr;
5017 return make<SpecialName>("initializer for module ", Module);
5018 }
5113 } 5019 }
5114 } 5020 }
5115 return nullptr; 5021 return nullptr;
@@ -5120,6 +5026,26 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
5120// ::= <special-name> 5026// ::= <special-name>
5121template <typename Derived, typename Alloc> 5027template <typename Derived, typename Alloc>
5122Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() { 5028Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
5029 // The template parameters of an encoding are unrelated to those of the
5030 // enclosing context.
5031 class SaveTemplateParams {
5032 AbstractManglingParser *Parser;
5033 decltype(TemplateParams) OldParams;
5034 decltype(OuterTemplateParams) OldOuterParams;
5035
5036 public:
5037 SaveTemplateParams(AbstractManglingParser *TheParser) : Parser(TheParser) {
5038 OldParams = std::move(Parser->TemplateParams);
5039 OldOuterParams = std::move(Parser->OuterTemplateParams);
5040 Parser->TemplateParams.clear();
5041 Parser->OuterTemplateParams.clear();
5042 }
5043 ~SaveTemplateParams() {
5044 Parser->TemplateParams = std::move(OldParams);
5045 Parser->OuterTemplateParams = std::move(OldOuterParams);
5046 }
5047 } SaveTemplateParams(this);
5048
5123 if (look() == 'G' || look() == 'T') 5049 if (look() == 'G' || look() == 'T')
5124 return getDerived().parseSpecialName(); 5050 return getDerived().parseSpecialName();
5125 5051
@@ -5204,14 +5130,19 @@ template <>
5204struct FloatData<long double> 5130struct FloatData<long double>
5205{ 5131{
5206#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \ 5132#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
5207 defined(__wasm__) 5133 defined(__wasm__) || defined(__riscv) || defined(__loongarch__)
5208 static const size_t mangled_size = 32; 5134 static const size_t mangled_size = 32;
5209#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__) 5135#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
5210 static const size_t mangled_size = 16; 5136 static const size_t mangled_size = 16;
5211#else 5137#else
5212 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms 5138 static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
5213#endif 5139#endif
5214 static const size_t max_demangled_size = 40; 5140 // `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
5141 // 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
5142 // Negatives are one character longer than positives.
5143 // `0x1.` and `p` are constant, and exponents `+16383` and `-16382` are the
5144 // same length. 1 sign bit, 112 mantissa bits, and 15 exponent bits == 128.
5145 static const size_t max_demangled_size = 42;
5215 static constexpr const char *spec = "%LaL"; 5146 static constexpr const char *spec = "%LaL";
5216}; 5147};
5217 5148
@@ -5221,7 +5152,7 @@ Node *AbstractManglingParser<Alloc, Derived>::parseFloatingLiteral() {
5221 const size_t N = FloatData<Float>::mangled_size; 5152 const size_t N = FloatData<Float>::mangled_size;
5222 if (numLeft() <= N) 5153 if (numLeft() <= N)
5223 return nullptr; 5154 return nullptr;
5224 StringView Data(First, First + N); 5155 std::string_view Data(First, N);
5225 for (char C : Data) 5156 for (char C : Data)
5226 if (!std::isxdigit(C)) 5157 if (!std::isxdigit(C))
5227 return nullptr; 5158 return nullptr;
@@ -5264,43 +5195,41 @@ bool AbstractManglingParser<Alloc, Derived>::parseSeqId(size_t *Out) {
5264// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> > 5195// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
5265// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> > 5196// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
5266// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> > 5197// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
5198// The St case is handled specially in parseNestedName.
5267template <typename Derived, typename Alloc> 5199template <typename Derived, typename Alloc>
5268Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() { 5200Node *AbstractManglingParser<Derived, Alloc>::parseSubstitution() {
5269 if (!consumeIf('S')) 5201 if (!consumeIf('S'))
5270 return nullptr; 5202 return nullptr;
5271 5203
5272 if (std::islower(look())) { 5204 if (look() >= 'a' && look() <= 'z') {
5273 Node *SpecialSub; 5205 SpecialSubKind Kind;
5274 switch (look()) { 5206 switch (look()) {
5275 case 'a': 5207 case 'a':
5276 ++First; 5208 Kind = SpecialSubKind::allocator;
5277 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::allocator);
5278 break; 5209 break;
5279 case 'b': 5210 case 'b':
5280 ++First; 5211 Kind = SpecialSubKind::basic_string;
5281 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::basic_string);
5282 break; 5212 break;
5283 case 's': 5213 case 'd':
5284 ++First; 5214 Kind = SpecialSubKind::iostream;
5285 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::string);
5286 break; 5215 break;
5287 case 'i': 5216 case 'i':
5288 ++First; 5217 Kind = SpecialSubKind::istream;
5289 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::istream);
5290 break; 5218 break;
5291 case 'o': 5219 case 'o':
5292 ++First; 5220 Kind = SpecialSubKind::ostream;
5293 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::ostream);
5294 break; 5221 break;
5295 case 'd': 5222 case 's':
5296 ++First; 5223 Kind = SpecialSubKind::string;
5297 SpecialSub = make<SpecialSubstitution>(SpecialSubKind::iostream);
5298 break; 5224 break;
5299 default: 5225 default:
5300 return nullptr; 5226 return nullptr;
5301 } 5227 }
5228 ++First;
5229 auto *SpecialSub = make<SpecialSubstitution>(Kind);
5302 if (!SpecialSub) 5230 if (!SpecialSub)
5303 return nullptr; 5231 return nullptr;
5232
5304 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution> 5233 // Itanium C++ ABI 5.1.2: If a name that would use a built-in <substitution>
5305 // has ABI tags, the tags are appended to the substitution; the result is a 5234 // has ABI tags, the tags are appended to the substitution; the result is a
5306 // substitutable component. 5235 // substitutable component.
@@ -5543,7 +5472,8 @@ Node *AbstractManglingParser<Derived, Alloc>::parse() {
5543 if (Encoding == nullptr) 5472 if (Encoding == nullptr)
5544 return nullptr; 5473 return nullptr;
5545 if (look() == '.') { 5474 if (look() == '.') {
5546 Encoding = make<DotSuffix>(Encoding, StringView(First, Last)); 5475 Encoding =
5476 make<DotSuffix>(Encoding, std::string_view(First, Last - First));
5547 First = Last; 5477 First = Last;
5548 } 5478 }
5549 if (numLeft() != 0) 5479 if (numLeft() != 0)