16#ifndef DEMANGLE_ITANIUMDEMANGLE_H
17#define DEMANGLE_ITANIUMDEMANGLE_H
34#pragma clang diagnostic push
35#pragma clang diagnostic ignored "-Wunused-template"
41 static_assert(std::is_trivial<T>::value,
42 "T is required to be a trivial type");
48 bool isInline()
const {
return First == Inline; }
56 void reserve(
size_t NewCap) {
59 auto *Tmp =
static_cast<T *
>(std::malloc(NewCap *
sizeof(
T)));
62 std::copy(First, Last, Tmp);
65 First =
static_cast<T *
>(std::realloc(First, NewCap *
sizeof(
T)));
80 if (
Other.isInline()) {
82 Last = First +
Other.size();
94 if (
Other.isInline()) {
100 Last = First +
Other.size();
135 Last = First +
Index;
141 bool empty()
const {
return First == Last; }
142 size_t size()
const {
return static_cast<size_t>(Last - First); }
164#define NODE(NodeKind) K##NodeKind,
165#include "ItaniumNodes.def"
227 template<
typename Fn>
void visit(Fn
F)
const;
271 bool StrictlyWorse =
false)
const {
313 : Elements(Elements_), NumElements(NumElements_) {}
315 bool empty()
const {
return NumElements == 0; }
316 size_t size()
const {
return NumElements; }
319 Node **
end()
const {
return Elements + NumElements; }
324 bool FirstElement =
true;
325 for (
size_t Idx = 0;
Idx != NumElements; ++
Idx) {
326 size_t BeforeComma = OB.getCurrentPosition();
329 size_t AfterComma = OB.getCurrentPosition();
334 if (AfterComma == OB.getCurrentPosition()) {
335 OB.setCurrentPosition(BeforeComma);
339 FirstElement =
false;
355 const std::string_view Suffix;
359 :
Node(KDotSuffix), Prefix(Prefix_), Suffix(Suffix_) {}
361 template<
typename Fn>
void match(Fn
F)
const {
F(Prefix, Suffix); }
373 std::string_view Ext;
378 :
Node(KVendorExtQualType), Ty(Ty_), Ext(Ext_), TA(TA_) {}
381 std::string_view
getExt()
const {
return Ext; }
384 template <
typename Fn>
void match(Fn
F)
const {
F(Ty, Ext, TA); }
460 :
Node(KConversionOperatorType), Ty(Ty_) {}
462 template<
typename Fn>
void match(Fn
F)
const {
F(Ty); }
472 const std::string_view Postfix;
476 :
Node(KPostfixQualifiedType), Ty(Ty_), Postfix(Postfix_) {}
478 template<
typename Fn>
void match(Fn
F)
const {
F(Ty, Postfix); }
487 const std::string_view Name;
492 template<
typename Fn>
void match(Fn
F)
const {
F(Name); }
494 std::string_view
getName()
const {
return Name; }
506 :
Node(KBitIntType), Size(Size_), Signed(Signed_) {}
508 template <
typename Fn>
void match(Fn
F)
const {
F(Size, Signed); }
515 Size->printAsOperand(OB);
521 std::string_view
Kind;
525 :
Node(KElaboratedTypeSpefType),
Kind(Kind_), Child(Child_) {}
537 std::string_view Transform;
541 :
Node(KTransformedType), Transform(Transform_),
BaseType(BaseType_) {}
578 :
Node(KEnableIfAttr), Conditions(Conditions_) {}
580 template<
typename Fn>
void match(Fn
F)
const {
F(Conditions); }
583 OB +=
" [enable_if:";
591 std::string_view Protocol;
597 :
Node(KObjCProtoName), Ty(Ty_), Protocol(Protocol_) {}
599 template<
typename Fn>
void match(Fn
F)
const {
F(Ty, Protocol); }
602 return Ty->
getKind() == KNameType &&
624 template<
typename Fn>
void match(Fn
F)
const {
F(Pointee); }
627 return Pointee->hasRHSComponent(OB);
632 if (Pointee->getKind() != KObjCProtoName ||
634 Pointee->printLeft(OB);
635 if (Pointee->hasArray(OB))
637 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
641 const auto *objcProto =
static_cast<const ObjCProtoName *
>(Pointee);
643 OB += objcProto->Protocol;
649 if (Pointee->getKind() != KObjCProtoName ||
651 if (Pointee->hasArray(OB) || Pointee->hasFunction(OB))
653 Pointee->printRight(OB);
668 mutable bool Printing =
false;
677 std::pair<ReferenceKind, const Node *> collapse(
OutputBuffer &OB)
const {
678 auto SoFar = std::make_pair(RK, Pointee);
684 if (SN->
getKind() != KReferenceType)
687 SoFar.second = RT->Pointee;
688 SoFar.first = std::min(SoFar.first, RT->RK);
692 if (Prev.
size() > 1 && SoFar.second == Prev[(Prev.
size() - 1) / 2]) {
694 SoFar.second =
nullptr;
704 Pointee(Pointee_), RK(RK_) {}
706 template<
typename Fn>
void match(Fn
F)
const {
F(Pointee, RK); }
716 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
717 if (!Collapsed.second)
719 Collapsed.second->printLeft(OB);
720 if (Collapsed.second->hasArray(OB))
722 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
725 OB += (Collapsed.first == ReferenceKind::LValue ?
"&" :
"&&");
731 std::pair<ReferenceKind, const Node *> Collapsed = collapse(OB);
732 if (!Collapsed.second)
734 if (Collapsed.second->hasArray(OB) || Collapsed.second->hasFunction(OB))
736 Collapsed.second->printRight(OB);
741 const Node *ClassType;
742 const Node *MemberType;
747 ClassType(ClassType_), MemberType(MemberType_) {}
749 template<
typename Fn>
void match(Fn
F)
const {
F(ClassType, MemberType); }
761 ClassType->print(OB);
781 Base(Base_), Dimension(Dimension_) {}
783 template<
typename Fn>
void match(Fn
F)
const {
F(Base, Dimension); }
791 if (OB.back() !=
']')
795 Dimension->print(OB);
797 Base->printRight(OB);
806 const Node *ExceptionSpec;
811 :
Node(KFunctionType,
814 Ret(Ret_), Params(Params_), CVQuals(CVQuals_), RefQual(RefQual_),
815 ExceptionSpec(ExceptionSpec_) {}
817 template<
typename Fn>
void match(Fn
F)
const {
818 F(Ret, Params, CVQuals, RefQual, ExceptionSpec);
854 if (ExceptionSpec !=
nullptr) {
856 ExceptionSpec->
print(OB);
866 template<
typename Fn>
void match(Fn
F)
const {
F(E); }
880 :
Node(KDynamicExceptionSpec), Types(Types_) {}
882 template<
typename Fn>
void match(Fn
F)
const {
F(Types); }
887 Types.printWithComma(OB);
904 :
Node(KExplicitObjectParameter), Base(Base_) {
907 "Creating an ExplicitObjectParameter without a valid Base Node.");
910 template <
typename Fn>
void match(Fn
F)
const {
F(Base); }
923 const Node *Requires;
929 const Node *Attrs_,
const Node *Requires_,
931 :
Node(KFunctionEncoding,
934 Ret(Ret_), Name(Name_), Params(Params_), Attrs(Attrs_),
935 Requires(Requires_), CVQuals(CVQuals_), RefQual(RefQual_) {}
937 template<
typename Fn>
void match(Fn
F)
const {
938 F(Ret, Name, Params, Attrs, Requires, CVQuals, RefQual);
954 if (!Ret->hasRHSComponent(OB))
979 if (Attrs !=
nullptr)
982 if (Requires !=
nullptr) {
999 OB +=
"operator\"\" ";
1005 const std::string_view Special;
1010 :
Node(KSpecialName), Special(Special_), Child(Child_) {}
1012 template<
typename Fn>
void match(Fn
F)
const {
F(Special, Child); }
1021 const Node *FirstType;
1022 const Node *SecondType;
1026 :
Node(KCtorVtableSpecialName),
1027 FirstType(FirstType_), SecondType(SecondType_) {}
1029 template<
typename Fn>
void match(Fn
F)
const {
F(FirstType, SecondType); }
1032 OB +=
"construction vtable for ";
1033 FirstType->print(OB);
1035 SecondType->
print(OB);
1062 :
Node(KMemberLikeFriendName),
Qual(Qual_),
Name(Name_) {}
1084 template <
typename Fn>
void match(Fn
F)
const {
1133 const Node *Qualifier;
1138 :
Node(KQualifiedName), Qualifier(Qualifier_), Name(Name_) {}
1140 template<
typename Fn>
void match(Fn
F)
const {
F(Qualifier, Name); }
1142 std::string_view
getBaseName()
const override {
return Name->getBaseName(); }
1145 Qualifier->print(OB);
1153 const Node *Dimension;
1157 :
Node(KVectorType),
BaseType(BaseType_), Dimension(Dimension_) {}
1168 Dimension->print(OB);
1174 const Node *Dimension;
1178 :
Node(KPixelVectorType), Dimension(Dimension_) {}
1180 template<
typename Fn>
void match(Fn
F)
const {
F(Dimension); }
1184 OB +=
"pixel vector[";
1185 Dimension->print(OB);
1191 const Node *Dimension;
1195 :
Node(KBinaryFPType), Dimension(Dimension_) {}
1197 template<
typename Fn>
void match(Fn
F)
const {
F(Dimension); }
1201 Dimension->print(OB);
1219 :
Node(KSyntheticTemplateParamName),
Kind(Kind_), Index(Index_) {}
1225 case TemplateParamKind::Type:
1228 case TemplateParamKind::NonType:
1231 case TemplateParamKind::Template:
1246 :
Node(KTemplateParamQualifiedArg), Param(Param_), Arg(Arg_) {}
1248 template <
typename Fn>
void match(Fn
F)
const {
F(Param, Arg); }
1264 :
Node(KTypeTemplateParamDecl,
Cache::
Yes), Name(Name_) {}
1266 template<
typename Fn>
void match(Fn
F)
const {
F(Name); }
1281 Constraint(Constraint_), Name(Name_) {}
1283 template<
typename Fn>
void match(Fn
F)
const {
F(Constraint, Name); }
1286 Constraint->print(OB);
1300 :
Node(KNonTypeTemplateParamDecl,
Cache::
Yes), Name(Name_), Type(Type_) {}
1302 template<
typename Fn>
void match(Fn
F)
const {
F(Name, Type); }
1305 Type->printLeft(OB);
1306 if (!Type->hasRHSComponent(OB))
1312 Type->printRight(OB);
1325 :
Node(KTemplateTemplateParamDecl,
Cache::
Yes), Name(Name_),
1326 Params(Params_), Requires(Requires_) {}
1328 template <
typename Fn>
void match(Fn
F)
const {
F(Name, Params, Requires); }
1334 OB +=
"> typename ";
1339 if (Requires !=
nullptr) {
1341 Requires->
print(OB);
1352 :
Node(KTemplateParamPackDecl,
Cache::
Yes), Param(Param_) {}
1354 template<
typename Fn>
void match(Fn
F)
const {
F(Param); }
1357 Param->printLeft(OB);
1378 if (OB.CurrentPackMax == std::numeric_limits<unsigned>::max()) {
1379 OB.CurrentPackMax =
static_cast<unsigned>(Data.size());
1380 OB.CurrentPackIndex = 0;
1387 if (std::all_of(Data.begin(), Data.end(),
1388 [](
Node *
P) { return P->getArrayCache() == Cache::No; }))
1390 if (std::all_of(Data.begin(), Data.end(),
1391 [](
Node *
P) { return P->getFunctionCache() == Cache::No; }))
1393 if (std::all_of(Data.begin(), Data.end(), [](
Node *
P) {
1394 return P->getRHSComponentCache() == Cache::No;
1399 template<
typename Fn>
void match(Fn
F)
const {
F(Data); }
1402 initializePackExpansion(OB);
1403 size_t Idx = OB.CurrentPackIndex;
1404 return Idx < Data.size() && Data[
Idx]->hasRHSComponent(OB);
1407 initializePackExpansion(OB);
1408 size_t Idx = OB.CurrentPackIndex;
1409 return Idx < Data.size() && Data[
Idx]->hasArray(OB);
1412 initializePackExpansion(OB);
1413 size_t Idx = OB.CurrentPackIndex;
1414 return Idx < Data.size() && Data[
Idx]->hasFunction(OB);
1417 initializePackExpansion(OB);
1418 size_t Idx = OB.CurrentPackIndex;
1419 return Idx < Data.size() ? Data[
Idx]->getSyntaxNode(OB) :
this;
1423 initializePackExpansion(OB);
1424 size_t Idx = OB.CurrentPackIndex;
1425 if (
Idx < Data.size())
1426 Data[
Idx]->printLeft(OB);
1429 initializePackExpansion(OB);
1430 size_t Idx = OB.CurrentPackIndex;
1431 if (
Idx < Data.size())
1432 Data[
Idx]->printRight(OB);
1445 :
Node(KTemplateArgumentPack), Elements(Elements_) {}
1447 template<
typename Fn>
void match(Fn
F)
const {
F(Elements); }
1452 Elements.printWithComma(OB);
1463 :
Node(KParameterPackExpansion), Child(Child_) {}
1465 template<
typename Fn>
void match(Fn
F)
const {
F(Child); }
1470 constexpr unsigned Max = std::numeric_limits<unsigned>::max();
1473 size_t StreamPos = OB.getCurrentPosition();
1481 if (OB.CurrentPackMax == Max) {
1488 if (OB.CurrentPackMax == 0) {
1489 OB.setCurrentPosition(StreamPos);
1494 for (
unsigned I = 1,
E = OB.CurrentPackMax;
I <
E; ++
I) {
1496 OB.CurrentPackIndex =
I;
1508 :
Node(KTemplateArgs), Params(Params_), Requires(Requires_) {}
1510 template<
typename Fn>
void match(Fn
F)
const {
F(Params, Requires); }
1517 Params.printWithComma(OB);
1559 template<
typename Fn>
void match(Fn
F)
const =
delete;
1623 :
Node(KGlobalQualifiedName), Child(Child_) {}
1625 template<
typename Fn>
void match(Fn
F)
const {
F(Child); }
1627 std::string_view
getBaseName()
const override {
return Child->getBaseName(); }
1665 case SpecialSubKind::allocator:
1666 return {
"allocator"};
1667 case SpecialSubKind::basic_string:
1668 return {
"basic_string"};
1669 case SpecialSubKind::string:
1670 return {
"basic_string"};
1671 case SpecialSubKind::istream:
1672 return {
"basic_istream"};
1673 case SpecialSubKind::ostream:
1674 return {
"basic_ostream"};
1675 case SpecialSubKind::iostream:
1676 return {
"basic_iostream"};
1685 OB <<
"<char, std::char_traits<char>";
1686 if (
SSK == SpecialSubKind::string)
1687 OB <<
", std::allocator<char>";
1705 SV.remove_prefix(
sizeof(
"basic_") - 1);
1720 const Node *Basename;
1726 :
Node(KCtorDtorName), Basename(Basename_), IsDtor(IsDtor_),
1727 Variant(Variant_) {}
1729 template<
typename Fn>
void match(Fn
F)
const {
F(Basename, IsDtor, Variant); }
1734 OB += Basename->getBaseName();
1744 template<
typename Fn>
void match(Fn
F)
const {
F(Base); }
1748 Base->printLeft(OB);
1753 const std::string_view Count;
1757 :
Node(KUnnamedTypeName), Count(Count_) {}
1759 template<
typename Fn>
void match(Fn
F)
const {
F(Count); }
1770 const Node *Requires1;
1772 const Node *Requires2;
1773 std::string_view Count;
1778 std::string_view Count_)
1779 :
Node(KClosureTypeName), TemplateParams(TemplateParams_),
1780 Requires1(Requires1_), Params(Params_), Requires2(Requires2_),
1783 template<
typename Fn>
void match(Fn
F)
const {
1784 F(TemplateParams, Requires1, Params, Requires2, Count);
1788 if (!TemplateParams.
empty()) {
1794 if (Requires1 !=
nullptr) {
1796 Requires1->
print(OB);
1802 if (Requires2 !=
nullptr) {
1804 Requires2->
print(OB);
1821 :
Node(KStructuredBindingName), Bindings(Bindings_) {}
1823 template<
typename Fn>
void match(Fn
F)
const {
F(Bindings); }
1836 const std::string_view InfixOperator;
1842 :
Node(KBinaryExpr, Prec_),
LHS(LHS_), InfixOperator(InfixOperator_),
1845 template <
typename Fn>
void match(Fn
F)
const {
1850 bool ParenAll = OB.isGtInsideTemplateArgs() &&
1851 (InfixOperator ==
">" || InfixOperator ==
">>");
1858 if (!(InfixOperator ==
","))
1860 OB += InfixOperator;
1874 :
Node(KArraySubscriptExpr, Prec_), Op1(Op1_), Op2(Op2_) {}
1876 template <
typename Fn>
void match(Fn
F)
const {
1890 const std::string_view Operator;
1894 :
Node(KPostfixExpr, Prec_), Child(Child_), Operator(Operator_) {}
1896 template <
typename Fn>
void match(Fn
F)
const {
1914 :
Node(KConditionalExpr, Prec_),
Cond(Cond_), Then(Then_), Else(Else_) {}
1916 template <
typename Fn>
void match(Fn
F)
const {
1923 Then->printAsOperand(OB);
1931 const std::string_view
Kind;
1939 template <
typename Fn>
void match(Fn
F)
const {
1952 const Node *SubExpr;
1953 std::string_view Offset;
1959 std::string_view Offset_,
NodeArray UnionSelectors_,
1960 bool OnePastTheEnd_)
1961 :
Node(KSubobjectExpr), Type(Type_), SubExpr(SubExpr_), Offset(Offset_),
1962 UnionSelectors(UnionSelectors_), OnePastTheEnd(OnePastTheEnd_) {}
1964 template<
typename Fn>
void match(Fn
F)
const {
1965 F(Type, SubExpr, Offset, UnionSelectors, OnePastTheEnd);
1972 OB +=
" at offset ";
1973 if (Offset.empty()) {
1975 }
else if (Offset[0] ==
'n') {
1977 OB += std::string_view(Offset.data() + 1, Offset.size() - 1);
1986 const std::string_view Prefix;
1988 const std::string_view Postfix;
1993 :
Node(KEnclosingExpr, Prec_), Prefix(Prefix_), Infix(Infix_) {}
1995 template <
typename Fn>
void match(Fn
F)
const {
2010 const std::string_view CastKind;
2017 :
Node(KCastExpr, Prec_), CastKind(CastKind_), To(To_),
From(From_) {}
2019 template <
typename Fn>
void match(Fn
F)
const {
2032 From->printAsOperand(OB);
2042 :
Node(KSizeofParamPackExpr), Pack(Pack_) {}
2044 template<
typename Fn>
void match(Fn
F)
const {
F(Pack); }
2061 :
Node(KCallExpr, Prec_), Callee(Callee_), Args(Args_) {}
2063 template <
typename Fn>
void match(Fn
F)
const {
2070 Args.printWithComma(OB);
2084 bool IsArray_,
Prec Prec_)
2085 :
Node(KNewExpr, Prec_), ExprList(ExprList_), Type(Type_),
2086 InitList(InitList_), IsGlobal(IsGlobal_), IsArray(IsArray_) {}
2088 template<
typename Fn>
void match(Fn
F)
const {
2098 if (!ExprList.
empty()) {
2105 if (!InitList.
empty()) {
2120 :
Node(KDeleteExpr, Prec_), Op(Op_), IsGlobal(IsGlobal_),
2121 IsArray(IsArray_) {}
2123 template <
typename Fn>
void match(Fn
F)
const {
2139 std::string_view Prefix;
2144 :
Node(KPrefixExpr, Prec_), Prefix(Prefix_), Child(Child_) {}
2146 template <
typename Fn>
void match(Fn
F)
const {
2157 std::string_view Number;
2177 :
Node(KConversionExpr, Prec_), Type(Type_), Expressions(Expressions_) {}
2179 template <
typename Fn>
void match(Fn
F)
const {
2195 const Node *SubExpr;
2196 std::string_view Offset;
2200 std::string_view Offset_,
Prec Prec_)
2201 :
Node(KPointerToMemberConversionExpr, Prec_), Type(Type_),
2202 SubExpr(SubExpr_), Offset(Offset_) {}
2204 template <
typename Fn>
void match(Fn
F)
const {
2223 :
Node(KInitListExpr), Ty(Ty_), Inits(Inits_) {}
2225 template<
typename Fn>
void match(Fn
F)
const {
F(Ty, Inits); }
2242 :
Node(KBracedExpr), Elem(Elem_), Init(Init_), IsArray(IsArray_) {}
2244 template<
typename Fn>
void match(Fn
F)
const {
F(Elem, Init, IsArray); }
2255 if (Init->
getKind() != KBracedExpr && Init->
getKind() != KBracedRangeExpr)
2267 :
Node(KBracedRangeExpr), First(First_), Last(Last_), Init(Init_) {}
2269 template<
typename Fn>
void match(Fn
F)
const {
F(First, Last, Init); }
2277 if (Init->
getKind() != KBracedExpr && Init->
getKind() != KBracedRangeExpr)
2284 const Node *Pack, *Init;
2285 std::string_view OperatorName;
2289 FoldExpr(
bool IsLeftFold_, std::string_view OperatorName_,
const Node *Pack_,
2291 :
Node(KFoldExpr), Pack(Pack_), Init(Init_), OperatorName(OperatorName_),
2292 IsLeftFold(IsLeftFold_) {}
2294 template<
typename Fn>
void match(Fn
F)
const {
2295 F(IsLeftFold, OperatorName, Pack, Init);
2299 auto PrintPack = [&] {
2309 if (!IsLeftFold || Init !=
nullptr) {
2315 OB <<
" " << OperatorName <<
" ";
2318 if (IsLeftFold || Init !=
nullptr) {
2320 OB <<
" " << OperatorName <<
" ";
2336 template<
typename Fn>
void match(Fn
F)
const {
F(Op); }
2350 template<
typename Fn>
void match(Fn
F)
const {
F(Value); }
2353 OB += Value ? std::string_view(
"true") : std::string_view(
"false");
2363 template<
typename Fn>
void match(Fn
F)
const {
F(Type); }
2378 template<
typename Fn>
void match(Fn
F)
const {
F(Type); }
2382 if (Type->getKind() == KClosureTypeName)
2391 std::string_view Integer;
2395 :
Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
2397 template<
typename Fn>
void match(Fn
F)
const {
F(Ty, Integer); }
2404 if (Integer[0] ==
'n')
2405 OB <<
'-' << std::string_view(Integer.data() + 1, Integer.size() - 1);
2412 std::string_view Type;
2413 std::string_view Value;
2417 :
Node(KIntegerLiteral), Type(Type_), Value(Value_) {}
2419 template<
typename Fn>
void match(Fn
F)
const {
F(Type, Value); }
2422 if (Type.size() > 3) {
2428 if (Value[0] ==
'n')
2429 OB <<
'-' << std::string_view(Value.data() + 1, Value.size() - 1);
2433 if (Type.size() <= 3)
2443 :
Node(KRequiresExpr), Parameters(Parameters_),
2444 Requirements(Requirements_) {}
2446 template<
typename Fn>
void match(Fn
F)
const {
F(Parameters, Requirements); }
2450 if (!Parameters.empty()) {
2453 Parameters.printWithComma(OB);
2458 for (
const Node *Req : Requirements) {
2469 const Node *TypeConstraint;
2472 const Node *TypeConstraint_)
2473 :
Node(KExprRequirement), Expr(Expr_), IsNoexcept(IsNoexcept_),
2474 TypeConstraint(TypeConstraint_) {}
2476 template <
typename Fn>
void match(Fn
F)
const {
2477 F(Expr, IsNoexcept, TypeConstraint);
2482 if (IsNoexcept || TypeConstraint)
2485 if (IsNoexcept || TypeConstraint)
2489 if (TypeConstraint) {
2491 TypeConstraint->
print(OB);
2501 :
Node(KTypeRequirement), Type(Type_) {}
2503 template <
typename Fn>
void match(Fn
F)
const {
F(Type); }
2513 const Node *Constraint;
2516 :
Node(KNestedRequirement), Constraint(Constraint_) {}
2518 template <
typename Fn>
void match(Fn
F)
const {
F(Constraint); }
2522 Constraint->
print(OB);
2531 return Node::KFloatLiteral;
2534 return Node::KDoubleLiteral;
2537 return Node::KLongDoubleLiteral;
2542 const std::string_view Contents;
2544 static constexpr Kind KindForClass =
2549 :
Node(KindForClass), Contents(Contents_) {}
2551 template<
typename Fn>
void match(Fn
F)
const {
F(Contents); }
2555 if (Contents.size() >=
N) {
2558 char buf[
sizeof(Float)];
2560 const char *t = Contents.data();
2561 const char *last = t +
N;
2563 for (; t != last; ++t, ++e) {
2564 unsigned d1 = isdigit(*t) ?
static_cast<unsigned>(*t -
'0')
2565 :
static_cast<unsigned>(*t -
'a' + 10);
2567 unsigned d0 = isdigit(*t) ?
static_cast<unsigned>(*t -
'0')
2568 :
static_cast<unsigned>(*t -
'a' + 10);
2569 *e =
static_cast<char>((d1 << 4) + d0);
2571#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
2572 std::reverse(buf, e);
2576 OB += std::string_view(num, n);
2587template<
typename Fn>
2592 return F(static_cast<const X *>(this));
2593#include "ItaniumNodes.def"
2601 template <> struct NodeKind<X> { \
2602 static constexpr Node::Kind Kind = Node::K##X; \
2603 static constexpr const char *name() { return #X; } \
2605#include "ItaniumNodes.def"
2627 size_t OldNumTemplateParamLists;
2632 : Parser(TheParser),
2692 void reset(
const char *First_,
const char *Last_) {
2701 for (
int I = 0;
I != 3; ++
I)
2711 size_t sz =
static_cast<size_t>(end - begin);
2713 Node **data =
new (mem)
Node *[sz];
2714 std::copy(begin, end, data);
2744 char look(
unsigned Lookahead = 0)
const {
2745 if (
static_cast<size_t>(
Last -
First) <= Lookahead)
2747 return First[Lookahead];
2765 return look() ==
'T' &&
2766 std::string_view(
"yptnk").find(
look(1)) != std::string_view::npos;
2816 for (;
I <
E; ++
I) {
2873 return *
this <
Other.Enc;
2876 return Enc[0] < Peek[0] || (
Enc[0] == Peek[0] &&
Enc[1] < Peek[1]);
2879 return Enc[0] == Peek[0] &&
Enc[1] == Peek[1];
2885 std::string_view Res =
Name;
2888 "operator name does not start with 'operator'");
2889 Res.remove_prefix(
sizeof(
"operator") - 1);
2891 Res.remove_prefix(1);
2924template <
typename Derived,
typename Alloc>
2927 return getDerived().parseNestedName(State);
2929 return getDerived().parseLocalName(State);
2931 Node *Result =
nullptr;
2932 bool IsSubst =
false;
2934 Result = getDerived().parseUnscopedName(State, &IsSubst);
2938 if (look() ==
'I') {
2943 Node *TA = getDerived().parseTemplateArgs(State !=
nullptr);
2948 Result = make<NameWithTemplateArgs>(Result, TA);
2949 }
else if (IsSubst) {
2960template <
typename Derived,
typename Alloc>
2962 if (!consumeIf(
'Z'))
2964 Node *Encoding = getDerived().parseEncoding();
2965 if (Encoding ==
nullptr || !consumeIf(
'E'))
2968 if (consumeIf(
's')) {
2970 auto *StringLitName = make<NameType>(
"string literal");
2973 return make<LocalName>(Encoding, StringLitName);
2980 if (consumeIf(
'd')) {
2982 if (!consumeIf(
'_'))
2984 Node *
N = getDerived().parseName(State);
2987 return make<LocalName>(Encoding,
N);
2990 Node *Entity = getDerived().parseName(State);
2991 if (Entity ==
nullptr)
2994 return make<LocalName>(Encoding, Entity);
3000template <
typename Derived,
typename Alloc>
3005 Node *Std =
nullptr;
3006 if (consumeIf(
"St")) {
3007 Std = make<NameType>(
"std");
3012 Node *Res =
nullptr;
3014 if (look() ==
'S') {
3015 Node *S = getDerived().parseSubstitution();
3018 if (S->
getKind() == Node::KModuleName)
3020 else if (IsSubst && Std ==
nullptr) {
3028 if (Res ==
nullptr || Std !=
nullptr) {
3029 Res = getDerived().parseUnqualifiedName(State, Std,
Module);
3041template <
typename Derived,
typename Alloc>
3044 if (getDerived().parseModuleNameOpt(
Module))
3047 bool IsMemberLikeFriend = Scope && consumeIf(
'F');
3052 if (look() >=
'1' && look() <=
'9') {
3053 Result = getDerived().parseSourceName(State);
3054 }
else if (look() ==
'U') {
3055 Result = getDerived().parseUnnamedTypeName(State);
3056 }
else if (consumeIf(
"DC")) {
3058 size_t BindingsBegin = Names.
size();
3060 Node *Binding = getDerived().parseSourceName(State);
3061 if (Binding ==
nullptr)
3064 }
while (!consumeIf(
'E'));
3065 Result = make<StructuredBindingName>(popTrailingNodeArray(BindingsBegin));
3066 }
else if (look() ==
'C' || look() ==
'D') {
3068 if (Scope ==
nullptr ||
Module !=
nullptr)
3070 Result = getDerived().parseCtorDtorName(Scope, State);
3072 Result = getDerived().parseOperatorName(State);
3075 if (Result !=
nullptr &&
Module !=
nullptr)
3076 Result = make<ModuleEntity>(
Module, Result);
3077 if (Result !=
nullptr)
3078 Result = getDerived().parseAbiTags(Result);
3079 if (Result !=
nullptr && IsMemberLikeFriend)
3080 Result = make<MemberLikeFriendName>(Scope, Result);
3081 else if (Result !=
nullptr && Scope !=
nullptr)
3082 Result = make<NestedName>(Scope, Result);
3092template <
typename Derived,
typename Alloc>
3095 while (consumeIf(
'W')) {
3096 bool IsPartition = consumeIf(
'P');
3097 Node *Sub = getDerived().parseSourceName(
nullptr);
3115template <
typename Derived,
typename Alloc>
3120 if (State !=
nullptr)
3121 TemplateParams.
clear();
3123 if (consumeIf(
"Ut")) {
3124 std::string_view Count = parseNumber();
3125 if (!consumeIf(
'_'))
3127 return make<UnnamedTypeName>(Count);
3129 if (consumeIf(
"Ul")) {
3131 TemplateParams.
size());
3134 size_t ParamsBegin = Names.
size();
3135 while (getDerived().isTemplateParamDecl()) {
3137 getDerived().parseTemplateParamDecl(LambdaTemplateParams.
params());
3142 NodeArray TempParams = popTrailingNodeArray(ParamsBegin);
3166 if (TempParams.
empty())
3169 Node *Requires1 =
nullptr;
3170 if (consumeIf(
'Q')) {
3171 Requires1 = getDerived().parseConstraintExpr();
3172 if (Requires1 ==
nullptr)
3176 if (!consumeIf(
"v")) {
3178 Node *
P = getDerived().parseType();
3182 }
while (look() !=
'E' && look() !=
'Q');
3184 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3186 Node *Requires2 =
nullptr;
3187 if (consumeIf(
'Q')) {
3188 Requires2 = getDerived().parseConstraintExpr();
3189 if (Requires2 ==
nullptr)
3193 if (!consumeIf(
'E'))
3196 std::string_view Count = parseNumber();
3197 if (!consumeIf(
'_'))
3199 return make<ClosureTypeName>(TempParams, Requires1, Params, Requires2,
3202 if (consumeIf(
"Ub")) {
3203 (void)parseNumber();
3204 if (!consumeIf(
'_'))
3206 return make<NameType>(
"'block-literal'");
3212template <
typename Derived,
typename Alloc>
3215 if (parsePositiveInteger(&Length))
3217 if (numLeft() < Length || Length == 0)
3219 std::string_view
Name(First, Length);
3222 return make<NameType>(
"(anonymous namespace)");
3223 return make<NameType>(
Name);
3227template <
typename Derived,
typename Alloc>
3239 "operator co_await"},
3248 "operator delete[]"},
3296 "reinterpret_cast"},
3308template <
typename Derived,
typename Alloc>
3314template <
typename Derived,
typename Alloc>
3322 size_t lower = 0u, upper = NumOps - 1;
3323 while (upper != lower) {
3324 size_t middle = (upper + lower) / 2;
3325 if (Ops[middle] < First)
3330 if (Ops[lower] != First)
3340template <
typename Derived,
typename Alloc>
3343 if (
const auto *Op = parseOperatorEncoding()) {
3344 if (Op->getKind() == OperatorInfo::CCast) {
3351 PermitForwardTemplateReferences ||
3353 Node *Ty = getDerived().parseType();
3357 return make<ConversionOperatorType>(Ty);
3360 if (Op->getKind() >= OperatorInfo::Unnameable)
3363 if (Op->getKind() == OperatorInfo::Member && !Op->getFlag())
3367 return make<NameType>(Op->getName());
3370 if (consumeIf(
"li")) {
3372 Node *SN = getDerived().parseSourceName(State);
3375 return make<LiteralOperator>(SN);
3378 if (consumeIf(
'v')) {
3380 if (look() >=
'0' && look() <=
'9') {
3382 Node *SN = getDerived().parseSourceName(State);
3385 return make<ConversionOperatorType>(SN);
3403template <
typename Derived,
typename Alloc>
3407 if (SoFar->
getKind() == Node::KSpecialSubstitution) {
3409 SoFar = make<ExpandedSpecialSubstitution>(
3415 if (consumeIf(
'C')) {
3416 bool IsInherited = consumeIf(
'I');
3417 if (look() !=
'1' && look() !=
'2' && look() !=
'3' && look() !=
'4' &&
3420 int Variant = look() -
'0';
3424 if (getDerived().parseName(State) ==
nullptr)
3427 return make<CtorDtorName>(SoFar,
false, Variant);
3430 if (look() ==
'D' && (look(1) ==
'0' || look(1) ==
'1' || look(1) ==
'2' ||
3431 look(1) ==
'4' || look(1) ==
'5')) {
3432 int Variant = look(1) -
'0';
3435 return make<CtorDtorName>(SoFar,
true, Variant);
3460template <
typename Derived,
typename Alloc>
3463 if (!consumeIf(
'N'))
3468 if (!consumeIf(
'H')) {
3473 if (consumeIf(
'O')) {
3476 }
else if (consumeIf(
'R')) {
3487 Node *SoFar =
nullptr;
3488 while (!consumeIf(
'E')) {
3493 if (look() ==
'T') {
3495 if (SoFar !=
nullptr)
3497 SoFar = getDerived().parseTemplateParam();
3498 }
else if (look() ==
'I') {
3500 if (SoFar ==
nullptr)
3502 Node *TA = getDerived().parseTemplateArgs(State !=
nullptr);
3505 if (SoFar->
getKind() == Node::KNameWithTemplateArgs)
3512 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3513 }
else if (look() ==
'D' && (look(1) ==
't' || look(1) ==
'T')) {
3515 if (SoFar !=
nullptr)
3517 SoFar = getDerived().parseDecltype();
3521 if (look() ==
'S') {
3524 if (look(1) ==
't') {
3526 S = make<NameType>(
"std");
3528 S = getDerived().parseSubstitution();
3532 if (S->
getKind() == Node::KModuleName) {
3534 }
else if (SoFar !=
nullptr) {
3543 SoFar = getDerived().parseUnqualifiedName(State, SoFar,
Module);
3546 if (SoFar ==
nullptr)
3555 if (SoFar ==
nullptr || Subs.
empty())
3563template <
typename Derived,
typename Alloc>
3565 Node *SN = getDerived().parseSourceName(
nullptr);
3568 if (look() ==
'I') {
3569 Node *TA = getDerived().parseTemplateArgs();
3572 return make<NameWithTemplateArgs>(SN, TA);
3579template <
typename Derived,
typename Alloc>
3582 if (std::isdigit(look()))
3583 Result = getDerived().parseSimpleId();
3585 Result = getDerived().parseUnresolvedType();
3586 if (Result ==
nullptr)
3588 return make<DtorName>(Result);
3594template <
typename Derived,
typename Alloc>
3596 if (look() ==
'T') {
3597 Node *TP = getDerived().parseTemplateParam();
3603 if (look() ==
'D') {
3604 Node *DT = getDerived().parseDecltype();
3610 return getDerived().parseSubstitution();
3620template <
typename Derived,
typename Alloc>
3622 if (std::isdigit(look()))
3623 return getDerived().parseSimpleId();
3625 if (consumeIf(
"dn"))
3626 return getDerived().parseDestructorName();
3630 Node *Oper = getDerived().parseOperatorName(
nullptr);
3631 if (Oper ==
nullptr)
3633 if (look() ==
'I') {
3634 Node *TA = getDerived().parseTemplateArgs();
3637 return make<NameWithTemplateArgs>(Oper, TA);
3654template <
typename Derived,
typename Alloc>
3656 Node *SoFar =
nullptr;
3660 if (consumeIf(
"srN")) {
3661 SoFar = getDerived().parseUnresolvedType();
3662 if (SoFar ==
nullptr)
3665 if (look() ==
'I') {
3666 Node *TA = getDerived().parseTemplateArgs();
3669 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3674 while (!consumeIf(
'E')) {
3675 Node *Qual = getDerived().parseSimpleId();
3676 if (Qual ==
nullptr)
3678 SoFar = make<QualifiedName>(SoFar, Qual);
3683 Node *Base = getDerived().parseBaseUnresolvedName();
3684 if (Base ==
nullptr)
3686 return make<QualifiedName>(SoFar, Base);
3690 if (!consumeIf(
"sr")) {
3691 SoFar = getDerived().parseBaseUnresolvedName();
3692 if (SoFar ==
nullptr)
3695 SoFar = make<GlobalQualifiedName>(SoFar);
3700 if (std::isdigit(look())) {
3702 Node *Qual = getDerived().parseSimpleId();
3703 if (Qual ==
nullptr)
3706 SoFar = make<QualifiedName>(SoFar, Qual);
3708 SoFar = make<GlobalQualifiedName>(Qual);
3713 }
while (!consumeIf(
'E'));
3718 SoFar = getDerived().parseUnresolvedType();
3719 if (SoFar ==
nullptr)
3722 if (look() ==
'I') {
3723 Node *TA = getDerived().parseTemplateArgs();
3726 SoFar = make<NameWithTemplateArgs>(SoFar, TA);
3734 Node *Base = getDerived().parseBaseUnresolvedName();
3735 if (Base ==
nullptr)
3737 return make<QualifiedName>(SoFar, Base);
3742template <
typename Derived,
typename Alloc>
3744 while (consumeIf(
'B')) {
3745 std::string_view SN = parseBareSourceName();
3748 N = make<AbiTagAttr>(
N, SN);
3756template <
typename Alloc,
typename Derived>
3759 const char *Tmp = First;
3762 if (numLeft() == 0 || !std::isdigit(*First))
3763 return std::string_view();
3764 while (numLeft() != 0 && std::isdigit(*First))
3766 return std::string_view(Tmp, First - Tmp);
3770template <
typename Alloc,
typename Derived>
3773 if (look() <
'0' || look() >
'9')
3775 while (look() >=
'0' && look() <=
'9') {
3777 *Out +=
static_cast<size_t>(
consume() -
'0');
3782template <
typename Alloc,
typename Derived>
3785 if (parsePositiveInteger(&
Int) || numLeft() <
Int)
3787 std::string_view R(First,
Int);
3800template <
typename Derived,
typename Alloc>
3804 Node *ExceptionSpec =
nullptr;
3805 if (consumeIf(
"Do")) {
3806 ExceptionSpec = make<NameType>(
"noexcept");
3809 }
else if (consumeIf(
"DO")) {
3810 Node *
E = getDerived().parseExpr();
3811 if (
E ==
nullptr || !consumeIf(
'E'))
3813 ExceptionSpec = make<NoexceptSpec>(
E);
3816 }
else if (consumeIf(
"Dw")) {
3817 size_t SpecsBegin = Names.
size();
3818 while (!consumeIf(
'E')) {
3819 Node *
T = getDerived().parseType();
3825 make<DynamicExceptionSpec>(popTrailingNodeArray(SpecsBegin));
3832 if (!consumeIf(
'F'))
3835 Node *ReturnType = getDerived().parseType();
3836 if (ReturnType ==
nullptr)
3840 size_t ParamsBegin = Names.
size();
3846 if (consumeIf(
"RE")) {
3850 if (consumeIf(
"OE")) {
3854 Node *
T = getDerived().parseType();
3860 NodeArray Params = popTrailingNodeArray(ParamsBegin);
3861 return make<FunctionType>(ReturnType, Params, CVQuals,
3862 ReferenceQualifier, ExceptionSpec);
3870template <
typename Derived,
typename Alloc>
3872 if (!consumeIf(
"Dv"))
3874 if (look() >=
'1' && look() <=
'9') {
3875 Node *DimensionNumber = make<NameType>(parseNumber());
3876 if (!DimensionNumber)
3878 if (!consumeIf(
'_'))
3881 return make<PixelVectorType>(DimensionNumber);
3882 Node *ElemType = getDerived().parseType();
3883 if (ElemType ==
nullptr)
3885 return make<VectorType>(ElemType, DimensionNumber);
3888 if (!consumeIf(
'_')) {
3889 Node *DimExpr = getDerived().parseExpr();
3892 if (!consumeIf(
'_'))
3894 Node *ElemType = getDerived().parseType();
3897 return make<VectorType>(ElemType, DimExpr);
3899 Node *ElemType = getDerived().parseType();
3902 return make<VectorType>(ElemType,
nullptr);
3907template <
typename Derived,
typename Alloc>
3909 if (!consumeIf(
'D'))
3911 if (!consumeIf(
't') && !consumeIf(
'T'))
3913 Node *
E = getDerived().parseExpr();
3916 if (!consumeIf(
'E'))
3918 return make<EnclosingExpr>(
"decltype",
E);
3923template <
typename Derived,
typename Alloc>
3925 if (!consumeIf(
'A'))
3928 Node *Dimension =
nullptr;
3930 if (std::isdigit(look())) {
3931 Dimension = make<NameType>(parseNumber());
3934 if (!consumeIf(
'_'))
3936 }
else if (!consumeIf(
'_')) {
3937 Node *DimExpr = getDerived().parseExpr();
3938 if (DimExpr ==
nullptr)
3940 if (!consumeIf(
'_'))
3942 Dimension = DimExpr;
3945 Node *Ty = getDerived().parseType();
3948 return make<ArrayType>(Ty, Dimension);
3952template <
typename Derived,
typename Alloc>
3954 if (!consumeIf(
'M'))
3956 Node *ClassType = getDerived().parseType();
3957 if (ClassType ==
nullptr)
3959 Node *MemberType = getDerived().parseType();
3960 if (MemberType ==
nullptr)
3962 return make<PointerToMemberType>(ClassType, MemberType);
3969template <
typename Derived,
typename Alloc>
3971 std::string_view ElabSpef;
3972 if (consumeIf(
"Ts"))
3973 ElabSpef =
"struct";
3974 else if (consumeIf(
"Tu"))
3976 else if (consumeIf(
"Te"))
3979 Node *
Name = getDerived().parseName();
3980 if (
Name ==
nullptr)
3983 if (!ElabSpef.empty())
3984 return make<ElaboratedTypeSpefType>(ElabSpef,
Name);
3992template <
typename Derived,
typename Alloc>
3994 if (consumeIf(
'U')) {
3995 std::string_view Qual = parseBareSourceName();
4001 constexpr size_t Len =
sizeof(
"objcproto") - 1;
4002 std::string_view ProtoSourceName(Qual.data() + Len, Qual.size() - Len);
4003 std::string_view Proto;
4006 SaveLast(Last, &*ProtoSourceName.rbegin() + 1);
4007 Proto = parseBareSourceName();
4011 Node *Child = getDerived().parseQualifiedType();
4012 if (Child ==
nullptr)
4014 return make<ObjCProtoName>(Child, Proto);
4018 if (look() ==
'I') {
4019 TA = getDerived().parseTemplateArgs();
4024 Node *Child = getDerived().parseQualifiedType();
4025 if (Child ==
nullptr)
4027 return make<VendorExtQualType>(Child, Qual, TA);
4031 Node *Ty = getDerived().parseType();
4035 Ty = make<QualType>(Ty, Quals);
4059template <
typename Derived,
typename Alloc>
4061 Node *Result =
nullptr;
4068 unsigned AfterQuals = 0;
4069 if (look(AfterQuals) ==
'r') ++AfterQuals;
4070 if (look(AfterQuals) ==
'V') ++AfterQuals;
4071 if (look(AfterQuals) ==
'K') ++AfterQuals;
4073 if (look(AfterQuals) ==
'F' ||
4074 (look(AfterQuals) ==
'D' &&
4075 (look(AfterQuals + 1) ==
'o' || look(AfterQuals + 1) ==
'O' ||
4076 look(AfterQuals + 1) ==
'w' || look(AfterQuals + 1) ==
'x'))) {
4077 Result = getDerived().parseFunctionType();
4083 Result = getDerived().parseQualifiedType();
4089 return make<NameType>(
"void");
4093 return make<NameType>(
"wchar_t");
4097 return make<NameType>(
"bool");
4101 return make<NameType>(
"char");
4105 return make<NameType>(
"signed char");
4109 return make<NameType>(
"unsigned char");
4113 return make<NameType>(
"short");
4117 return make<NameType>(
"unsigned short");
4121 return make<NameType>(
"int");
4125 return make<NameType>(
"unsigned int");
4129 return make<NameType>(
"long");
4133 return make<NameType>(
"unsigned long");
4137 return make<NameType>(
"long long");
4141 return make<NameType>(
"unsigned long long");
4145 return make<NameType>(
"__int128");
4149 return make<NameType>(
"unsigned __int128");
4153 return make<NameType>(
"float");
4157 return make<NameType>(
"double");
4161 return make<NameType>(
"long double");
4165 return make<NameType>(
"__float128");
4169 return make<NameType>(
"...");
4174 std::string_view Res = parseBareSourceName();
4180 if (consumeIf(
'I')) {
4184 if (!consumeIf(
'E'))
4186 Result = make<TransformedType>(Res,
BaseType);
4188 Result = make<NameType>(Res);
4196 return make<NameType>(
"decimal64");
4200 return make<NameType>(
"decimal128");
4204 return make<NameType>(
"decimal32");
4208 return make<NameType>(
"half");
4212 Node *DimensionNumber = make<NameType>(parseNumber());
4213 if (!DimensionNumber)
4215 if (!consumeIf(
'_'))
4217 return make<BinaryFPType>(DimensionNumber);
4225 bool Signed = look(1) ==
'B';
4227 Node *
Size = std::isdigit(look()) ? make<NameType>(parseNumber())
4228 : getDerived().parseExpr();
4231 if (!consumeIf(
'_'))
4238 return make<NameType>(
"char32_t");
4242 return make<NameType>(
"char16_t");
4246 return make<NameType>(
"char8_t");
4250 return make<NameType>(
"auto");
4254 return make<NameType>(
"decltype(auto)");
4259 std::string_view Kind = look(1) ==
'k' ?
" auto" :
" decltype(auto)";
4261 Node *Constraint = getDerived().parseName();
4264 return make<PostfixQualifiedType>(Constraint, Kind);
4269 return make<NameType>(
"std::nullptr_t");
4274 Result = getDerived().parseDecltype();
4279 Result = getDerived().parseVectorType();
4285 Node *Child = getDerived().parseType();
4288 Result = make<ParameterPackExpansion>(Child);
4297 Result = getDerived().parseFunctionType();
4303 Result = getDerived().parseFunctionType();
4308 Result = getDerived().parseArrayType();
4313 Result = getDerived().parsePointerToMemberType();
4319 if (look(1) ==
's' || look(1) ==
'u' || look(1) ==
'e') {
4320 Result = getDerived().parseClassEnumType();
4324 Result = getDerived().parseTemplateParam();
4325 if (Result ==
nullptr)
4338 if (TryToParseTemplateArgs && look() ==
'I') {
4339 Node *TA = getDerived().parseTemplateArgs();
4342 Result = make<NameWithTemplateArgs>(Result, TA);
4349 Node *
Ptr = getDerived().parseType();
4352 Result = make<PointerType>(
Ptr);
4358 Node *Ref = getDerived().parseType();
4367 Node *Ref = getDerived().parseType();
4376 Node *
P = getDerived().parseType();
4379 Result = make<PostfixQualifiedType>(
P,
" complex");
4385 Node *
P = getDerived().parseType();
4388 Result = make<PostfixQualifiedType>(
P,
" imaginary");
4393 if (look(1) !=
't') {
4394 bool IsSubst =
false;
4395 Result = getDerived().parseUnscopedName(
nullptr, &IsSubst);
4409 if (look() ==
'I' && (!IsSubst || TryToParseTemplateArgs)) {
4412 Node *TA = getDerived().parseTemplateArgs();
4415 Result = make<NameWithTemplateArgs>(Result, TA);
4416 }
else if (IsSubst) {
4427 Result = getDerived().parseClassEnumType();
4435 if (Result !=
nullptr)
4440template <
typename Derived,
typename Alloc>
4444 Node *
E = getDerived().parseExpr();
4447 return make<PrefixExpr>(Kind,
E, Prec);
4450template <
typename Derived,
typename Alloc>
4454 Node *
LHS = getDerived().parseExpr();
4457 Node *
RHS = getDerived().parseExpr();
4460 return make<BinaryExpr>(
LHS, Kind,
RHS, Prec);
4463template <
typename Derived,
typename Alloc>
4465 std::string_view Lit) {
4466 std::string_view Tmp = parseNumber(
true);
4467 if (!Tmp.empty() && consumeIf(
'E'))
4468 return make<IntegerLiteral>(Lit, Tmp);
4473template <
typename Alloc,
typename Derived>
4490template <
typename Derived,
typename Alloc>
4492 if (consumeIf(
"fpT"))
4493 return make<NameType>(
"this");
4494 if (consumeIf(
"fp")) {
4495 parseCVQualifiers();
4496 std::string_view Num = parseNumber();
4497 if (!consumeIf(
'_'))
4499 return make<FunctionParam>(Num);
4501 if (consumeIf(
"fL")) {
4502 if (parseNumber().empty())
4504 if (!consumeIf(
'p'))
4506 parseCVQualifiers();
4507 std::string_view Num = parseNumber();
4508 if (!consumeIf(
'_'))
4510 return make<FunctionParam>(Num);
4517template <
typename Derived,
typename Alloc>
4519 if (!consumeIf(
"cv"))
4524 Ty = getDerived().parseType();
4530 if (consumeIf(
'_')) {
4531 size_t ExprsBegin = Names.
size();
4532 while (!consumeIf(
'E')) {
4533 Node *
E = getDerived().parseExpr();
4538 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
4539 return make<ConversionExpr>(Ty, Exprs);
4542 Node *
E[1] = {getDerived().parseExpr()};
4543 if (
E[0] ==
nullptr)
4545 return make<ConversionExpr>(Ty, makeNodeArray(
E,
E + 1));
4555template <
typename Derived,
typename Alloc>
4557 if (!consumeIf(
'L'))
4562 return getDerived().parseIntegerLiteral(
"wchar_t");
4564 if (consumeIf(
"b0E"))
4565 return make<BoolExpr>(0);
4566 if (consumeIf(
"b1E"))
4567 return make<BoolExpr>(1);
4571 return getDerived().parseIntegerLiteral(
"char");
4574 return getDerived().parseIntegerLiteral(
"signed char");
4577 return getDerived().parseIntegerLiteral(
"unsigned char");
4580 return getDerived().parseIntegerLiteral(
"short");
4583 return getDerived().parseIntegerLiteral(
"unsigned short");
4586 return getDerived().parseIntegerLiteral(
"");
4589 return getDerived().parseIntegerLiteral(
"u");
4592 return getDerived().parseIntegerLiteral(
"l");
4595 return getDerived().parseIntegerLiteral(
"ul");
4598 return getDerived().parseIntegerLiteral(
"ll");
4601 return getDerived().parseIntegerLiteral(
"ull");
4604 return getDerived().parseIntegerLiteral(
"__int128");
4607 return getDerived().parseIntegerLiteral(
"unsigned __int128");
4610 return getDerived().template parseFloatingLiteral<float>();
4613 return getDerived().template parseFloatingLiteral<double>();
4616#if defined(__powerpc__) || defined(__s390__)
4619 return getDerived().template parseFloatingLiteral<double>();
4621 return getDerived().template parseFloatingLiteral<long double>();
4624 if (consumeIf(
"_Z")) {
4625 Node *R = getDerived().parseEncoding();
4626 if (R !=
nullptr && consumeIf(
'E'))
4631 Node *
T = getDerived().parseType();
4636 return make<StringLiteral>(
T);
4640 if (consumeIf(
"Dn") && (consumeIf(
'0'), consumeIf(
'E')))
4641 return make<NameType>(
"nullptr");
4651 Node *
T = parseUnnamedTypeName(
nullptr);
4652 if (!
T || !consumeIf(
'E'))
4654 return make<LambdaExpr>(
T);
4658 Node *
T = getDerived().parseType();
4661 std::string_view
N = parseNumber(
true);
4664 if (!consumeIf(
'E'))
4666 return make<EnumLiteral>(
T,
N);
4675template <
typename Derived,
typename Alloc>
4677 if (look() ==
'd') {
4681 Node *
Field = getDerived().parseSourceName(
nullptr);
4682 if (
Field ==
nullptr)
4684 Node *Init = getDerived().parseBracedExpr();
4685 if (Init ==
nullptr)
4687 return make<BracedExpr>(
Field, Init,
false);
4692 if (
Index ==
nullptr)
4694 Node *Init = getDerived().parseBracedExpr();
4695 if (Init ==
nullptr)
4697 return make<BracedExpr>(
Index, Init,
true);
4701 Node *RangeBegin = getDerived().parseExpr();
4702 if (RangeBegin ==
nullptr)
4704 Node *RangeEnd = getDerived().parseExpr();
4705 if (RangeEnd ==
nullptr)
4707 Node *Init = getDerived().parseBracedExpr();
4708 if (Init ==
nullptr)
4710 return make<BracedRangeExpr>(RangeBegin, RangeEnd, Init);
4714 return getDerived().parseExpr();
4722template <
typename Derived,
typename Alloc>
4724 if (!consumeIf(
'f'))
4727 bool IsLeftFold =
false, HasInitializer =
false;
4733 HasInitializer =
true;
4736 HasInitializer =
true;
4746 const auto *Op = parseOperatorEncoding();
4749 if (!(Op->getKind() == OperatorInfo::Binary
4750 || (Op->getKind() == OperatorInfo::Member
4751 && Op->getName().back() ==
'*')))
4754 Node *Pack = getDerived().parseExpr();
4755 if (Pack ==
nullptr)
4758 Node *Init =
nullptr;
4759 if (HasInitializer) {
4760 Init = getDerived().parseExpr();
4761 if (Init ==
nullptr)
4765 if (IsLeftFold && Init)
4768 return make<FoldExpr>(IsLeftFold, Op->getSymbol(), Pack, Init);
4774template <
typename Derived,
typename Alloc>
4778 Node *Ty = getDerived().parseType();
4781 Node *Expr = getDerived().parseExpr();
4784 std::string_view
Offset = getDerived().parseNumber(
true);
4785 if (!consumeIf(
'E'))
4787 return make<PointerToMemberConversionExpr>(Ty, Expr,
Offset, Prec);
4794template <
typename Derived,
typename Alloc>
4796 Node *Ty = getDerived().parseType();
4799 Node *Expr = getDerived().parseExpr();
4802 std::string_view
Offset = getDerived().parseNumber(
true);
4803 size_t SelectorsBegin = Names.
size();
4804 while (consumeIf(
'_')) {
4805 Node *Selector = make<NameType>(parseNumber());
4810 bool OnePastTheEnd = consumeIf(
'p');
4811 if (!consumeIf(
'E'))
4813 return make<SubobjectExpr>(
4814 Ty, Expr,
Offset, popTrailingNodeArray(SelectorsBegin), OnePastTheEnd);
4817template <
typename Derived,
typename Alloc>
4822 return getDerived().parseExpr();
4825template <
typename Derived,
typename Alloc>
4828 if (consumeIf(
"rQ")) {
4830 size_t ParamsBegin = Names.
size();
4831 while (!consumeIf(
'_')) {
4832 Node *
Type = getDerived().parseType();
4833 if (
Type ==
nullptr)
4837 Params = popTrailingNodeArray(ParamsBegin);
4838 }
else if (!consumeIf(
"rq")) {
4843 size_t ReqsBegin = Names.
size();
4845 Node *Constraint =
nullptr;
4846 if (consumeIf(
'X')) {
4848 Node *Expr = getDerived().parseExpr();
4849 if (Expr ==
nullptr)
4851 bool Noexcept = consumeIf(
'N');
4852 Node *TypeReq =
nullptr;
4853 if (consumeIf(
'R')) {
4854 TypeReq = getDerived().parseName();
4855 if (TypeReq ==
nullptr)
4858 Constraint = make<ExprRequirement>(Expr, Noexcept, TypeReq);
4859 }
else if (consumeIf(
'T')) {
4861 Node *
Type = getDerived().parseType();
4862 if (
Type ==
nullptr)
4864 Constraint = make<TypeRequirement>(
Type);
4865 }
else if (consumeIf(
'Q')) {
4873 Node *NestedReq = getDerived().parseExpr();
4874 if (NestedReq ==
nullptr)
4876 Constraint = make<NestedRequirement>(NestedReq);
4878 if (Constraint ==
nullptr)
4881 }
while (!consumeIf(
'E'));
4883 return make<RequiresExpr>(Params, popTrailingNodeArray(ReqsBegin));
4930template <
typename Derived,
typename Alloc>
4932 bool Global = consumeIf(
"gs");
4934 const auto *Op = parseOperatorEncoding();
4936 auto Sym = Op->getSymbol();
4937 switch (Op->getKind()) {
4938 case OperatorInfo::Binary:
4940 return getDerived().parseBinaryExpr(
Sym, Op->getPrecedence());
4941 case OperatorInfo::Prefix:
4943 return getDerived().parsePrefixExpr(
Sym, Op->getPrecedence());
4944 case OperatorInfo::Postfix: {
4947 return getDerived().parsePrefixExpr(
Sym, Op->getPrecedence());
4948 Node *Ex = getDerived().parseExpr();
4951 return make<PostfixExpr>(Ex,
Sym, Op->getPrecedence());
4953 case OperatorInfo::Array: {
4955 Node *Base = getDerived().parseExpr();
4956 if (Base ==
nullptr)
4959 if (
Index ==
nullptr)
4961 return make<ArraySubscriptExpr>(Base,
Index, Op->getPrecedence());
4963 case OperatorInfo::Member: {
4965 Node *
LHS = getDerived().parseExpr();
4968 Node *
RHS = getDerived().parseExpr();
4971 return make<MemberExpr>(
LHS,
Sym,
RHS, Op->getPrecedence());
4973 case OperatorInfo::New: {
4979 size_t Exprs = Names.
size();
4980 while (!consumeIf(
'_')) {
4981 Node *Ex = getDerived().parseExpr();
4986 NodeArray ExprList = popTrailingNodeArray(Exprs);
4987 Node *Ty = getDerived().parseType();
4990 bool HaveInits = consumeIf(
"pi");
4991 size_t InitsBegin = Names.
size();
4992 while (!consumeIf(
'E')) {
4995 Node *Init = getDerived().parseExpr();
4996 if (Init ==
nullptr)
5000 NodeArray Inits = popTrailingNodeArray(InitsBegin);
5001 return make<NewExpr>(ExprList, Ty, Inits, Global,
5002 Op->getFlag(), Op->getPrecedence());
5004 case OperatorInfo::Del: {
5006 Node *Ex = getDerived().parseExpr();
5009 return make<DeleteExpr>(Ex, Global, Op->getFlag(),
5010 Op->getPrecedence());
5012 case OperatorInfo::Call: {
5014 Node *Callee = getDerived().parseExpr();
5015 if (Callee ==
nullptr)
5017 size_t ExprsBegin = Names.
size();
5018 while (!consumeIf(
'E')) {
5019 Node *
E = getDerived().parseExpr();
5024 return make<CallExpr>(Callee, popTrailingNodeArray(ExprsBegin),
5025 Op->getPrecedence());
5027 case OperatorInfo::CCast: {
5032 Ty = getDerived().parseType();
5037 size_t ExprsBegin = Names.
size();
5038 bool IsMany = consumeIf(
'_');
5039 while (!consumeIf(
'E')) {
5040 Node *
E = getDerived().parseExpr();
5047 NodeArray Exprs = popTrailingNodeArray(ExprsBegin);
5048 if (!IsMany && Exprs.
size() != 1)
5050 return make<ConversionExpr>(Ty, Exprs, Op->getPrecedence());
5052 case OperatorInfo::Conditional: {
5054 Node *
Cond = getDerived().parseExpr();
5055 if (
Cond ==
nullptr)
5057 Node *
LHS = getDerived().parseExpr();
5060 Node *
RHS = getDerived().parseExpr();
5063 return make<ConditionalExpr>(
Cond,
LHS,
RHS, Op->getPrecedence());
5065 case OperatorInfo::NamedCast: {
5067 Node *Ty = getDerived().parseType();
5070 Node *Ex = getDerived().parseExpr();
5073 return make<CastExpr>(
Sym, Ty, Ex, Op->getPrecedence());
5075 case OperatorInfo::OfIdOp: {
5078 Op->getFlag() ? getDerived().parseType() : getDerived().parseExpr();
5081 return make<EnclosingExpr>(
Sym, Arg, Op->getPrecedence());
5083 case OperatorInfo::NameOnly: {
5095 return getDerived().parseExprPrimary();
5097 return getDerived().parseTemplateParam();
5098 if (look() ==
'f') {
5100 if (look(1) ==
'p' || (look(1) ==
'L' && std::isdigit(look(2))))
5101 return getDerived().parseFunctionParam();
5102 return getDerived().parseFoldExpr();
5104 if (consumeIf(
"il")) {
5105 size_t InitsBegin = Names.
size();
5106 while (!consumeIf(
'E')) {
5107 Node *
E = getDerived().parseBracedExpr();
5112 return make<InitListExpr>(
nullptr, popTrailingNodeArray(InitsBegin));
5114 if (consumeIf(
"mc"))
5116 if (consumeIf(
"nx")) {
5117 Node *Ex = getDerived().parseExpr();
5122 if (look() ==
'r' && (look(1) ==
'q' || look(1) ==
'Q'))
5123 return parseRequiresExpr();
5124 if (consumeIf(
"so"))
5125 return parseSubobjectExpr();
5126 if (consumeIf(
"sp")) {
5127 Node *Child = getDerived().parseExpr();
5128 if (Child ==
nullptr)
5130 return make<ParameterPackExpansion>(Child);
5132 if (consumeIf(
"sZ")) {
5133 if (look() ==
'T') {
5134 Node *R = getDerived().parseTemplateParam();
5137 return make<SizeofParamPackExpr>(R);
5139 Node *
FP = getDerived().parseFunctionParam();
5142 return make<EnclosingExpr>(
"sizeof... ",
FP);
5144 if (consumeIf(
"sP")) {
5145 size_t ArgsBegin = Names.
size();
5146 while (!consumeIf(
'E')) {
5147 Node *Arg = getDerived().parseTemplateArg();
5152 auto *Pack = make<NodeArrayNode>(popTrailingNodeArray(ArgsBegin));
5155 return make<EnclosingExpr>(
"sizeof... ", Pack);
5157 if (consumeIf(
"tl")) {
5158 Node *Ty = getDerived().parseType();
5161 size_t InitsBegin = Names.
size();
5162 while (!consumeIf(
'E')) {
5163 Node *
E = getDerived().parseBracedExpr();
5168 return make<InitListExpr>(Ty, popTrailingNodeArray(InitsBegin));
5170 if (consumeIf(
"tr"))
5171 return make<NameType>(
"throw");
5172 if (consumeIf(
"tw")) {
5173 Node *Ex = getDerived().parseExpr();
5176 return make<ThrowExpr>(Ex);
5178 if (consumeIf(
'u')) {
5179 Node *
Name = getDerived().parseSourceName(
nullptr);
5187 bool IsUUID =
false;
5189 if (
Name->getBaseName() ==
"__uuidof") {
5190 if (consumeIf(
't')) {
5191 UUID = getDerived().parseType();
5193 }
else if (consumeIf(
'z')) {
5194 UUID = getDerived().parseExpr();
5198 size_t ExprsBegin = Names.
size();
5200 if (
UUID ==
nullptr)
5204 while (!consumeIf(
'E')) {
5205 Node *
E = getDerived().parseTemplateArg();
5211 return make<CallExpr>(
Name, popTrailingNodeArray(ExprsBegin),
5216 return getDerived().parseUnresolvedName(Global);
5227template <
typename Alloc,
typename Derived>
5232 return parseNumber(
true).empty() || !consumeIf(
'_');
5234 return parseNumber(
true).empty() || !consumeIf(
'_') ||
5235 parseNumber(
true).empty() || !consumeIf(
'_');
5260template <
typename Derived,
typename Alloc>
5270 Node *Arg = getDerived().parseTemplateArg();
5273 return make<SpecialName>(
"template parameter object for ", Arg);
5278 Node *Ty = getDerived().parseType();
5281 return make<SpecialName>(
"vtable for ", Ty);
5286 Node *Ty = getDerived().parseType();
5289 return make<SpecialName>(
"VTT for ", Ty);
5294 Node *Ty = getDerived().parseType();
5297 return make<SpecialName>(
"typeinfo for ", Ty);
5302 Node *Ty = getDerived().parseType();
5305 return make<SpecialName>(
"typeinfo name for ", Ty);
5310 if (parseCallOffset() || parseCallOffset())
5312 Node *Encoding = getDerived().parseEncoding();
5313 if (Encoding ==
nullptr)
5315 return make<SpecialName>(
"covariant return thunk to ", Encoding);
5321 Node *FirstType = getDerived().parseType();
5322 if (FirstType ==
nullptr)
5324 if (parseNumber(
true).empty() || !consumeIf(
'_'))
5326 Node *SecondType = getDerived().parseType();
5327 if (SecondType ==
nullptr)
5329 return make<CtorVtableSpecialName>(SecondType, FirstType);
5334 Node *
Name = getDerived().parseName();
5335 if (
Name ==
nullptr)
5337 return make<SpecialName>(
"thread-local wrapper routine for ",
Name);
5342 Node *
Name = getDerived().parseName();
5343 if (
Name ==
nullptr)
5345 return make<SpecialName>(
"thread-local initialization routine for ",
Name);
5350 bool IsVirt = look() ==
'v';
5351 if (parseCallOffset())
5353 Node *BaseEncoding = getDerived().parseEncoding();
5354 if (BaseEncoding ==
nullptr)
5357 return make<SpecialName>(
"virtual thunk to ", BaseEncoding);
5359 return make<SpecialName>(
"non-virtual thunk to ", BaseEncoding);
5367 Node *
Name = getDerived().parseName();
5368 if (
Name ==
nullptr)
5370 return make<SpecialName>(
"guard variable for ",
Name);
5377 Node *
Name = getDerived().parseName();
5378 if (
Name ==
nullptr)
5381 bool ParsedSeqId = !parseSeqId(&Count);
5382 if (!consumeIf(
'_') && ParsedSeqId)
5384 return make<SpecialName>(
"reference temporary for ",
Name);
5390 if (getDerived().parseModuleNameOpt(
Module))
5394 return make<SpecialName>(
"initializer for module ",
Module);
5405template <
typename Derived,
typename Alloc>
5411 if (look() ==
'G' || look() ==
'T')
5412 return getDerived().parseSpecialName();
5414 auto IsEndOfEncoding = [&] {
5418 return numLeft() == 0 || look() ==
'E' || look() ==
'.' || look() ==
'_';
5422 Node *
Name = getDerived().parseName(&NameInfo);
5423 if (
Name ==
nullptr)
5426 if (resolveForwardTemplateRefs(NameInfo))
5429 if (IsEndOfEncoding())
5442 Node *Attrs =
nullptr;
5443 if (consumeIf(
"Ua9enable_ifI")) {
5444 size_t BeforeArgs = Names.
size();
5445 while (!consumeIf(
'E')) {
5446 Node *Arg = getDerived().parseTemplateArg();
5451 Attrs = make<EnableIfAttr>(popTrailingNodeArray(BeforeArgs));
5456 Node *ReturnType =
nullptr;
5458 ReturnType = getDerived().parseType();
5459 if (ReturnType ==
nullptr)
5464 if (!consumeIf(
'v')) {
5465 size_t ParamsBegin = Names.
size();
5467 Node *Ty = getDerived().parseType();
5471 const bool IsFirstParam = ParamsBegin == Names.
size();
5473 Ty = make<ExplicitObjectParameter>(Ty);
5479 }
while (!IsEndOfEncoding() && look() !=
'Q');
5480 Params = popTrailingNodeArray(ParamsBegin);
5483 Node *Requires =
nullptr;
5484 if (consumeIf(
'Q')) {
5485 Requires = getDerived().parseConstraintExpr();
5490 return make<FunctionEncoding>(ReturnType,
Name, Params, Attrs, Requires,
5495template <
class Float>
5501 static const size_t mangled_size = 8;
5502 static const size_t max_demangled_size = 24;
5503 static constexpr const char* spec =
"%af";
5509 static const size_t mangled_size = 16;
5510 static const size_t max_demangled_size = 32;
5511 static constexpr const char* spec =
"%a";
5517#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
5518 defined(__wasm__) || defined(__riscv) || defined(__loongarch__) || \
5520 static const size_t mangled_size = 32;
5521#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
5522 static const size_t mangled_size = 16;
5524 static const size_t mangled_size = 20;
5531 static const size_t max_demangled_size = 42;
5532 static constexpr const char *spec =
"%LaL";
5535template <
typename Alloc,
typename Derived>
5536template <
class Float>
5541 std::string_view Data(First,
N);
5543 if (!(
C >=
'0' &&
C <=
'9') && !(
C >=
'a' &&
C <=
'f'))
5546 if (!consumeIf(
'E'))
5548 return make<FloatLiteralImpl<Float>>(Data);
5552template <
typename Alloc,
typename Derived>
5554 if (!(look() >=
'0' && look() <=
'9') &&
5555 !(look() >=
'A' && look() <=
'Z'))
5560 if (look() >=
'0' && look() <=
'9') {
5562 Id +=
static_cast<size_t>(look() -
'0');
5563 }
else if (look() >=
'A' && look() <=
'Z') {
5565 Id +=
static_cast<size_t>(look() -
'A') + 10;
5585template <
typename Derived,
typename Alloc>
5587 if (!consumeIf(
'S'))
5590 if (look() >=
'a' && look() <=
'z') {
5615 auto *SpecialSub = make<SpecialSubstitution>(Kind);
5622 Node *WithTags = getDerived().parseAbiTags(SpecialSub);
5623 if (WithTags != SpecialSub) {
5625 SpecialSub = WithTags;
5631 if (consumeIf(
'_')) {
5639 if (parseSeqId(&
Index))
5642 if (!consumeIf(
'_') ||
Index >= Subs.
size())
5651template <
typename Derived,
typename Alloc>
5653 const char *Begin = First;
5654 if (!consumeIf(
'T'))
5658 if (consumeIf(
'L')) {
5659 if (parsePositiveInteger(&Level))
5662 if (!consumeIf(
'_'))
5667 if (!consumeIf(
'_')) {
5668 if (parsePositiveInteger(&
Index))
5671 if (!consumeIf(
'_'))
5679 if (InConstraintExpr) {
5680 return make<NameType>(std::string_view(Begin, First - 1 - Begin));
5687 if (PermitForwardTemplateReferences && Level == 0) {
5688 Node *ForwardRef = make<ForwardTemplateReference>(
Index);
5698 if (Level >= TemplateParams.
size() || !TemplateParams[Level] ||
5699 Index >= TemplateParams[Level]->
size()) {
5702 if (ParsingLambdaParamsAtLevel == Level && Level <= TemplateParams.
size()) {
5705 if (Level == TemplateParams.
size())
5707 return make<NameType>(
"auto");
5713 return (*TemplateParams[Level])[
Index];
5721template <
typename Derived,
typename Alloc>
5725 unsigned Index = NumSyntheticTemplateParameters[(int)Kind]++;
5726 Node *
N = make<SyntheticTemplateParamName>(Kind,
Index);
5732 if (consumeIf(
"Ty")) {
5736 return make<TypeTemplateParamDecl>(
Name);
5739 if (consumeIf(
"Tk")) {
5740 Node *Constraint = getDerived().parseName();
5746 return make<ConstrainedTypeTemplateParamDecl>(Constraint,
Name);
5749 if (consumeIf(
"Tn")) {
5756 return make<NonTypeTemplateParamDecl>(
Name,
Type);
5759 if (consumeIf(
"Tt")) {
5763 size_t ParamsBegin = Names.
size();
5765 Node *Requires =
nullptr;
5766 while (!consumeIf(
'E')) {
5767 Node *
P = parseTemplateParamDecl(TemplateTemplateParamParams.
params());
5771 if (consumeIf(
'Q')) {
5772 Requires = getDerived().parseConstraintExpr();
5773 if (Requires ==
nullptr || !consumeIf(
'E'))
5778 NodeArray InnerParams = popTrailingNodeArray(ParamsBegin);
5779 return make<TemplateTemplateParamDecl>(
Name, InnerParams, Requires);
5782 if (consumeIf(
"Tp")) {
5783 Node *
P = parseTemplateParamDecl(Params);
5786 return make<TemplateParamPackDecl>(
P);
5798template <
typename Derived,
typename Alloc>
5803 Node *Arg = getDerived().parseExpr();
5804 if (Arg ==
nullptr || !consumeIf(
'E'))
5810 size_t ArgsBegin = Names.
size();
5811 while (!consumeIf(
'E')) {
5812 Node *Arg = getDerived().parseTemplateArg();
5817 NodeArray Args = popTrailingNodeArray(ArgsBegin);
5818 return make<TemplateArgumentPack>(Args);
5822 if (look(1) ==
'Z') {
5824 Node *Arg = getDerived().parseEncoding();
5825 if (Arg ==
nullptr || !consumeIf(
'E'))
5830 return getDerived().parseExprPrimary();
5834 if (!getDerived().isTemplateParamDecl())
5835 return getDerived().parseType();
5836 Node *Param = getDerived().parseTemplateParamDecl(
nullptr);
5839 Node *Arg = getDerived().parseTemplateArg();
5842 return make<TemplateParamQualifiedArg>(Param, Arg);
5845 return getDerived().parseType();
5851template <
typename Derived,
typename Alloc>
5854 if (!consumeIf(
'I'))
5860 TemplateParams.
clear();
5861 TemplateParams.
push_back(&OuterTemplateParams);
5862 OuterTemplateParams.
clear();
5865 size_t ArgsBegin = Names.
size();
5866 Node *Requires =
nullptr;
5867 while (!consumeIf(
'E')) {
5869 Node *Arg = getDerived().parseTemplateArg();
5874 if (Arg->
getKind() == Node::KTemplateParamQualifiedArg) {
5878 if (Arg->
getKind() == Node::KTemplateArgumentPack) {
5886 Node *Arg = getDerived().parseTemplateArg();
5891 if (consumeIf(
'Q')) {
5892 Requires = getDerived().parseConstraintExpr();
5893 if (!Requires || !consumeIf(
'E'))
5898 return make<TemplateArgs>(popTrailingNodeArray(ArgsBegin), Requires);
5906template <
typename Derived,
typename Alloc>
5908 if (consumeIf(
"_Z") || consumeIf(
"__Z")) {
5909 Node *Encoding = getDerived().parseEncoding(ParseParams);
5910 if (Encoding ==
nullptr)
5912 if (look() ==
'.') {
5914 make<DotSuffix>(Encoding, std::string_view(First, Last - First));
5922 if (consumeIf(
"___Z") || consumeIf(
"____Z")) {
5923 Node *Encoding = getDerived().parseEncoding(ParseParams);
5924 if (Encoding ==
nullptr || !consumeIf(
"_block_invoke"))
5926 bool RequireNumber = consumeIf(
'_');
5927 if (parseNumber().empty() && RequireNumber)
5933 return make<SpecialName>(
"invocation function for block in ", Encoding);
5936 Node *Ty = getDerived().parseType();
5942template <
typename Alloc>
5950#if defined(__clang__)
5951#pragma clang diagnostic pop
BlockVerifier::State From
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live value
#define DEMANGLE_DUMP_METHOD
#define DEMANGLE_FALLTHROUGH
#define DEMANGLE_NAMESPACE_END
#define DEMANGLE_ASSERT(__expr, __msg)
#define DEMANGLE_NAMESPACE_BEGIN
#define DEMANGLE_UNREACHABLE
std::optional< std::vector< StOtherPiece > > Other
Qualifiers operator|=(Qualifiers &Q1, Qualifiers Q2)
const char * parse_discriminator(const char *first, const char *last)
Machine Check Debug Module
static StringRef getName(Value *V)
const SmallVectorImpl< MachineOperand > & Cond
std::pair< llvm::MachO::Target, std::string > UUID
static bool consume(InternalInstruction *insn, T &ptr)
SaveTemplateParams(AbstractManglingParser *TheParser)
TemplateParamList * params()
~ScopedTemplateParamList()
ScopedTemplateParamList(AbstractManglingParser *TheParser)
void printLeft(OutputBuffer &OB) const override
ArraySubscriptExpr(const Node *Op1_, const Node *Op2_, Prec Prec_)
void printRight(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
bool hasArraySlow(OutputBuffer &) const override
ArrayType(const Node *Base_, Node *Dimension_)
bool hasRHSComponentSlow(OutputBuffer &) const override
BinaryExpr(const Node *LHS_, std::string_view InfixOperator_, const Node *RHS_, Prec Prec_)
void printLeft(OutputBuffer &OB) const override
BinaryFPType(const Node *Dimension_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
BitIntType(const Node *Size_, bool Signed_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
BracedExpr(const Node *Elem_, const Node *Init_, bool IsArray_)
void printLeft(OutputBuffer &OB) const override
BracedRangeExpr(const Node *First_, const Node *Last_, const Node *Init_)
CallExpr(const Node *Callee_, NodeArray Args_, Prec Prec_)
void printLeft(OutputBuffer &OB) const override
CastExpr(std::string_view CastKind_, const Node *To_, const Node *From_, Prec Prec_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
void printDeclarator(OutputBuffer &OB) const
ClosureTypeName(NodeArray TemplateParams_, const Node *Requires1_, NodeArray Params_, const Node *Requires2_, std::string_view Count_)
void printLeft(OutputBuffer &OB) const override
ConditionalExpr(const Node *Cond_, const Node *Then_, const Node *Else_, Prec Prec_)
A constrained template type parameter declaration, 'C T'.
ConstrainedTypeTemplateParamDecl(Node *Constraint_, Node *Name_)
void printRight(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
ConversionExpr(const Node *Type_, NodeArray Expressions_, Prec Prec_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
ConversionOperatorType(const Node *Ty_)
CtorDtorName(const Node *Basename_, bool IsDtor_, int Variant_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
CtorVtableSpecialName(const Node *FirstType_, const Node *SecondType_)
void printLeft(OutputBuffer &OB) const override
DeleteExpr(Node *Op_, bool IsGlobal_, bool IsArray_, Prec Prec_)
DotSuffix(const Node *Prefix_, std::string_view Suffix_)
void printLeft(OutputBuffer &OB) const override
DtorName(const Node *Base_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
DynamicExceptionSpec(NodeArray Types_)
ElaboratedTypeSpefType(std::string_view Kind_, Node *Child_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
EnableIfAttr(NodeArray Conditions_)
void printLeft(OutputBuffer &OB) const override
EnclosingExpr(std::string_view Prefix_, const Node *Infix_, Prec Prec_=Prec::Primary)
void printLeft(OutputBuffer &OB) const override
EnumLiteral(const Node *Ty_, std::string_view Integer_)
std::string_view getBaseName() const override
bool isInstantiation() const
ExpandedSpecialSubstitution(SpecialSubKind SSK_)
ExpandedSpecialSubstitution(SpecialSubKind SSK_, Kind K_)
Represents the explicitly named object parameter.
ExplicitObjectParameter(Node *Base_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
ExprRequirement(const Node *Expr_, bool IsNoexcept_, const Node *TypeConstraint_)
void printLeft(OutputBuffer &OB) const override
FloatLiteralImpl(std::string_view Contents_)
void printLeft(OutputBuffer &OB) const override
FoldExpr(bool IsLeftFold_, std::string_view OperatorName_, const Node *Pack_, const Node *Init_)
void printRight(OutputBuffer &OB) const override
Qualifiers getCVQuals() const
FunctionRefQual getRefQual() const
const Node * getReturnType() const
bool hasRHSComponentSlow(OutputBuffer &) const override
void printLeft(OutputBuffer &OB) const override
const Node * getName() const
bool hasFunctionSlow(OutputBuffer &) const override
FunctionEncoding(const Node *Ret_, const Node *Name_, NodeArray Params_, const Node *Attrs_, const Node *Requires_, Qualifiers CVQuals_, FunctionRefQual RefQual_)
NodeArray getParams() const
void printLeft(OutputBuffer &OB) const override
FunctionParam(std::string_view Number_)
void printLeft(OutputBuffer &OB) const override
FunctionType(const Node *Ret_, NodeArray Params_, Qualifiers CVQuals_, FunctionRefQual RefQual_, const Node *ExceptionSpec_)
bool hasRHSComponentSlow(OutputBuffer &) const override
void printRight(OutputBuffer &OB) const override
bool hasFunctionSlow(OutputBuffer &) const override
GlobalQualifiedName(Node *Child_)
std::string_view getBaseName() const override
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
InitListExpr(const Node *Ty_, NodeArray Inits_)
IntegerLiteral(std::string_view Type_, std::string_view Value_)
void printLeft(OutputBuffer &OB) const override
LambdaExpr(const Node *Type_)
void printLeft(OutputBuffer &OB) const override
LiteralOperator(const Node *OpName_)
void printLeft(OutputBuffer &OB) const override
MemberExpr(const Node *LHS_, std::string_view Kind_, const Node *RHS_, Prec Prec_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
NameType(std::string_view Name_)
std::string_view getBaseName() const override
std::string_view getName() const
void printLeft(OutputBuffer &OB) const override
NestedRequirement(const Node *Constraint_)
NewExpr(NodeArray ExprList_, Node *Type_, NodeArray InitList_, bool IsGlobal_, bool IsArray_, Prec Prec_)
void printLeft(OutputBuffer &OB) const override
NodeArray(Node **Elements_, size_t NumElements_)
void printWithComma(OutputBuffer &OB) const
Node * operator[](size_t Idx) const
void print(OutputBuffer &OB) const
Prec getPrecedence() const
virtual void printLeft(OutputBuffer &) const =0
void visit(Fn F) const
Visit the most-derived object corresponding to this object.
void printAsOperand(OutputBuffer &OB, Prec P=Prec::Default, bool StrictlyWorse=false) const
Node(Kind K_, Cache RHSComponentCache_, Cache ArrayCache_=Cache::No, Cache FunctionCache_=Cache::No)
bool hasRHSComponent(OutputBuffer &OB) const
DEMANGLE_DUMP_METHOD void dump() const
bool hasFunction(OutputBuffer &OB) const
Node(Kind K_, Prec Precedence_=Prec::Primary, Cache RHSComponentCache_=Cache::No, Cache ArrayCache_=Cache::No, Cache FunctionCache_=Cache::No)
Cache getRHSComponentCache() const
bool hasArray(OutputBuffer &OB) const
Cache getArrayCache() const
virtual bool hasRHSComponentSlow(OutputBuffer &) const
Cache ArrayCache
Track if this node is a (possibly qualified) array type.
virtual bool hasArraySlow(OutputBuffer &) const
Prec
Operator precedence for expression nodes.
virtual std::string_view getBaseName() const
virtual const Node * getSyntaxNode(OutputBuffer &) const
virtual bool hasFunctionSlow(OutputBuffer &) const
Cache getFunctionCache() const
virtual void printRight(OutputBuffer &) const
Cache RHSComponentCache
Tracks if this node has a component on its right side, in which case we need to call printRight.
Cache
Three-way bool to track a cached value.
Cache FunctionCache
Track if this node is a (possibly qualified) function type.
NoexceptSpec(const Node *E_)
void printLeft(OutputBuffer &OB) const override
A non-type template parameter declaration, 'int N'.
void printRight(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
NonTypeTemplateParamDecl(Node *Name_, Node *Type_)
bool isObjCObject() const
ObjCProtoName(const Node *Ty_, std::string_view Protocol_)
void printLeft(OutputBuffer &OB) const override
PODSmallVector & operator=(PODSmallVector &&Other)
PODSmallVector(const PODSmallVector &)=delete
void push_back(const T &Elem)
PODSmallVector & operator=(const PODSmallVector &)=delete
PODSmallVector(PODSmallVector &&Other)
void shrinkToSize(size_t Index)
T & operator[](size_t Index)
const Node * getChild() const
ParameterPackExpansion(const Node *Child_)
void printLeft(OutputBuffer &OB) const override
An unexpanded parameter pack (either in the expression or type context).
ParameterPack(NodeArray Data_)
void printRight(OutputBuffer &OB) const override
bool hasArraySlow(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
const Node * getSyntaxNode(OutputBuffer &OB) const override
bool hasFunctionSlow(OutputBuffer &OB) const override
bool hasRHSComponentSlow(OutputBuffer &OB) const override
PixelVectorType(const Node *Dimension_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
PointerToMemberConversionExpr(const Node *Type_, const Node *SubExpr_, std::string_view Offset_, Prec Prec_)
void printRight(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
bool hasRHSComponentSlow(OutputBuffer &OB) const override
PointerToMemberType(const Node *ClassType_, const Node *MemberType_)
bool hasRHSComponentSlow(OutputBuffer &OB) const override
PointerType(const Node *Pointee_)
const Node * getPointee() const
void printRight(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
PostfixExpr(const Node *Child_, std::string_view Operator_, Prec Prec_)
void printLeft(OutputBuffer &OB) const override
PostfixQualifiedType(const Node *Ty_, std::string_view Postfix_)
void printLeft(OutputBuffer &OB) const override
PrefixExpr(std::string_view Prefix_, Node *Child_, Prec Prec_)
void printLeft(OutputBuffer &OB) const override
bool hasFunctionSlow(OutputBuffer &OB) const override
QualType(const Node *Child_, Qualifiers Quals_)
void printLeft(OutputBuffer &OB) const override
void printQuals(OutputBuffer &OB) const
Qualifiers getQuals() const
void printRight(OutputBuffer &OB) const override
const Node * getChild() const
bool hasRHSComponentSlow(OutputBuffer &OB) const override
bool hasArraySlow(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
std::string_view getBaseName() const override
QualifiedName(const Node *Qualifier_, const Node *Name_)
void printLeft(OutputBuffer &OB) const override
bool hasRHSComponentSlow(OutputBuffer &OB) const override
ReferenceType(const Node *Pointee_, ReferenceKind RK_)
void printRight(OutputBuffer &OB) const override
RequiresExpr(NodeArray Parameters_, NodeArray Requirements_)
void printLeft(OutputBuffer &OB) const override
SizeofParamPackExpr(const Node *Pack_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
SpecialName(std::string_view Special_, const Node *Child_)
std::string_view getBaseName() const override
SpecialSubstitution(SpecialSubKind SSK_)
void printLeft(OutputBuffer &OB) const override
StringLiteral(const Node *Type_)
void printLeft(OutputBuffer &OB) const override
StructuredBindingName(NodeArray Bindings_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
SubobjectExpr(const Node *Type_, const Node *SubExpr_, std::string_view Offset_, NodeArray UnionSelectors_, bool OnePastTheEnd_)
An invented name for a template parameter for which we don't have a corresponding template argument.
void printLeft(OutputBuffer &OB) const override
SyntheticTemplateParamName(TemplateParamKind Kind_, unsigned Index_)
TemplateArgs(NodeArray Params_, Node *Requires_)
void printLeft(OutputBuffer &OB) const override
A variadic template argument.
void printLeft(OutputBuffer &OB) const override
TemplateArgumentPack(NodeArray Elements_)
NodeArray getElements() const
A template parameter pack declaration, 'typename ...T'.
void printRight(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
TemplateParamPackDecl(Node *Param_)
TemplateParamQualifiedArg(Node *Param_, Node *Arg_)
void printLeft(OutputBuffer &OB) const override
A template template parameter declaration, 'template<typename T> typename N'.
void printLeft(OutputBuffer &OB) const override
TemplateTemplateParamDecl(Node *Name_, NodeArray Params_, Node *Requires_)
void printRight(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
ThrowExpr(const Node *Op_)
TypeRequirement(const Node *Type_)
void printLeft(OutputBuffer &OB) const override
A template type parameter declaration, 'typename T'.
void printLeft(OutputBuffer &OB) const override
TypeTemplateParamDecl(Node *Name_)
void printRight(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
UnnamedTypeName(std::string_view Count_)
VectorType(const Node *BaseType_, const Node *Dimension_)
const Node * getDimension() const
void printLeft(OutputBuffer &OB) const override
const Node * getBaseType() const
VendorExtQualType(const Node *Ty_, std::string_view Ext_, const Node *TA_)
void printLeft(OutputBuffer &OB) const override
std::string_view getExt() const
const Node * getTA() const
const Node * getTy() const
constexpr Node::Kind getFloatLiteralKind(float *)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
void printLeft(OutputBuffer &OB) const override
AbiTagAttr(Node *Base_, std::string_view Tag_)
std::string_view getBaseName() const override
Holds some extra information about a <name> that is being parsed.
bool HasExplicitObjectParameter
bool EndsWithTemplateArgs
NameState(AbstractManglingParser *Enclosing)
size_t ForwardTemplateRefsBegin
FunctionRefQual ReferenceQualifier
constexpr OperatorInfo(const char(&E)[3], OIKind K, bool F, Node::Prec P, const char *N)
Node::Prec getPrecedence() const
bool operator<(const OperatorInfo &Other) const
std::string_view getName() const
bool operator==(const char *Peek) const
bool operator!=(const char *Peek) const
bool operator<(const char *Peek) const
std::string_view getSymbol() const
bool parseModuleNameOpt(ModuleName *&Module)
Node * parseSubstitution()
PODSmallVector< Node *, 32 > Subs
Node * parseFloatingLiteral()
void reset(const char *First_, const char *Last_)
Node * parseClassEnumType()
Node * parseBaseUnresolvedName()
Node * parseSubobjectExpr()
PODSmallVector< ForwardTemplateReference *, 4 > ForwardTemplateRefs
Node * parseConversionExpr()
PODSmallVector< Node *, 32 > Names
Node * parseConstraintExpr()
bool isTemplateParamDecl()
Node * parseTemplateArgs(bool TagTemplates=false)
Node * parseSpecialName()
Node * parseTemplateParam()
Node * parseType()
Parse the <type> production.
Node * parseTemplateParamDecl(TemplateParamList *Params)
Qualifiers parseCVQualifiers()
Node * parsePrefixExpr(std::string_view Kind, Node::Prec Prec)
bool PermitForwardTemplateReferences
Node * parseUnresolvedName(bool Global)
Parse the <unresolved-name> production.
Node * parsePointerToMemberConversionExpr(Node::Prec Prec)
Node * parsePointerToMemberType()
bool resolveForwardTemplateRefs(NameState &State)
Node * parseIntegerLiteral(std::string_view Lit)
Node * make(Args &&... args)
bool parseSeqId(size_t *Out)
Node * parseEncoding(bool ParseParams=true)
Node * parseName(NameState *State=nullptr)
Parse the <name> production>
Node * parseBinaryExpr(std::string_view Kind, Node::Prec Prec)
std::string_view parseNumber(bool AllowNegative=false)
TemplateParamList OuterTemplateParams
Node * parse(bool ParseParams=true)
Top-level entry point into the parser.
Node * parseFunctionType()
Node * parseDestructorName()
NodeArray makeNodeArray(It begin, It end)
Node * parseLocalName(NameState *State)
AbstractManglingParser(const char *First_, const char *Last_)
Node * parseRequiresExpr()
char look(unsigned Lookahead=0) const
bool parsePositiveInteger(size_t *Out)
Node * parseExprPrimary()
Node * parseQualifiedType()
Node * parseCtorDtorName(Node *&SoFar, NameState *State)
Node * parseExpr()
Parse the <expression> production.
Node * parseAbiTags(Node *N)
static const OperatorInfo Ops[]
Node * parseNestedName(NameState *State)
unsigned NumSyntheticTemplateParameters[3]
Node * parseSourceName(NameState *State)
Node * parseUnscopedName(NameState *State, bool *isSubstName)
size_t ParsingLambdaParamsAtLevel
Node * parseTemplateArg()
bool TryToParseTemplateArgs
bool consumeIf(std::string_view S)
Node * parseUnqualifiedName(NameState *State, Node *Scope, ModuleName *Module)
std::string_view parseBareSourceName()
NodeArray popTrailingNodeArray(size_t FromPosition)
Node * parseFunctionParam()
PODSmallVector< TemplateParamList *, 4 > TemplateParams
const OperatorInfo * parseOperatorEncoding()
Node * parseUnresolvedType()
Node * parseOperatorName(NameState *State)
Node * parseUnnamedTypeName(NameState *State)
static const size_t NumOps
A forward-reference to a template argument that was not known at the point where the template paramet...
const Node * getSyntaxNode(OutputBuffer &OB) const override
bool hasRHSComponentSlow(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
bool hasFunctionSlow(OutputBuffer &OB) const override
bool hasArraySlow(OutputBuffer &OB) const override
void printRight(OutputBuffer &OB) const override
ForwardTemplateReference(size_t Index_)
void match(Fn F) const =delete
LocalName(Node *Encoding_, Node *Entity_)
void printLeft(OutputBuffer &OB) const override
std::string_view getBaseName() const override
MemberLikeFriendName(Node *Qual_, Node *Name_)
void printLeft(OutputBuffer &OB) const override
std::string_view getBaseName() const override
void printLeft(OutputBuffer &OB) const override
ModuleEntity(ModuleName *Module_, Node *Name_)
void printLeft(OutputBuffer &OB) const override
ModuleName(ModuleName *Parent_, Node *Name_, bool IsPartition_=false)
void printLeft(OutputBuffer &OB) const override
std::string_view getBaseName() const override
NameWithTemplateArgs(Node *Name_, Node *TemplateArgs_)
std::string_view getBaseName() const override
NestedName(Node *Qual_, Node *Name_)
void printLeft(OutputBuffer &OB) const override
void printLeft(OutputBuffer &OB) const override
NodeArrayNode(NodeArray Array_)
Determine the kind of a node from its type.