-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[Clang] Mangling of pack indexing type and expression for itanium #123513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -603,6 +603,7 @@ class CXXNameMangler { | |
void mangleInitListElements(const InitListExpr *InitList); | ||
void mangleRequirement(SourceLocation RequiresExprLoc, | ||
const concepts::Requirement *Req); | ||
void mangleReferenceToPack(const NamedDecl *ND); | ||
void mangleExpression(const Expr *E, unsigned Arity = UnknownArity, | ||
bool AsTemplateArg = false); | ||
void mangleCXXCtorType(CXXCtorType T, const CXXRecordDecl *InheritedFrom); | ||
|
@@ -4348,10 +4349,10 @@ void CXXNameMangler::mangleType(const PackExpansionType *T) { | |
} | ||
|
||
void CXXNameMangler::mangleType(const PackIndexingType *T) { | ||
if (!T->hasSelectedType()) | ||
mangleType(T->getPattern()); | ||
else | ||
mangleType(T->getSelectedType()); | ||
// <type> ::= Dy <type> <expression> # pack indexing type (C++23) | ||
Out << "Dy"; | ||
mangleType(T->getPattern()); | ||
mangleExpression(T->getIndexExpr()); | ||
} | ||
|
||
void CXXNameMangler::mangleType(const ObjCInterfaceType *T) { | ||
|
@@ -4787,6 +4788,7 @@ void CXXNameMangler::mangleRequirement(SourceLocation RequiresExprLoc, | |
|
||
void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, | ||
bool AsTemplateArg) { | ||
// clang-format off | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Why turning it off? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
// <expression> ::= <unary operator-name> <expression> | ||
// ::= <binary operator-name> <expression> <expression> | ||
// ::= <trinary operator-name> <expression> <expression> <expression> | ||
|
@@ -4806,6 +4808,8 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, | |
// ::= ds <expression> <expression> # expr.*expr | ||
// ::= sZ <template-param> # size of a parameter pack | ||
// ::= sZ <function-param> # size of a function parameter pack | ||
// ::= sy <template-param> <expression> # pack indexing expression | ||
// ::= sy <function-param> <expression> # pack indexing expression | ||
// ::= u <source-name> <template-arg>* E # vendor extended expression | ||
// ::= <expr-primary> | ||
// <expr-primary> ::= L <type> <value number> E # integer literal | ||
|
@@ -4815,6 +4819,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, | |
// ::= L <pointer type> 0 E # null pointer template argument | ||
// ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C99); not used by clang | ||
// ::= L <mangled-name> E # external name | ||
// clang-format on | ||
QualType ImplicitlyConvertedToType; | ||
|
||
// A top-level expression that's not <expr-primary> needs to be wrapped in | ||
|
@@ -4886,7 +4891,6 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, | |
case Expr::OMPIteratorExprClass: | ||
case Expr::CXXInheritedCtorInitExprClass: | ||
case Expr::CXXParenListInitExprClass: | ||
case Expr::PackIndexingExprClass: | ||
llvm_unreachable("unexpected statement kind"); | ||
|
||
case Expr::ConstantExprClass: | ||
|
@@ -5788,17 +5792,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, | |
} | ||
|
||
Out << "sZ"; | ||
const NamedDecl *Pack = SPE->getPack(); | ||
if (const TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Pack)) | ||
mangleTemplateParameter(TTP->getDepth(), TTP->getIndex()); | ||
else if (const NonTypeTemplateParmDecl *NTTP | ||
= dyn_cast<NonTypeTemplateParmDecl>(Pack)) | ||
mangleTemplateParameter(NTTP->getDepth(), NTTP->getIndex()); | ||
else if (const TemplateTemplateParmDecl *TempTP | ||
= dyn_cast<TemplateTemplateParmDecl>(Pack)) | ||
mangleTemplateParameter(TempTP->getDepth(), TempTP->getIndex()); | ||
else | ||
mangleFunctionParam(cast<ParmVarDecl>(Pack)); | ||
mangleReferenceToPack(SPE->getPack()); | ||
break; | ||
} | ||
|
||
|
@@ -5828,6 +5822,15 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, | |
break; | ||
} | ||
|
||
case Expr::PackIndexingExprClass: { | ||
auto *PE = cast<PackIndexingExpr>(E); | ||
NotPrimaryExpr(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am looking at the test cases and I don't see the |
||
Out << "sy"; | ||
mangleReferenceToPack(PE->getPackDecl()); | ||
mangleExpression(PE->getIndexExpr()); | ||
break; | ||
} | ||
|
||
case Expr::CXXThisExprClass: | ||
NotPrimaryExpr(); | ||
Out << "fpT"; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu -std=c++2c | FileCheck %s | ||
|
||
namespace GH112003 { | ||
|
||
// CHECK-LABEL: define {{.*}} @_ZN8GH1120033fooILi0ETpTnDaJLi0ELi0EEEEDTsyT0_T_Ev | ||
// CHECK-LABEL: define {{.*}} @_ZN8GH1120033fooILi1ETpTnDaJLi0ELi0EEEEDTsyT0_T_Ev | ||
// CHECK-LABEL: define {{.*}} @_ZN8GH1120033fooILi0ETpTnDaJLl1EEEEDTsyT0_T_Ev | ||
template <int I, auto...V> | ||
decltype(V...[I]) foo() {return {};} | ||
|
||
// CHECK-LABEL: define {{.*}} @_ZN8GH1120033barILi0EJilEEEDyT0_T_v | ||
// CHECK-LABEL: define {{.*}} @_ZN8GH1120033barILi1EJilEEEDyT0_T_v | ||
template <int I, typename...V> | ||
V...[I] bar() {return {};} | ||
|
||
|
||
template <int I, typename... T> | ||
using First = T...[0]; | ||
|
||
// CHECK-LABEL: define {{.*}} @_ZN8GH1120033bazILi0EJiEEEvDy_SUBSTPACK_Li0E | ||
// FIXME: handle indexing of partially substituted packs | ||
template <int I, typename...V> | ||
void baz(First<I, int, V...>){}; | ||
|
||
|
||
void fn() { | ||
foo<0, 0, 0>(); | ||
foo<1, 0, 0>(); | ||
foo<0, 1L>(); | ||
bar<0, int, long>(); | ||
bar<1, int, long>(); | ||
baz<0, int>(0); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30220,6 +30220,11 @@ const char* cases[][2] = { | |
{"_ZZNH3Foo3fooES_iENK4Foo24foo2Ev", "Foo::foo(this Foo, int)::Foo2::foo2() const" }, | ||
{"_ZNH3FooclERKS_", "Foo::operator()(this Foo const&)"}, | ||
|
||
|
||
// C++26 pack indexing | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add invalid cases as well see |
||
{"_Z3fooILi0ETpTnDaJLi1ELi2EEEDTsyT0_T_Ev", "decltype((1, 2...)[0]) foo<0, 1, 2>()"}, | ||
{"_Z1gILi0EJciEEDyT0_T_v", "(char, int)[0] g<0, char, int>()"}, | ||
|
||
// fixed-point types as defined in the N1169 draft of ISO/IEC DTR 18037 | ||
{"_Z1fDAs", "f(short _Accum)"}, | ||
{"_Z1fDAt", "f(unsigned short _Accum)"}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should live in
C++2c support
section, as this isn't strictly a bug.