Skip to content

Commit bcbaf5a

Browse files
committed
[WIP][Clang] Mangling of pack indexing type and expression for itanium
1 parent 7dd34ba commit bcbaf5a

File tree

6 files changed

+134
-14
lines changed

6 files changed

+134
-14
lines changed

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ class CXXNameMangler {
603603
void mangleInitListElements(const InitListExpr *InitList);
604604
void mangleRequirement(SourceLocation RequiresExprLoc,
605605
const concepts::Requirement *Req);
606+
void mangleReferenceToPack(const NamedDecl* ND);
606607
void mangleExpression(const Expr *E, unsigned Arity = UnknownArity,
607608
bool AsTemplateArg = false);
608609
void mangleCXXCtorType(CXXCtorType T, const CXXRecordDecl *InheritedFrom);
@@ -4348,8 +4349,12 @@ void CXXNameMangler::mangleType(const PackExpansionType *T) {
43484349
}
43494350

43504351
void CXXNameMangler::mangleType(const PackIndexingType *T) {
4351-
if (!T->hasSelectedType())
4352+
// <type> ::= Dy <type> <expression> # pack indexing type (C++23)
4353+
if (!T->hasSelectedType()) {
4354+
Out << "Dy";
43524355
mangleType(T->getPattern());
4356+
mangleExpression(T->getIndexExpr());
4357+
}
43534358
else
43544359
mangleType(T->getSelectedType());
43554360
}
@@ -4785,6 +4790,19 @@ void CXXNameMangler::mangleRequirement(SourceLocation RequiresExprLoc,
47854790
}
47864791
}
47874792

4793+
void CXXNameMangler::mangleReferenceToPack(const NamedDecl* Pack) {
4794+
if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Pack))
4795+
mangleTemplateParameter(TTP->getDepth(), TTP->getIndex());
4796+
else if (const NonTypeTemplateParmDecl *NTTP
4797+
= dyn_cast<NonTypeTemplateParmDecl>(Pack))
4798+
mangleTemplateParameter(NTTP->getDepth(), NTTP->getIndex());
4799+
else if (const TemplateTemplateParmDecl *TempTP
4800+
= dyn_cast<TemplateTemplateParmDecl>(Pack))
4801+
mangleTemplateParameter(TempTP->getDepth(), TempTP->getIndex());
4802+
else
4803+
mangleFunctionParam(cast<ParmVarDecl>(Pack));
4804+
}
4805+
47884806
void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
47894807
bool AsTemplateArg) {
47904808
// <expression> ::= <unary operator-name> <expression>
@@ -4803,6 +4821,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
48034821
// ::= fpT # 'this' expression (part of <function-param>)
48044822
// ::= sr <type> <unqualified-name> # dependent name
48054823
// ::= sr <type> <unqualified-name> <template-args> # dependent template-id
4824+
// ::= sy <expression> <expression> # pack indexing expression
48064825
// ::= ds <expression> <expression> # expr.*expr
48074826
// ::= sZ <template-param> # size of a parameter pack
48084827
// ::= sZ <function-param> # size of a function parameter pack
@@ -4886,7 +4905,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
48864905
case Expr::OMPIteratorExprClass:
48874906
case Expr::CXXInheritedCtorInitExprClass:
48884907
case Expr::CXXParenListInitExprClass:
4889-
case Expr::PackIndexingExprClass:
48904908
llvm_unreachable("unexpected statement kind");
48914909

48924910
case Expr::ConstantExprClass:
@@ -5788,17 +5806,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
57885806
}
57895807

57905808
Out << "sZ";
5791-
const NamedDecl *Pack = SPE->getPack();
5792-
if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Pack))
5793-
mangleTemplateParameter(TTP->getDepth(), TTP->getIndex());
5794-
else if (const NonTypeTemplateParmDecl *NTTP
5795-
= dyn_cast<NonTypeTemplateParmDecl>(Pack))
5796-
mangleTemplateParameter(NTTP->getDepth(), NTTP->getIndex());
5797-
else if (const TemplateTemplateParmDecl *TempTP
5798-
= dyn_cast<TemplateTemplateParmDecl>(Pack))
5799-
mangleTemplateParameter(TempTP->getDepth(), TempTP->getIndex());
5800-
else
5801-
mangleFunctionParam(cast<ParmVarDecl>(Pack));
5809+
mangleReferenceToPack(SPE->getPack());
58025810
break;
58035811
}
58045812

@@ -5828,6 +5836,19 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
58285836
break;
58295837
}
58305838

5839+
case Expr::PackIndexingExprClass: {
5840+
auto *PE = cast<PackIndexingExpr>(E);
5841+
if(PE->isFullySubstituted()) {
5842+
E = PE->getSelectedExpr();
5843+
goto recurse;
5844+
}
5845+
NotPrimaryExpr();
5846+
Out << "sy";
5847+
mangleReferenceToPack(PE->getPackDecl());
5848+
mangleExpression(PE->getIndexExpr());
5849+
break;
5850+
}
5851+
58315852
case Expr::CXXThisExprClass:
58325853
NotPrimaryExpr();
58335854
Out << "fpT";

libcxxabi/src/demangle/ItaniumDemangle.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,29 @@ class ParameterPackExpansion final : public Node {
15211521
}
15221522
};
15231523

1524+
class PackIndexing final : public Node {
1525+
const Node *Pattern;
1526+
const Node *Index;
1527+
1528+
public:
1529+
PackIndexing(const Node *Pattern_, const Node *Index_)
1530+
: Node(KPackIndexing), Pattern(Pattern_), Index(Index_) {}
1531+
1532+
template <typename Fn> void match(Fn F) const {
1533+
F(Pattern, Index);
1534+
}
1535+
1536+
void printLeft(OutputBuffer &OB) const override {
1537+
OB.printOpen('(');
1538+
ParameterPackExpansion PPE(Pattern);
1539+
PPE.printLeft(OB);
1540+
OB.printClose(')');
1541+
OB.printOpen('[');
1542+
Index->printLeft(OB);
1543+
OB.printClose(']');
1544+
}
1545+
};
1546+
15241547
class TemplateArgs final : public Node {
15251548
NodeArray Params;
15261549
Node *Requires;
@@ -4510,6 +4533,18 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
45104533
Result = make<ParameterPackExpansion>(Child);
45114534
break;
45124535
}
4536+
// ::= Dy <type> <expression> # pack indexing (C++26)
4537+
case 'y': {
4538+
First += 2;
4539+
Node *Pattern = getDerived().parseType();
4540+
if (!Pattern)
4541+
return nullptr;
4542+
Node *Index = getDerived().parseExpr();
4543+
if (!Index)
4544+
return nullptr;
4545+
Result = make<PackIndexing>(Pattern, Index);
4546+
break;
4547+
}
45134548
// Exception specifier on a function type.
45144549
case 'o':
45154550
case 'O':
@@ -5354,6 +5389,15 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
53545389
return nullptr;
53555390
return make<ParameterPackExpansion>(Child);
53565391
}
5392+
if (consumeIf("sy")) {
5393+
Node *Pattern = getDerived().parseExpr();
5394+
if (Pattern == nullptr)
5395+
return nullptr;
5396+
Node *Index = getDerived().parseExpr();
5397+
if (Index == nullptr)
5398+
return nullptr;
5399+
return make<PackIndexing>(Pattern, Index);
5400+
}
53575401
if (consumeIf("sZ")) {
53585402
if (look() == 'T') {
53595403
Node *R = getDerived().parseTemplateParam();

libcxxabi/src/demangle/ItaniumNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,5 @@ NODE(ExprRequirement)
100100
NODE(TypeRequirement)
101101
NODE(NestedRequirement)
102102
NODE(ExplicitObjectParameter)
103-
103+
NODE(PackIndexing)
104104
#undef NODE

libcxxabi/test/test_demangle.pass.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30220,6 +30220,11 @@ const char* cases[][2] = {
3022030220
{"_ZZNH3Foo3fooES_iENK4Foo24foo2Ev", "Foo::foo(this Foo, int)::Foo2::foo2() const" },
3022130221
{"_ZNH3FooclERKS_", "Foo::operator()(this Foo const&)"},
3022230222

30223+
30224+
// C++26 pack indexing
30225+
{"_Z3fooILi0ETpTnDaJLi1ELi2EEEDTsyT0_T_Ev", "decltype((1, 2...)[0]) foo<0, 1, 2>()"},
30226+
{"_Z1gILi0EJciEEDyT0_T_v", "(char, int)[0] g<0, char, int>()"},
30227+
3022330228
// fixed-point types as defined in the N1169 draft of ISO/IEC DTR 18037
3022430229
{"_Z1fDAs", "f(short _Accum)"},
3022530230
{"_Z1fDAt", "f(unsigned short _Accum)"},

llvm/include/llvm/Demangle/ItaniumDemangle.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,30 @@ class ParameterPackExpansion final : public Node {
15211521
}
15221522
};
15231523

1524+
/// A pack expansion. Below this node, there are some unexpanded ParameterPacks
1525+
/// which each have Child->ParameterPackSize elements.
1526+
class PackIndexing final : public Node {
1527+
const Node *Pattern;
1528+
const Node *Index;
1529+
1530+
public:
1531+
PackIndexing(const Node *Pattern_, const Node *Index_)
1532+
: Node(KPackIndexing), Pattern(Pattern_), Index(Index_) {}
1533+
1534+
template <typename Fn> void match(Fn F) const {
1535+
F(Pattern, Index);
1536+
}
1537+
1538+
void printLeft(OutputBuffer &OB) const override {
1539+
ParameterPackExpansion PPE(Pattern);
1540+
PPE.printLeft(OB);
1541+
OB += "...[";
1542+
Index->print(OB);
1543+
OB += "]";
1544+
}
1545+
};
1546+
1547+
15241548
class TemplateArgs final : public Node {
15251549
NodeArray Params;
15261550
Node *Requires;
@@ -4510,6 +4534,20 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() {
45104534
Result = make<ParameterPackExpansion>(Child);
45114535
break;
45124536
}
4537+
// ::= Dy <type> <expression> # pack indexing (C++26)
4538+
case 'y': {
4539+
First += 2;
4540+
Node *Pattern = look() == 'T' ?
4541+
getDerived().parseTemplateParam()
4542+
: getDerived().parseFunctionParam();
4543+
if (Pattern == nullptr)
4544+
return nullptr;
4545+
Node *Index = getDerived().parseExpr();
4546+
if (Index == nullptr)
4547+
return nullptr;
4548+
Result = make<PackIndexing>(Pattern, Index);
4549+
break;
4550+
}
45134551
// Exception specifier on a function type.
45144552
case 'o':
45154553
case 'O':
@@ -5354,6 +5392,17 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() {
53545392
return nullptr;
53555393
return make<ParameterPackExpansion>(Child);
53565394
}
5395+
if (consumeIf("sy")) {
5396+
Node *Pattern = look() == 'T' ?
5397+
getDerived().parseTemplateParam()
5398+
: getDerived().parseFunctionParam();
5399+
if (Pattern == nullptr)
5400+
return nullptr;
5401+
Node *Index = getDerived().parseExpr();
5402+
if (Index == nullptr)
5403+
return nullptr;
5404+
return make<PackIndexing>(Pattern, Index);
5405+
}
53575406
if (consumeIf("sZ")) {
53585407
if (look() == 'T') {
53595408
Node *R = getDerived().parseTemplateParam();

llvm/include/llvm/Demangle/ItaniumNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,6 @@ NODE(ExprRequirement)
100100
NODE(TypeRequirement)
101101
NODE(NestedRequirement)
102102
NODE(ExplicitObjectParameter)
103+
NODE(PackIndexing)
103104

104105
#undef NODE

0 commit comments

Comments
 (0)