llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-debuginfo Author: cor3ntin (cor3ntin) <details> <summary>Changes</summary> https://isocpp.org/files/papers/P2662R3.pdf Because there is a slight chance the syntax might change slightly (see https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2994r0.html), the feature is not exposed in other language modes. --- Patch is 101.21 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/72644.diff 69 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+2) - (modified) clang/include/clang-c/Index.h (+6-1) - (modified) clang/include/clang/AST/ASTContext.h (+8) - (modified) clang/include/clang/AST/ASTNodeTraverser.h (+6) - (modified) clang/include/clang/AST/ExprCXX.h (+106) - (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+11) - (modified) clang/include/clang/AST/Type.h (+66) - (modified) clang/include/clang/AST/TypeLoc.h (+28) - (modified) clang/include/clang/AST/TypeProperties.td (+14) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+7-1) - (modified) clang/include/clang/Basic/Specifiers.h (+1) - (modified) clang/include/clang/Basic/StmtNodes.td (+1) - (modified) clang/include/clang/Basic/TokenKinds.def (+2) - (modified) clang/include/clang/Basic/TypeNodes.td (+1) - (modified) clang/include/clang/Parse/Parser.h (+9) - (modified) clang/include/clang/Sema/DeclSpec.h (+23-2) - (modified) clang/include/clang/Sema/Sema.h (+25) - (modified) clang/include/clang/Serialization/ASTBitCodes.h (+1) - (modified) clang/include/clang/Serialization/TypeBitCodes.def (+2) - (modified) clang/lib/AST/ASTContext.cpp (+43) - (modified) clang/lib/AST/ASTImporter.cpp (+12) - (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+10) - (modified) clang/lib/AST/Expr.cpp (+8) - (modified) clang/lib/AST/ExprCXX.cpp (+37) - (modified) clang/lib/AST/ExprClassification.cpp (+3) - (modified) clang/lib/AST/ExprConstant.cpp (+7) - (modified) clang/lib/AST/ItaniumMangle.cpp (+9) - (modified) clang/lib/AST/MicrosoftMangle.cpp (+6) - (modified) clang/lib/AST/StmtPrinter.cpp (+4) - (modified) clang/lib/AST/StmtProfile.cpp (+6) - (modified) clang/lib/AST/Type.cpp (+40) - (modified) clang/lib/AST/TypePrinter.cpp (+18) - (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+5) - (modified) clang/lib/CodeGen/CGExpr.cpp (+2) - (modified) clang/lib/CodeGen/CGExprAgg.cpp (+3) - (modified) clang/lib/CodeGen/CGExprComplex.cpp (+4) - (modified) clang/lib/CodeGen/CGExprConstant.cpp (+4) - (modified) clang/lib/CodeGen/CGExprScalar.cpp (+3) - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+1) - (modified) clang/lib/Parse/ParseCXXInlineMethods.cpp (+14) - (modified) clang/lib/Parse/ParseDecl.cpp (+5) - (modified) clang/lib/Parse/ParseDeclCXX.cpp (+101) - (modified) clang/lib/Parse/ParseExpr.cpp (+13) - (modified) clang/lib/Parse/ParseExprCXX.cpp (+67-1) - (modified) clang/lib/Parse/ParseTentative.cpp (+13) - (modified) clang/lib/Parse/Parser.cpp (+2-1) - (modified) clang/lib/Sema/DeclSpec.cpp (+21) - (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+23) - (modified) clang/lib/Sema/SemaDecl.cpp (+1) - (modified) clang/lib/Sema/SemaDeclCXX.cpp (+4) - (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+1) - (modified) clang/lib/Sema/SemaExpr.cpp (+3) - (modified) clang/lib/Sema/SemaExprCXX.cpp (+24-8) - (modified) clang/lib/Sema/SemaTemplate.cpp (+5) - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+16) - (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+64-2) - (modified) clang/lib/Sema/SemaType.cpp (+60) - (modified) clang/lib/Sema/TreeTransform.h (+200) - (modified) clang/lib/Serialization/ASTReader.cpp (+4) - (modified) clang/lib/Serialization/ASTReaderStmt.cpp (+22) - (modified) clang/lib/Serialization/ASTWriter.cpp (+5) - (modified) clang/lib/Serialization/ASTWriterStmt.cpp (+16) - (modified) clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (+1) - (added) clang/test/PCH/pack_indexing.cpp (+16) - (added) clang/test/Parser/cxx2b-pack-indexing.cpp (+65) - (added) clang/test/SemaCXX/cxx2b-pack-indexing.cpp (+115) - (modified) clang/tools/libclang/CIndex.cpp (+8) - (modified) clang/tools/libclang/CXCursor.cpp (+4) - (modified) clang/www/cxx_status.html (+1-1) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ed1a978b5382d71..dab670409077678 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -182,6 +182,8 @@ C++2c Feature Support This is applied to both C++ standard attributes, and other attributes supported by Clang. This completes the implementation of `P2361R6 Unevaluated Strings <https://wg21.link/P2361R6>`_ +- Implemented `P2662R3 Pack Indexing <https://wg21.link/P2662R3>`_. + Resolutions to C++ Defect Reports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 64ab3378957c702..2c0b89a0d12b21e 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -1685,7 +1685,12 @@ enum CXCursorKind { */ CXCursor_CXXParenListInitExpr = 155, - CXCursor_LastExpr = CXCursor_CXXParenListInitExpr, + /** + * Represents a C++26 pack indexing expression + */ + CXCursor_PackIndexingExpr = 156, + + CXCursor_LastExpr = CXCursor_PackIndexingExpr, /* Statements */ CXCursor_FirstStmt = 200, diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3e46a5da3fc043f..9e1c44eb19b805c 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -214,6 +214,9 @@ class ASTContext : public RefCountedBase<ASTContext> { DependentTypeOfExprTypes; mutable llvm::ContextualFoldingSet<DependentDecltypeType, ASTContext &> DependentDecltypeTypes; + + mutable llvm::FoldingSet<PackIndexingType> DependentPackIndexingTypes; + mutable llvm::FoldingSet<TemplateTypeParmType> TemplateTypeParmTypes; mutable llvm::FoldingSet<ObjCTypeParamType> ObjCTypeParamTypes; mutable llvm::FoldingSet<SubstTemplateTypeParmType> @@ -1713,6 +1716,11 @@ class ASTContext : public RefCountedBase<ASTContext> { /// C++11 decltype. QualType getDecltypeType(Expr *e, QualType UnderlyingType) const; + QualType getPackIndexingType(QualType Pattern, Expr *IndexExpr, + bool FullyExpanded = false, + ArrayRef<QualType> Expansions = {}, + int Index = -1) const; + /// Unary type transforms QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType, UnaryTransformType::UTTKind UKind) const; diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index cc8dab97f8b010f..950da2b8d2c4560 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -385,6 +385,12 @@ class ASTNodeTraverser void VisitDecltypeType(const DecltypeType *T) { Visit(T->getUnderlyingExpr()); } + + void VisitPackIndexingType(const PackIndexingType *T) { + Visit(T->getPattern()); + Visit(T->getIndexExpr()); + } + void VisitUnaryTransformType(const UnaryTransformType *T) { Visit(T->getBaseType()); } diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 24278016431837b..efd6558326099eb 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -4344,6 +4344,112 @@ class SizeOfPackExpr final } }; +class PackIndexingExpr final + : public Expr, + private llvm::TrailingObjects<PackIndexingExpr, Expr *> { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + + SourceLocation EllipsisLoc; + + // The location of the closing bracket + SourceLocation RSquareLoc; + + // The pack being indexed, followed by the index + Stmt *SubExprs[2]; + + // The evaluated index + std::optional<int64_t> Index; + + size_t TransformedExpressions; + + PackIndexingExpr(QualType Type, SourceLocation EllipsisLoc, + SourceLocation RSquareLoc, Expr *PackIdExpr, Expr *IndexExpr, + std::optional<int64_t> Index = std::nullopt, + ArrayRef<Expr *> SubstitutedExprs = {}) + : Expr(PackIndexingExprClass, Type, VK_LValue, OK_Ordinary), + EllipsisLoc(EllipsisLoc), RSquareLoc(RSquareLoc), + SubExprs{PackIdExpr, IndexExpr}, Index(Index), + TransformedExpressions(SubstitutedExprs.size()) { + + auto *Exprs = getTrailingObjects<Expr *>(); + std::uninitialized_copy(SubstitutedExprs.begin(), SubstitutedExprs.end(), + Exprs); + + ExprDependence D = IndexExpr->getDependence(); + if (SubstitutedExprs.empty()) + D |= (PackIdExpr->getDependence() | + ExprDependence::TypeValueInstantiation) & + ~ExprDependence::UnexpandedPack; + else if (!IndexExpr->isValueDependent()) { + assert(Index && *Index < int64_t(SubstitutedExprs.size()) && + "pack index out of bound"); + D |= SubstitutedExprs[*Index]->getDependence(); + setValueKind(SubstitutedExprs[*Index]->getValueKind()); + } + setDependence(D); + } + + /// Create an empty expression. + PackIndexingExpr(EmptyShell Empty) : Expr(PackIndexingExprClass, Empty) {} + + unsigned numTrailingObjects(OverloadToken<Expr *>) const { + return TransformedExpressions; + } + +public: + static PackIndexingExpr *Create(ASTContext &Context, + SourceLocation EllipsisLoc, + SourceLocation RSquareLoc, Expr *PackIdExpr, + Expr *IndexExpr, + std::optional<int64_t> Index = std::nullopt, + ArrayRef<Expr *> SubstitutedExprs = {}); + static PackIndexingExpr *CreateDeserialized(ASTContext &Context, + unsigned NumTransformedExprs); + + /// Determine the location of the 'sizeof' keyword. + SourceLocation getEllipsisLoc() const { return EllipsisLoc; } + + /// Determine the location of the parameter pack. + SourceLocation getPackLoc() const { return SubExprs[0]->getBeginLoc(); } + + /// Determine the location of the right parenthesis. + SourceLocation getRSquareLoc() const { return RSquareLoc; } + + SourceLocation getBeginLoc() const LLVM_READONLY { return getPackLoc(); } + SourceLocation getEndLoc() const LLVM_READONLY { return RSquareLoc; } + + Expr *getPackIdExpression() const { return cast<Expr>(SubExprs[0]); } + + NamedDecl *getPackDecl() const; + + Expr *getIndexExpr() const { return cast<Expr>(SubExprs[1]); } + + Expr *getSelectedExpr() const { + assert(Index && !isInstantiationDependent() && + "extracting the indexed expression of a dependant pack"); + return getTrailingObjects<Expr *>()[*Index]; + } + + llvm::ArrayRef<Expr *> getExpressions() const { + if (TransformedExpressions == 0) + return {}; + return {getTrailingObjects<Expr *>(), TransformedExpressions}; + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == PackIndexingExprClass; + } + + // Iterators + child_range children() { return child_range(SubExprs, SubExprs + 2); } + + const_child_range children() const { + return const_child_range(SubExprs, SubExprs + 2); + } +}; + /// Represents a reference to a non-type template parameter /// that has been substituted with a template argument. class SubstNonTypeTemplateParmExpr : public Expr { diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 53bc15e1b19f668..1c26f0512fa1342 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1063,6 +1063,11 @@ DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnmodifiedType())); }) DEF_TRAVERSE_TYPE(DecltypeType, { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) +DEF_TRAVERSE_TYPE(PackIndexingType, { + TRY_TO(TraverseType(T->getPattern())); + TRY_TO(TraverseStmt(T->getIndexExpr())); +}) + DEF_TRAVERSE_TYPE(UnaryTransformType, { TRY_TO(TraverseType(T->getBaseType())); TRY_TO(TraverseType(T->getUnderlyingType())); @@ -1341,6 +1346,11 @@ DEF_TRAVERSE_TYPELOC(DecltypeType, { TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr())); }) +DEF_TRAVERSE_TYPELOC(PackIndexingType, { + TRY_TO(TraverseType(TL.getPattern())); + TRY_TO(TraverseStmt(TL.getTypePtr()->getIndexExpr())); +}) + DEF_TRAVERSE_TYPELOC(UnaryTransformType, { TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); }) @@ -2857,6 +2867,7 @@ DEF_TRAVERSE_STMT(CompoundAssignOperator, {}) DEF_TRAVERSE_STMT(CXXNoexceptExpr, {}) DEF_TRAVERSE_STMT(PackExpansionExpr, {}) DEF_TRAVERSE_STMT(SizeOfPackExpr, {}) +DEF_TRAVERSE_STMT(PackIndexingExpr, {}) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {}) DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {}) DEF_TRAVERSE_STMT(FunctionParmPackExpr, {}) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 6c147eb8f640623..a710766d1cf92f9 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -4884,6 +4884,72 @@ class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode { Expr *E); }; +class PackIndexingType final + : public Type, + public llvm::FoldingSetNode, + private llvm::TrailingObjects<PackIndexingType, QualType> { + friend TrailingObjects; + + const ASTContext &Context; + QualType Pattern; + Expr *IndexExpr; + + unsigned Size; + int Index = -1; + +protected: + friend class ASTContext; // ASTContext creates these. + PackIndexingType(const ASTContext &Context, QualType Canonical, + QualType Pattern, Expr *IndexExpr, + ArrayRef<QualType> Expansions = {}, int Index = -1); + +public: + Expr *getIndexExpr() const { return IndexExpr; } + QualType getPattern() const { return Pattern; } + + bool isSugared() const { return hasSelectedType(); } + + QualType desugar() const { + if (hasSelectedType()) + return getSelectedType(); + return QualType(this, 0); + } + + QualType getSelectedType() const { + assert(hasSelectedType() && "Type is dependant"); + return *(getExpansionsPtr() + Index); + } + + bool hasSelectedType() const { return Index != -1 && !isDependentType(); } + + ArrayRef<QualType> getExpansions() const { + return {getExpansionsPtr(), Size}; + } + + static bool classof(const Type *T) { + return T->getTypeClass() == PackIndexing; + } + + void Profile(llvm::FoldingSetNodeID &ID) { + if (hasSelectedType()) + getSelectedType().Profile(ID); + else + Profile(ID, Context, getPattern(), getIndexExpr()); + } + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, + QualType Pattern, Expr *E); + +private: + const QualType *getExpansionsPtr() const { + return getTrailingObjects<QualType>(); + } + + static TypeDependence computeDependence(QualType Pattern, Expr *IndexExpr, + ArrayRef<QualType> Expansions = {}); + + unsigned numTrailingObjects(OverloadToken<QualType>) const { return Size; } +}; + /// A unary type transform, which is a type constructed from another. class UnaryTransformType : public Type { public: diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 471deb14aba51fc..38e40ece425fb8f 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -2055,6 +2055,34 @@ class DecltypeTypeLoc } }; +struct PackIndexingTypeLocInfo { + SourceLocation EllipsisLoc; +}; + +class PackIndexingTypeLoc + : public ConcreteTypeLoc<UnqualTypeLoc, PackIndexingTypeLoc, + PackIndexingType, PackIndexingTypeLocInfo> { + +public: + Expr *getIndexExpr() const { return getTypePtr()->getIndexExpr(); } + QualType getPattern() const { return getTypePtr()->getPattern(); } + + SourceLocation getEllipsisLoc() const { return getLocalData()->EllipsisLoc; } + void setEllipsisLoc(SourceLocation Loc) { getLocalData()->EllipsisLoc = Loc; } + + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + setEllipsisLoc(Loc); + } + + TypeLoc getPatternLoc() const { return getInnerTypeLoc(); } + + QualType getInnerType() const { return this->getTypePtr()->getPattern(); } + + SourceRange getLocalSourceRange() const { + return SourceRange(getEllipsisLoc(), getEllipsisLoc()); + } +}; + struct UnaryTransformTypeLocInfo { // FIXME: While there's only one unary transform right now, future ones may // need different representations diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index 682c869b0c58479..0ba172a4035fdb4 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -433,6 +433,20 @@ let Class = DecltypeType in { }]>; } +let Class = PackIndexingType in { + def : Property<"pattern", QualType> { + let Read = [{ node->getPattern() }]; + } + def : Property<"indexExpression", ExprRef> { + let Read = [{ node->getIndexExpr() }]; + } + + def : Creator<[{ + return ctx.getPackIndexingType(pattern, indexExpression); + }]>; +} + + let Class = UnaryTransformType in { def : Property<"baseType", QualType> { let Read = [{ node->getBaseType() }]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a9dde041bc22a6d..5f80debb9a454f6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5681,9 +5681,15 @@ def err_function_parameter_pack_without_parameter_packs : Error< def err_ellipsis_in_declarator_not_parameter : Error< "only function and template parameters can be parameter packs">; -def err_sizeof_pack_no_pack_name : Error< +def err_expected_name_of_pack : Error< "%0 does not refer to the name of a parameter pack">; +def err_pack_index_out_of_bound : Error< + "%0 is not a valid index for pack %1 of size %2">; + +def err_pack_index_todo : Error< + "Pack index not implemented">; + def err_fold_expression_packs_both_sides : Error< "binary fold expression has unexpanded parameter packs in both operands">; def err_fold_expression_empty : Error< diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index 87f29c8ae10bd9a..bff4c1616c1d027 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -94,6 +94,7 @@ namespace clang { TST_auto_type, // __auto_type extension TST_unknown_anytype, // __unknown_anytype extension TST_atomic, // C11 _Atomic + TST_indexed_typename_pack, #define GENERIC_IMAGE_TYPE(ImgType, Id) TST_##ImgType##_t, // OpenCL image types #include "clang/Basic/OpenCLImageTypes.def" TST_error // erroneous type diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index cec301dfca2817b..9d03800840fcd0b 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -154,6 +154,7 @@ def UnresolvedMemberExpr : StmtNode<OverloadExpr>; def CXXNoexceptExpr : StmtNode<Expr>; def PackExpansionExpr : StmtNode<Expr>; def SizeOfPackExpr : StmtNode<Expr>; +def PackIndexingExpr : StmtNode<Expr>; def SubstNonTypeTemplateParmExpr : StmtNode<Expr>; def SubstNonTypeTemplateParmPackExpr : StmtNode<Expr>; def FunctionParmPackExpr : StmtNode<Expr>; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 82a503d01068d53..6b5f8210fa6d0e3 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -836,6 +836,8 @@ ANNOTATION(primary_expr) // annotation for a primary expression, used when // message send ANNOTATION(decltype) // annotation for a decltype expression, // e.g., "decltype(foo.bar())" +ANNOTATION(indexed_pack_type) // annotation for an indexed pack of type, + // e.g., "T...[expr]" // Annotation for #pragma unused(...) // For each argument inside the parentheses the pragma handler will produce diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td index 649b071cebb9404..6419762417371b9 100644 --- a/clang/include/clang/Basic/TypeNodes.td +++ b/clang/include/clang/Basic/TypeNodes.td @@ -103,6 +103,7 @@ def InjectedClassNameType : TypeNode<Type>, AlwaysDependent, LeafType; def DependentNameType : TypeNode<Type>, AlwaysDependent; def DependentTemplateSpecializationType : TypeNode<Type>, AlwaysDependent; def PackExpansionType : TypeNode<Type>, AlwaysDependent; +def PackIndexingType : TypeNode<Type>, NeverCanonicalUnlessDependent; def ObjCTypeParamType : TypeNode<Type>, NeverCanonical; def ObjCObjectType : TypeNode<Type>; def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 30e0352c868637b..c7bbc3d6384306f 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1884,6 +1884,10 @@ class Parser : public CodeCompletionHandler { // C++ Expressions ExprResult tryParseCXXIdExpression(CXXScopeSpec &SS, bool isAddressOfOperand, Token &Replacement); + + ExprResult tryParseCXXPackIndexingExpression(ExprResult PackIdExpression); + ExprResult ParseCXXPackIndexingExpression(ExprResult PackIdExpression); + ExprResult ParseCXXIdExpression(bool isAddressOfOperand = false); bool areTokensAdjacent(const Token &A, const Token &B); @@ -2430,6 +2434,11 @@ class Parser : public CodeCompletionHandler { DeclSpecContext DSC, LateParsedAttrList *LateAttrs, ImplicitTypenameContext AllowImplicitTypename); + SourceLocation ParseIndexedTypeNamePack(DeclSpec &DS); + void AnnotateExistingIndexedTypeNamePack(ParsedType T, + SourceLocation StartLoc, + SourceLocation EndLoc); + bool DiagnoseMissingSemiAfterTagDefinition( DeclSpec &DS, AccessSpecifier AS, DeclSpecContext DSContext, LateParsedAttrList *LateAttrs = nullptr); diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index 4561cca929c0d0b..4726cbbd1af50c9 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -309,6 +309,7 @@ class DeclSpec { static const TST TST_typeof_unqualExpr = clang::TST_typeof_unqualExpr; static const TST TST_decltype = clang::TST_decltype; static const TST TST_decltype_auto = clang::TST_decltype_auto; + static const TST TST_indexed_typename_pack = clang::TST_indexed_typename_pack; #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ static const TST TST_##Trait = clang::TST_##Trait; #include "clang/Basic/TransformTypeTraits.def" @@ -389,6 +390,7 @@ class DeclSpec { Expr *ExprRep; TemplateIdAnnotation *TemplateIdRep; }; + Expr *PackIndexingExpr = nullptr; /// ExplicitSpecifier - Store information about explicit spicifer. ExplicitSpecifier FS_explicit_specifier; @@ -405,7 +407,7 @@ class DeclSpec { SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc; SourceRange TSWRange; - SourceLocation TSCLoc, TSSLoc, TSTLoc, AltiVecLoc, TSSatLoc; + SourceLocation TSCLoc, TSSLoc, TSTLoc, AltiVecLoc, TSSatLoc, EllipsisLoc; /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union, /// typename, then this is the location of the named type (if present); /// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and @@ -427,7 +429,8 @@ class DeclSpec { static bool isTypeRep(TST T) { return T == TST_atomic || T == TST_typename || T == TST_typeofType || - T == TST_typeof_unqualType || isTransformTypeTrait(T); + T == TST_typeof_unqualType || isTransformTypeTrait(T) || + T == TST_indexed_typename_pack; } static bool isExprRep(TST T) { return T == TST_typeofExpr || T == TST_typeof_unqualExpr || @@ -530,6 +533,13 @@ class DeclSpec { assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr"); return ExprRep; } + + Expr *getPackIndexingExpr() const { + assert(TypeSpecType == TST_indexed_ty... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/72644 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits