llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: cor3ntin (cor3ntin) <details> <summary>Changes</summary> See https://github.com/itanium-cxx-abi/cxx-abi/pull/198 and #<!-- -->112003 --- Full diff: https://github.com/llvm/llvm-project/pull/123513.diff 8 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/lib/AST/ItaniumMangle.cpp (+58-31) - (added) clang/test/CodeGenCXX/mangle-cxx2c.cpp (+11) - (modified) libcxxabi/src/demangle/ItaniumDemangle.h (+43) - (modified) libcxxabi/src/demangle/ItaniumNodes.def (+1-1) - (modified) libcxxabi/test/test_demangle.pass.cpp (+5) - (modified) llvm/include/llvm/Demangle/ItaniumDemangle.h (+43) - (modified) llvm/include/llvm/Demangle/ItaniumNodes.def (+1-1) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b63bd366cfe884..e5946fc71c56a6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -1003,6 +1003,7 @@ Bug Fixes to C++ Support lambda functions or inline friend functions defined inside templates (#GH122493). - Clang now rejects declaring an alias template with the same name as its template parameter. (#GH123423) - Correctly determine the implicit constexprness of lambdas in dependent contexts. (#GH97958) (#GH114234) +- Implement Itanium mangling for pack indexing. (#GH112003) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 1dd936cf4fb518..4b2cb630e16f87 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -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) { @@ -4785,35 +4786,63 @@ void CXXNameMangler::mangleRequirement(SourceLocation RequiresExprLoc, } } +void CXXNameMangler::mangleReferenceToPack(const NamedDecl *Pack) { + if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Pack)) + mangleTemplateParameter(TTP->getDepth(), TTP->getIndex()); + else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Pack)) + mangleTemplateParameter(NTTP->getDepth(), NTTP->getIndex()); + else if (const auto *TempTP = dyn_cast<TemplateTemplateParmDecl>(Pack)) + mangleTemplateParameter(TempTP->getDepth(), TempTP->getIndex()); + else + mangleFunctionParam(cast<ParmVarDecl>(Pack)); +} + void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, bool AsTemplateArg) { // <expression> ::= <unary operator-name> <expression> // ::= <binary operator-name> <expression> <expression> - // ::= <trinary operator-name> <expression> <expression> <expression> - // ::= cv <type> expression # conversion with one argument - // ::= cv <type> _ <expression>* E # conversion with a different number of arguments - // ::= dc <type> <expression> # dynamic_cast<type> (expression) - // ::= sc <type> <expression> # static_cast<type> (expression) - // ::= cc <type> <expression> # const_cast<type> (expression) - // ::= rc <type> <expression> # reinterpret_cast<type> (expression) + // ::= <trinary operator-name> <expression> <expression> + // <expression> + // ::= cv <type> expression # conversion with one + // argument + // ::= cv <type> _ <expression>* E # conversion with a different + // number of arguments + // ::= dc <type> <expression> # dynamic_cast<type> + // (expression) + // ::= sc <type> <expression> # static_cast<type> + // (expression) + // ::= cc <type> <expression> # const_cast<type> + // (expression) + // ::= rc <type> <expression> # reinterpret_cast<type> + // (expression) // ::= st <type> # sizeof (a type) // ::= at <type> # alignof (a type) // ::= <template-param> // ::= <function-param> - // ::= fpT # 'this' expression (part of <function-param>) - // ::= sr <type> <unqualified-name> # dependent name - // ::= sr <type> <unqualified-name> <template-args> # dependent template-id - // ::= ds <expression> <expression> # expr.*expr - // ::= sZ <template-param> # size of a parameter pack + // ::= fpT # 'this' expression (part + // of <function-param>) + // ::= sr <type> <unqualified-name> # dependent + // name + // ::= sr <type> <unqualified-name> <template-args> # dependent + // template-id + // ::= sy <expression> <expression> # pack + // indexing expression + // ::= ds <expression> <expression> # + // expr.*expr + // ::= sZ <template-param> # size of a + // parameter pack // ::= sZ <function-param> # size of a function parameter pack - // ::= u <source-name> <template-arg>* E # vendor extended expression + // ::= u <source-name> <template-arg>* E # vendor extended + // expression // ::= <expr-primary> // <expr-primary> ::= L <type> <value number> E # integer literal // ::= L <type> <value float> E # floating literal // ::= L <type> <string type> E # string literal // ::= L <nullptr type> E # nullptr literal "LDnE" - // ::= 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 <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 QualType ImplicitlyConvertedToType; @@ -4886,7 +4915,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 +5816,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 +5846,15 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity, break; } + case Expr::PackIndexingExprClass: { + auto *PE = cast<PackIndexingExpr>(E); + NotPrimaryExpr(); + Out << "sy"; + mangleReferenceToPack(PE->getPackDecl()); + mangleExpression(PE->getIndexExpr()); + break; + } + case Expr::CXXThisExprClass: NotPrimaryExpr(); Out << "fpT"; diff --git a/clang/test/CodeGenCXX/mangle-cxx2c.cpp b/clang/test/CodeGenCXX/mangle-cxx2c.cpp new file mode 100644 index 00000000000000..3e4689948a7a7e --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-cxx2c.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-linux-gnu -std=c++2a | FileCheck %s + +namespace spaceship { + struct X {}; + struct Y {}; + int operator<=>(X, Y); + + // CHECK-LABEL: define {{.*}} @_ZN9spaceship1fIiEEvDTcmltcvNS_1YE_EcvNS_1XE_EcvT__EE + template<typename T> void f(decltype(Y() < X(), T()) x) {} + template void f<int>(int); +} diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h index 3df41b5f4d7d07..4cda6514bfac35 100644 --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -1521,6 +1521,27 @@ class ParameterPackExpansion final : public Node { } }; +class PackIndexing final : public Node { + const Node *Pattern; + const Node *Index; + +public: + PackIndexing(const Node *Pattern_, const Node *Index_) + : Node(KPackIndexing), Pattern(Pattern_), Index(Index_) {} + + template <typename Fn> void match(Fn F) const { F(Pattern, Index); } + + void printLeft(OutputBuffer &OB) const override { + OB.printOpen('('); + ParameterPackExpansion PPE(Pattern); + PPE.printLeft(OB); + OB.printClose(')'); + OB.printOpen('['); + Index->printLeft(OB); + OB.printClose(']'); + } +}; + class TemplateArgs final : public Node { NodeArray Params; Node *Requires; @@ -4510,6 +4531,18 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() { Result = make<ParameterPackExpansion>(Child); break; } + // ::= Dy <type> <expression> # pack indexing (C++26) + case 'y': { + First += 2; + Node *Pattern = getDerived().parseType(); + if (!Pattern) + return nullptr; + Node *Index = getDerived().parseExpr(); + if (!Index) + return nullptr; + Result = make<PackIndexing>(Pattern, Index); + break; + } // Exception specifier on a function type. case 'o': case 'O': @@ -5354,6 +5387,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() { return nullptr; return make<ParameterPackExpansion>(Child); } + if (consumeIf("sy")) { + Node *Pattern = look() == 'T' ? getDerived().parseTemplateParam() + : getDerived().parseFunctionParam(); + if (Pattern == nullptr) + return nullptr; + Node *Index = getDerived().parseExpr(); + if (Index == nullptr) + return nullptr; + return make<PackIndexing>(Pattern, Index); + } if (consumeIf("sZ")) { if (look() == 'T') { Node *R = getDerived().parseTemplateParam(); diff --git a/libcxxabi/src/demangle/ItaniumNodes.def b/libcxxabi/src/demangle/ItaniumNodes.def index 18f5d52b47e911..2c183ec5d23f86 100644 --- a/libcxxabi/src/demangle/ItaniumNodes.def +++ b/libcxxabi/src/demangle/ItaniumNodes.def @@ -100,5 +100,5 @@ NODE(ExprRequirement) NODE(TypeRequirement) NODE(NestedRequirement) NODE(ExplicitObjectParameter) - +NODE(PackIndexing) #undef NODE diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp index e9c74f70a094b5..e0a84de5e8cef9 100644 --- a/libcxxabi/test/test_demangle.pass.cpp +++ b/libcxxabi/test/test_demangle.pass.cpp @@ -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 + {"_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)"}, diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h index b0363c1a7a7863..f567bfea37dbc8 100644 --- a/llvm/include/llvm/Demangle/ItaniumDemangle.h +++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h @@ -1521,6 +1521,27 @@ class ParameterPackExpansion final : public Node { } }; +class PackIndexing final : public Node { + const Node *Pattern; + const Node *Index; + +public: + PackIndexing(const Node *Pattern_, const Node *Index_) + : Node(KPackIndexing), Pattern(Pattern_), Index(Index_) {} + + template <typename Fn> void match(Fn F) const { F(Pattern, Index); } + + void printLeft(OutputBuffer &OB) const override { + OB.printOpen('('); + ParameterPackExpansion PPE(Pattern); + PPE.printLeft(OB); + OB.printClose(')'); + OB.printOpen('['); + Index->printLeft(OB); + OB.printClose(']'); + } +}; + class TemplateArgs final : public Node { NodeArray Params; Node *Requires; @@ -4510,6 +4531,18 @@ Node *AbstractManglingParser<Derived, Alloc>::parseType() { Result = make<ParameterPackExpansion>(Child); break; } + // ::= Dy <type> <expression> # pack indexing (C++26) + case 'y': { + First += 2; + Node *Pattern = getDerived().parseType(); + if (!Pattern) + return nullptr; + Node *Index = getDerived().parseExpr(); + if (!Index) + return nullptr; + Result = make<PackIndexing>(Pattern, Index); + break; + } // Exception specifier on a function type. case 'o': case 'O': @@ -5354,6 +5387,16 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExpr() { return nullptr; return make<ParameterPackExpansion>(Child); } + if (consumeIf("sy")) { + Node *Pattern = look() == 'T' ? getDerived().parseTemplateParam() + : getDerived().parseFunctionParam(); + if (Pattern == nullptr) + return nullptr; + Node *Index = getDerived().parseExpr(); + if (Index == nullptr) + return nullptr; + return make<PackIndexing>(Pattern, Index); + } if (consumeIf("sZ")) { if (look() == 'T') { Node *R = getDerived().parseTemplateParam(); diff --git a/llvm/include/llvm/Demangle/ItaniumNodes.def b/llvm/include/llvm/Demangle/ItaniumNodes.def index 330552663ee658..3a28b1f1759247 100644 --- a/llvm/include/llvm/Demangle/ItaniumNodes.def +++ b/llvm/include/llvm/Demangle/ItaniumNodes.def @@ -100,5 +100,5 @@ NODE(ExprRequirement) NODE(TypeRequirement) NODE(NestedRequirement) NODE(ExplicitObjectParameter) - +NODE(PackIndexing) #undef NODE `````````` </details> https://github.com/llvm/llvm-project/pull/123513 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits