xref: /freebsd/contrib/llvm-project/clang/lib/Sema/SemaTemplateVariadic.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
70b57cec5SDimitry Andric //
80b57cec5SDimitry Andric //  This file implements semantic analysis for C++0x variadic templates.
90b57cec5SDimitry Andric //===----------------------------------------------------------------------===/
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "clang/Sema/Sema.h"
120b57cec5SDimitry Andric #include "TypeLocBuilder.h"
130b57cec5SDimitry Andric #include "clang/AST/Expr.h"
140b57cec5SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
150b57cec5SDimitry Andric #include "clang/AST/TypeLoc.h"
160b57cec5SDimitry Andric #include "clang/Sema/Lookup.h"
170b57cec5SDimitry Andric #include "clang/Sema/ParsedTemplate.h"
180b57cec5SDimitry Andric #include "clang/Sema/ScopeInfo.h"
190b57cec5SDimitry Andric #include "clang/Sema/SemaInternal.h"
200b57cec5SDimitry Andric #include "clang/Sema/Template.h"
21bdd1243dSDimitry Andric #include <optional>
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric using namespace clang;
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric //----------------------------------------------------------------------------
260b57cec5SDimitry Andric // Visitor that collects unexpanded parameter packs
270b57cec5SDimitry Andric //----------------------------------------------------------------------------
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric namespace {
300b57cec5SDimitry Andric   /// A class that collects unexpanded parameter packs.
310b57cec5SDimitry Andric   class CollectUnexpandedParameterPacksVisitor :
320b57cec5SDimitry Andric     public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
330b57cec5SDimitry Andric   {
340b57cec5SDimitry Andric     typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
350b57cec5SDimitry Andric       inherited;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric     bool InLambda = false;
400b57cec5SDimitry Andric     unsigned DepthLimit = (unsigned)-1;
410b57cec5SDimitry Andric 
addUnexpanded(NamedDecl * ND,SourceLocation Loc=SourceLocation ())420b57cec5SDimitry Andric     void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
430b57cec5SDimitry Andric       if (auto *VD = dyn_cast<VarDecl>(ND)) {
440b57cec5SDimitry Andric         // For now, the only problematic case is a generic lambda's templated
450b57cec5SDimitry Andric         // call operator, so we don't need to look for all the other ways we
460b57cec5SDimitry Andric         // could have reached a dependent parameter pack.
470b57cec5SDimitry Andric         auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext());
480b57cec5SDimitry Andric         auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;
490b57cec5SDimitry Andric         if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)
500b57cec5SDimitry Andric           return;
510b57cec5SDimitry Andric       } else if (getDepthAndIndex(ND).first >= DepthLimit)
520b57cec5SDimitry Andric         return;
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric       Unexpanded.push_back({ND, Loc});
550b57cec5SDimitry Andric     }
addUnexpanded(const TemplateTypeParmType * T,SourceLocation Loc=SourceLocation ())560b57cec5SDimitry Andric     void addUnexpanded(const TemplateTypeParmType *T,
570b57cec5SDimitry Andric                        SourceLocation Loc = SourceLocation()) {
580b57cec5SDimitry Andric       if (T->getDepth() < DepthLimit)
590b57cec5SDimitry Andric         Unexpanded.push_back({T, Loc});
600b57cec5SDimitry Andric     }
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   public:
CollectUnexpandedParameterPacksVisitor(SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)630b57cec5SDimitry Andric     explicit CollectUnexpandedParameterPacksVisitor(
640b57cec5SDimitry Andric         SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
650b57cec5SDimitry Andric         : Unexpanded(Unexpanded) {}
660b57cec5SDimitry Andric 
shouldWalkTypesOfTypeLocs() const670b57cec5SDimitry Andric     bool shouldWalkTypesOfTypeLocs() const { return false; }
680b57cec5SDimitry Andric 
69*0fca6ea1SDimitry Andric     // We need this so we can find e.g. attributes on lambdas.
shouldVisitImplicitCode() const70*0fca6ea1SDimitry Andric     bool shouldVisitImplicitCode() const { return true; }
71*0fca6ea1SDimitry Andric 
720b57cec5SDimitry Andric     //------------------------------------------------------------------------
730b57cec5SDimitry Andric     // Recording occurrences of (unexpanded) parameter packs.
740b57cec5SDimitry Andric     //------------------------------------------------------------------------
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric     /// Record occurrences of template type parameter packs.
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)770b57cec5SDimitry Andric     bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
780b57cec5SDimitry Andric       if (TL.getTypePtr()->isParameterPack())
790b57cec5SDimitry Andric         addUnexpanded(TL.getTypePtr(), TL.getNameLoc());
800b57cec5SDimitry Andric       return true;
810b57cec5SDimitry Andric     }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric     /// Record occurrences of template type parameter packs
840b57cec5SDimitry Andric     /// when we don't have proper source-location information for
850b57cec5SDimitry Andric     /// them.
860b57cec5SDimitry Andric     ///
870b57cec5SDimitry Andric     /// Ideally, this routine would never be used.
VisitTemplateTypeParmType(TemplateTypeParmType * T)880b57cec5SDimitry Andric     bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
890b57cec5SDimitry Andric       if (T->isParameterPack())
900b57cec5SDimitry Andric         addUnexpanded(T);
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric       return true;
930b57cec5SDimitry Andric     }
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric     /// Record occurrences of function and non-type template
960b57cec5SDimitry Andric     /// parameter packs in an expression.
VisitDeclRefExpr(DeclRefExpr * E)970b57cec5SDimitry Andric     bool VisitDeclRefExpr(DeclRefExpr *E) {
980b57cec5SDimitry Andric       if (E->getDecl()->isParameterPack())
990b57cec5SDimitry Andric         addUnexpanded(E->getDecl(), E->getLocation());
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric       return true;
1020b57cec5SDimitry Andric     }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric     /// Record occurrences of template template parameter packs.
TraverseTemplateName(TemplateName Template)1050b57cec5SDimitry Andric     bool TraverseTemplateName(TemplateName Template) {
1060b57cec5SDimitry Andric       if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
1070b57cec5SDimitry Andric               Template.getAsTemplateDecl())) {
1080b57cec5SDimitry Andric         if (TTP->isParameterPack())
1090b57cec5SDimitry Andric           addUnexpanded(TTP);
1100b57cec5SDimitry Andric       }
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric       return inherited::TraverseTemplateName(Template);
1130b57cec5SDimitry Andric     }
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric     /// Suppress traversal into Objective-C container literal
1160b57cec5SDimitry Andric     /// elements that are pack expansions.
TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral * E)1170b57cec5SDimitry Andric     bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1180b57cec5SDimitry Andric       if (!E->containsUnexpandedParameterPack())
1190b57cec5SDimitry Andric         return true;
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric       for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
1220b57cec5SDimitry Andric         ObjCDictionaryElement Element = E->getKeyValueElement(I);
1230b57cec5SDimitry Andric         if (Element.isPackExpansion())
1240b57cec5SDimitry Andric           continue;
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric         TraverseStmt(Element.Key);
1270b57cec5SDimitry Andric         TraverseStmt(Element.Value);
1280b57cec5SDimitry Andric       }
1290b57cec5SDimitry Andric       return true;
1300b57cec5SDimitry Andric     }
1310b57cec5SDimitry Andric     //------------------------------------------------------------------------
1320b57cec5SDimitry Andric     // Pruning the search for unexpanded parameter packs.
1330b57cec5SDimitry Andric     //------------------------------------------------------------------------
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric     /// Suppress traversal into statements and expressions that
1360b57cec5SDimitry Andric     /// do not contain unexpanded parameter packs.
TraverseStmt(Stmt * S)1370b57cec5SDimitry Andric     bool TraverseStmt(Stmt *S) {
1380b57cec5SDimitry Andric       Expr *E = dyn_cast_or_null<Expr>(S);
1390b57cec5SDimitry Andric       if ((E && E->containsUnexpandedParameterPack()) || InLambda)
1400b57cec5SDimitry Andric         return inherited::TraverseStmt(S);
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric       return true;
1430b57cec5SDimitry Andric     }
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric     /// Suppress traversal into types that do not contain
1460b57cec5SDimitry Andric     /// unexpanded parameter packs.
TraverseType(QualType T)1470b57cec5SDimitry Andric     bool TraverseType(QualType T) {
1480b57cec5SDimitry Andric       if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
1490b57cec5SDimitry Andric         return inherited::TraverseType(T);
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric       return true;
1520b57cec5SDimitry Andric     }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric     /// Suppress traversal into types with location information
1550b57cec5SDimitry Andric     /// that do not contain unexpanded parameter packs.
TraverseTypeLoc(TypeLoc TL)1560b57cec5SDimitry Andric     bool TraverseTypeLoc(TypeLoc TL) {
1570b57cec5SDimitry Andric       if ((!TL.getType().isNull() &&
1580b57cec5SDimitry Andric            TL.getType()->containsUnexpandedParameterPack()) ||
1590b57cec5SDimitry Andric           InLambda)
1600b57cec5SDimitry Andric         return inherited::TraverseTypeLoc(TL);
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric       return true;
1630b57cec5SDimitry Andric     }
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric     /// Suppress traversal of parameter packs.
TraverseDecl(Decl * D)1660b57cec5SDimitry Andric     bool TraverseDecl(Decl *D) {
1670b57cec5SDimitry Andric       // A function parameter pack is a pack expansion, so cannot contain
1680b57cec5SDimitry Andric       // an unexpanded parameter pack. Likewise for a template parameter
1690b57cec5SDimitry Andric       // pack that contains any references to other packs.
1700b57cec5SDimitry Andric       if (D && D->isParameterPack())
1710b57cec5SDimitry Andric         return true;
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric       return inherited::TraverseDecl(D);
1740b57cec5SDimitry Andric     }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric     /// Suppress traversal of pack-expanded attributes.
TraverseAttr(Attr * A)1770b57cec5SDimitry Andric     bool TraverseAttr(Attr *A) {
1780b57cec5SDimitry Andric       if (A->isPackExpansion())
1790b57cec5SDimitry Andric         return true;
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric       return inherited::TraverseAttr(A);
1820b57cec5SDimitry Andric     }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric     /// Suppress traversal of pack expansion expressions and types.
1850b57cec5SDimitry Andric     ///@{
TraversePackExpansionType(PackExpansionType * T)1860b57cec5SDimitry Andric     bool TraversePackExpansionType(PackExpansionType *T) { return true; }
TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL)1870b57cec5SDimitry Andric     bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; }
TraversePackExpansionExpr(PackExpansionExpr * E)1880b57cec5SDimitry Andric     bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; }
TraverseCXXFoldExpr(CXXFoldExpr * E)1890b57cec5SDimitry Andric     bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; }
TraversePackIndexingExpr(PackIndexingExpr * E)190*0fca6ea1SDimitry Andric     bool TraversePackIndexingExpr(PackIndexingExpr *E) {
191*0fca6ea1SDimitry Andric       return inherited::TraverseStmt(E->getIndexExpr());
192*0fca6ea1SDimitry Andric     }
TraversePackIndexingType(PackIndexingType * E)193*0fca6ea1SDimitry Andric     bool TraversePackIndexingType(PackIndexingType *E) {
194*0fca6ea1SDimitry Andric       return inherited::TraverseStmt(E->getIndexExpr());
195*0fca6ea1SDimitry Andric     }
TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL)196*0fca6ea1SDimitry Andric     bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL) {
197*0fca6ea1SDimitry Andric       return inherited::TraverseStmt(TL.getIndexExpr());
198*0fca6ea1SDimitry Andric     }
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric     ///@}
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric     /// Suppress traversal of using-declaration pack expansion.
TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)2030b57cec5SDimitry Andric     bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
2040b57cec5SDimitry Andric       if (D->isPackExpansion())
2050b57cec5SDimitry Andric         return true;
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric       return inherited::TraverseUnresolvedUsingValueDecl(D);
2080b57cec5SDimitry Andric     }
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric     /// Suppress traversal of using-declaration pack expansion.
TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)2110b57cec5SDimitry Andric     bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
2120b57cec5SDimitry Andric       if (D->isPackExpansion())
2130b57cec5SDimitry Andric         return true;
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric       return inherited::TraverseUnresolvedUsingTypenameDecl(D);
2160b57cec5SDimitry Andric     }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric     /// Suppress traversal of template argument pack expansions.
TraverseTemplateArgument(const TemplateArgument & Arg)2190b57cec5SDimitry Andric     bool TraverseTemplateArgument(const TemplateArgument &Arg) {
2200b57cec5SDimitry Andric       if (Arg.isPackExpansion())
2210b57cec5SDimitry Andric         return true;
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric       return inherited::TraverseTemplateArgument(Arg);
2240b57cec5SDimitry Andric     }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric     /// Suppress traversal of template argument pack expansions.
TraverseTemplateArgumentLoc(const TemplateArgumentLoc & ArgLoc)2270b57cec5SDimitry Andric     bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
2280b57cec5SDimitry Andric       if (ArgLoc.getArgument().isPackExpansion())
2290b57cec5SDimitry Andric         return true;
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric       return inherited::TraverseTemplateArgumentLoc(ArgLoc);
2320b57cec5SDimitry Andric     }
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric     /// Suppress traversal of base specifier pack expansions.
TraverseCXXBaseSpecifier(const CXXBaseSpecifier & Base)2350b57cec5SDimitry Andric     bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
2360b57cec5SDimitry Andric       if (Base.isPackExpansion())
2370b57cec5SDimitry Andric         return true;
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric       return inherited::TraverseCXXBaseSpecifier(Base);
2400b57cec5SDimitry Andric     }
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric     /// Suppress traversal of mem-initializer pack expansions.
TraverseConstructorInitializer(CXXCtorInitializer * Init)2430b57cec5SDimitry Andric     bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
2440b57cec5SDimitry Andric       if (Init->isPackExpansion())
2450b57cec5SDimitry Andric         return true;
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric       return inherited::TraverseConstructorInitializer(Init);
2480b57cec5SDimitry Andric     }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric     /// Note whether we're traversing a lambda containing an unexpanded
2510b57cec5SDimitry Andric     /// parameter pack. In this case, the unexpanded pack can occur anywhere,
2520b57cec5SDimitry Andric     /// including all the places where we normally wouldn't look. Within a
2530b57cec5SDimitry Andric     /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
2540b57cec5SDimitry Andric     /// outside an expression.
TraverseLambdaExpr(LambdaExpr * Lambda)2550b57cec5SDimitry Andric     bool TraverseLambdaExpr(LambdaExpr *Lambda) {
2560b57cec5SDimitry Andric       // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
2570b57cec5SDimitry Andric       // even if it's contained within another lambda.
2580b57cec5SDimitry Andric       if (!Lambda->containsUnexpandedParameterPack())
2590b57cec5SDimitry Andric         return true;
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric       bool WasInLambda = InLambda;
2620b57cec5SDimitry Andric       unsigned OldDepthLimit = DepthLimit;
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric       InLambda = true;
2650b57cec5SDimitry Andric       if (auto *TPL = Lambda->getTemplateParameterList())
2660b57cec5SDimitry Andric         DepthLimit = TPL->getDepth();
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric       inherited::TraverseLambdaExpr(Lambda);
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric       InLambda = WasInLambda;
2710b57cec5SDimitry Andric       DepthLimit = OldDepthLimit;
2720b57cec5SDimitry Andric       return true;
2730b57cec5SDimitry Andric     }
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric     /// Suppress traversal within pack expansions in lambda captures.
TraverseLambdaCapture(LambdaExpr * Lambda,const LambdaCapture * C,Expr * Init)2760b57cec5SDimitry Andric     bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C,
2770b57cec5SDimitry Andric                                Expr *Init) {
2780b57cec5SDimitry Andric       if (C->isPackExpansion())
2790b57cec5SDimitry Andric         return true;
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric       return inherited::TraverseLambdaCapture(Lambda, C, Init);
2820b57cec5SDimitry Andric     }
2830b57cec5SDimitry Andric   };
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric /// Determine whether it's possible for an unexpanded parameter pack to
2870b57cec5SDimitry Andric /// be valid in this location. This only happens when we're in a declaration
2880b57cec5SDimitry Andric /// that is nested within an expression that could be expanded, such as a
2890b57cec5SDimitry Andric /// lambda-expression within a function call.
2900b57cec5SDimitry Andric ///
2910b57cec5SDimitry Andric /// This is conservatively correct, but may claim that some unexpanded packs are
2920b57cec5SDimitry Andric /// permitted when they are not.
isUnexpandedParameterPackPermitted()2930b57cec5SDimitry Andric bool Sema::isUnexpandedParameterPackPermitted() {
2940b57cec5SDimitry Andric   for (auto *SI : FunctionScopes)
2950b57cec5SDimitry Andric     if (isa<sema::LambdaScopeInfo>(SI))
2960b57cec5SDimitry Andric       return true;
2970b57cec5SDimitry Andric   return false;
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric /// Diagnose all of the unexpanded parameter packs in the given
3010b57cec5SDimitry Andric /// vector.
3020b57cec5SDimitry Andric bool
DiagnoseUnexpandedParameterPacks(SourceLocation Loc,UnexpandedParameterPackContext UPPC,ArrayRef<UnexpandedParameterPack> Unexpanded)3030b57cec5SDimitry Andric Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
3040b57cec5SDimitry Andric                                        UnexpandedParameterPackContext UPPC,
3050b57cec5SDimitry Andric                                  ArrayRef<UnexpandedParameterPack> Unexpanded) {
3060b57cec5SDimitry Andric   if (Unexpanded.empty())
3070b57cec5SDimitry Andric     return false;
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   // If we are within a lambda expression and referencing a pack that is not
310a7dea167SDimitry Andric   // declared within the lambda itself, that lambda contains an unexpanded
3110b57cec5SDimitry Andric   // parameter pack, and we are done.
3120b57cec5SDimitry Andric   // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
3130b57cec5SDimitry Andric   // later.
3140b57cec5SDimitry Andric   SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences;
315a7dea167SDimitry Andric   if (auto *LSI = getEnclosingLambda()) {
3160b57cec5SDimitry Andric     for (auto &Pack : Unexpanded) {
317a7dea167SDimitry Andric       auto DeclaresThisPack = [&](NamedDecl *LocalPack) {
318a7dea167SDimitry Andric         if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) {
319a7dea167SDimitry Andric           auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack);
320a7dea167SDimitry Andric           return TTPD && TTPD->getTypeForDecl() == TTPT;
321a7dea167SDimitry Andric         }
3221ac55f4cSDimitry Andric         return declaresSameEntity(Pack.first.get<NamedDecl *>(), LocalPack);
323a7dea167SDimitry Andric       };
324349cc55cSDimitry Andric       if (llvm::any_of(LSI->LocalPacks, DeclaresThisPack))
3250b57cec5SDimitry Andric         LambdaParamPackReferences.push_back(Pack);
3260b57cec5SDimitry Andric     }
3270b57cec5SDimitry Andric 
328a7dea167SDimitry Andric     if (LambdaParamPackReferences.empty()) {
329a7dea167SDimitry Andric       // Construct in lambda only references packs declared outside the lambda.
330a7dea167SDimitry Andric       // That's OK for now, but the lambda itself is considered to contain an
331a7dea167SDimitry Andric       // unexpanded pack in this case, which will require expansion outside the
332a7dea167SDimitry Andric       // lambda.
333a7dea167SDimitry Andric 
334a7dea167SDimitry Andric       // We do not permit pack expansion that would duplicate a statement
335a7dea167SDimitry Andric       // expression, not even within a lambda.
336a7dea167SDimitry Andric       // FIXME: We could probably support this for statement expressions that
337a7dea167SDimitry Andric       // do not contain labels.
338a7dea167SDimitry Andric       // FIXME: This is insufficient to detect this problem; consider
339a7dea167SDimitry Andric       //   f( ({ bad: 0; }) + pack ... );
340a7dea167SDimitry Andric       bool EnclosingStmtExpr = false;
341a7dea167SDimitry Andric       for (unsigned N = FunctionScopes.size(); N; --N) {
342a7dea167SDimitry Andric         sema::FunctionScopeInfo *Func = FunctionScopes[N-1];
343349cc55cSDimitry Andric         if (llvm::any_of(
344349cc55cSDimitry Andric                 Func->CompoundScopes,
345a7dea167SDimitry Andric                 [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) {
346a7dea167SDimitry Andric           EnclosingStmtExpr = true;
347a7dea167SDimitry Andric           break;
348a7dea167SDimitry Andric         }
349a7dea167SDimitry Andric         // Coumpound-statements outside the lambda are OK for now; we'll check
350a7dea167SDimitry Andric         // for those when we finish handling the lambda.
351a7dea167SDimitry Andric         if (Func == LSI)
3520b57cec5SDimitry Andric           break;
3530b57cec5SDimitry Andric       }
3540b57cec5SDimitry Andric 
355a7dea167SDimitry Andric       if (!EnclosingStmtExpr) {
3560b57cec5SDimitry Andric         LSI->ContainsUnexpandedParameterPack = true;
3570b57cec5SDimitry Andric         return false;
3580b57cec5SDimitry Andric       }
359a7dea167SDimitry Andric     } else {
360a7dea167SDimitry Andric       Unexpanded = LambdaParamPackReferences;
361a7dea167SDimitry Andric     }
3620b57cec5SDimitry Andric   }
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric   SmallVector<SourceLocation, 4> Locations;
3650b57cec5SDimitry Andric   SmallVector<IdentifierInfo *, 4> Names;
3660b57cec5SDimitry Andric   llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric   for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
3690b57cec5SDimitry Andric     IdentifierInfo *Name = nullptr;
3700b57cec5SDimitry Andric     if (const TemplateTypeParmType *TTP
3710b57cec5SDimitry Andric           = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
3720b57cec5SDimitry Andric       Name = TTP->getIdentifier();
3730b57cec5SDimitry Andric     else
3741ac55f4cSDimitry Andric       Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric     if (Name && NamesKnown.insert(Name).second)
3770b57cec5SDimitry Andric       Names.push_back(Name);
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric     if (Unexpanded[I].second.isValid())
3800b57cec5SDimitry Andric       Locations.push_back(Unexpanded[I].second);
3810b57cec5SDimitry Andric   }
3820b57cec5SDimitry Andric 
383e8d8bef9SDimitry Andric   auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
3840b57cec5SDimitry Andric             << (int)UPPC << (int)Names.size();
3850b57cec5SDimitry Andric   for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)
3860b57cec5SDimitry Andric     DB << Names[I];
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   for (unsigned I = 0, N = Locations.size(); I != N; ++I)
3890b57cec5SDimitry Andric     DB << SourceRange(Locations[I]);
3900b57cec5SDimitry Andric   return true;
3910b57cec5SDimitry Andric }
3920b57cec5SDimitry Andric 
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TypeSourceInfo * T,UnexpandedParameterPackContext UPPC)3930b57cec5SDimitry Andric bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
3940b57cec5SDimitry Andric                                            TypeSourceInfo *T,
3950b57cec5SDimitry Andric                                          UnexpandedParameterPackContext UPPC) {
3960b57cec5SDimitry Andric   // C++0x [temp.variadic]p5:
3970b57cec5SDimitry Andric   //   An appearance of a name of a parameter pack that is not expanded is
3980b57cec5SDimitry Andric   //   ill-formed.
3990b57cec5SDimitry Andric   if (!T->getType()->containsUnexpandedParameterPack())
4000b57cec5SDimitry Andric     return false;
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4030b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
4040b57cec5SDimitry Andric                                                               T->getTypeLoc());
4050b57cec5SDimitry Andric   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4060b57cec5SDimitry Andric   return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
4070b57cec5SDimitry Andric }
4080b57cec5SDimitry Andric 
DiagnoseUnexpandedParameterPack(Expr * E,UnexpandedParameterPackContext UPPC)4090b57cec5SDimitry Andric bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
4100b57cec5SDimitry Andric                                         UnexpandedParameterPackContext UPPC) {
4110b57cec5SDimitry Andric   // C++0x [temp.variadic]p5:
4120b57cec5SDimitry Andric   //   An appearance of a name of a parameter pack that is not expanded is
4130b57cec5SDimitry Andric   //   ill-formed.
4140b57cec5SDimitry Andric   if (!E->containsUnexpandedParameterPack())
4150b57cec5SDimitry Andric     return false;
4160b57cec5SDimitry Andric 
4175f757f3fSDimitry Andric   // CollectUnexpandedParameterPacksVisitor does not expect to see a
4185f757f3fSDimitry Andric   // FunctionParmPackExpr, but diagnosing unexpected parameter packs may still
4195f757f3fSDimitry Andric   // see such an expression in a lambda body.
4205f757f3fSDimitry Andric   // We'll bail out early in this case to avoid triggering an assertion.
4215f757f3fSDimitry Andric   if (isa<FunctionParmPackExpr>(E) && getEnclosingLambda())
4225f757f3fSDimitry Andric     return false;
4235f757f3fSDimitry Andric 
4240b57cec5SDimitry Andric   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4250b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
4260b57cec5SDimitry Andric   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4270b57cec5SDimitry Andric   return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric 
DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr * RE)430e8d8bef9SDimitry Andric bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
431e8d8bef9SDimitry Andric   if (!RE->containsUnexpandedParameterPack())
432e8d8bef9SDimitry Andric     return false;
433e8d8bef9SDimitry Andric 
434e8d8bef9SDimitry Andric   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
435e8d8bef9SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE);
436e8d8bef9SDimitry Andric   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
437e8d8bef9SDimitry Andric 
438e8d8bef9SDimitry Andric   // We only care about unexpanded references to the RequiresExpr's own
439e8d8bef9SDimitry Andric   // parameter packs.
440e8d8bef9SDimitry Andric   auto Parms = RE->getLocalParameters();
441e8d8bef9SDimitry Andric   llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
442e8d8bef9SDimitry Andric   SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
443e8d8bef9SDimitry Andric   for (auto Parm : Unexpanded)
4441ac55f4cSDimitry Andric     if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl *>()))
445e8d8bef9SDimitry Andric       UnexpandedParms.push_back(Parm);
446e8d8bef9SDimitry Andric   if (UnexpandedParms.empty())
447e8d8bef9SDimitry Andric     return false;
448e8d8bef9SDimitry Andric 
449e8d8bef9SDimitry Andric   return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement,
450e8d8bef9SDimitry Andric                                           UnexpandedParms);
451e8d8bef9SDimitry Andric }
452e8d8bef9SDimitry Andric 
DiagnoseUnexpandedParameterPack(const CXXScopeSpec & SS,UnexpandedParameterPackContext UPPC)4530b57cec5SDimitry Andric bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
4540b57cec5SDimitry Andric                                         UnexpandedParameterPackContext UPPC) {
4550b57cec5SDimitry Andric   // C++0x [temp.variadic]p5:
4560b57cec5SDimitry Andric   //   An appearance of a name of a parameter pack that is not expanded is
4570b57cec5SDimitry Andric   //   ill-formed.
4580b57cec5SDimitry Andric   if (!SS.getScopeRep() ||
4590b57cec5SDimitry Andric       !SS.getScopeRep()->containsUnexpandedParameterPack())
4600b57cec5SDimitry Andric     return false;
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4630b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded)
4640b57cec5SDimitry Andric     .TraverseNestedNameSpecifier(SS.getScopeRep());
4650b57cec5SDimitry Andric   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4660b57cec5SDimitry Andric   return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
4670b57cec5SDimitry Andric                                           UPPC, Unexpanded);
4680b57cec5SDimitry Andric }
4690b57cec5SDimitry Andric 
DiagnoseUnexpandedParameterPack(const DeclarationNameInfo & NameInfo,UnexpandedParameterPackContext UPPC)4700b57cec5SDimitry Andric bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
4710b57cec5SDimitry Andric                                          UnexpandedParameterPackContext UPPC) {
4720b57cec5SDimitry Andric   // C++0x [temp.variadic]p5:
4730b57cec5SDimitry Andric   //   An appearance of a name of a parameter pack that is not expanded is
4740b57cec5SDimitry Andric   //   ill-formed.
4750b57cec5SDimitry Andric   switch (NameInfo.getName().getNameKind()) {
4760b57cec5SDimitry Andric   case DeclarationName::Identifier:
4770b57cec5SDimitry Andric   case DeclarationName::ObjCZeroArgSelector:
4780b57cec5SDimitry Andric   case DeclarationName::ObjCOneArgSelector:
4790b57cec5SDimitry Andric   case DeclarationName::ObjCMultiArgSelector:
4800b57cec5SDimitry Andric   case DeclarationName::CXXOperatorName:
4810b57cec5SDimitry Andric   case DeclarationName::CXXLiteralOperatorName:
4820b57cec5SDimitry Andric   case DeclarationName::CXXUsingDirective:
4830b57cec5SDimitry Andric   case DeclarationName::CXXDeductionGuideName:
4840b57cec5SDimitry Andric     return false;
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric   case DeclarationName::CXXConstructorName:
4870b57cec5SDimitry Andric   case DeclarationName::CXXDestructorName:
4880b57cec5SDimitry Andric   case DeclarationName::CXXConversionFunctionName:
4890b57cec5SDimitry Andric     // FIXME: We shouldn't need this null check!
4900b57cec5SDimitry Andric     if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
4910b57cec5SDimitry Andric       return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
4920b57cec5SDimitry Andric 
4930b57cec5SDimitry Andric     if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
4940b57cec5SDimitry Andric       return false;
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric     break;
4970b57cec5SDimitry Andric   }
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5000b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5010b57cec5SDimitry Andric     .TraverseType(NameInfo.getName().getCXXNameType());
5020b57cec5SDimitry Andric   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
5030b57cec5SDimitry Andric   return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
5040b57cec5SDimitry Andric }
5050b57cec5SDimitry Andric 
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TemplateName Template,UnexpandedParameterPackContext UPPC)5060b57cec5SDimitry Andric bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
5070b57cec5SDimitry Andric                                            TemplateName Template,
5080b57cec5SDimitry Andric                                        UnexpandedParameterPackContext UPPC) {
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric   if (Template.isNull() || !Template.containsUnexpandedParameterPack())
5110b57cec5SDimitry Andric     return false;
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5140b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5150b57cec5SDimitry Andric     .TraverseTemplateName(Template);
5160b57cec5SDimitry Andric   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
5170b57cec5SDimitry Andric   return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
5180b57cec5SDimitry Andric }
5190b57cec5SDimitry Andric 
DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,UnexpandedParameterPackContext UPPC)5200b57cec5SDimitry Andric bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
5210b57cec5SDimitry Andric                                          UnexpandedParameterPackContext UPPC) {
5220b57cec5SDimitry Andric   if (Arg.getArgument().isNull() ||
5230b57cec5SDimitry Andric       !Arg.getArgument().containsUnexpandedParameterPack())
5240b57cec5SDimitry Andric     return false;
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5270b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5280b57cec5SDimitry Andric     .TraverseTemplateArgumentLoc(Arg);
5290b57cec5SDimitry Andric   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
5300b57cec5SDimitry Andric   return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
5310b57cec5SDimitry Andric }
5320b57cec5SDimitry Andric 
collectUnexpandedParameterPacks(TemplateArgument Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5330b57cec5SDimitry Andric void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
5340b57cec5SDimitry Andric                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5350b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5360b57cec5SDimitry Andric     .TraverseTemplateArgument(Arg);
5370b57cec5SDimitry Andric }
5380b57cec5SDimitry Andric 
collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5390b57cec5SDimitry Andric void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
5400b57cec5SDimitry Andric                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5410b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5420b57cec5SDimitry Andric     .TraverseTemplateArgumentLoc(Arg);
5430b57cec5SDimitry Andric }
5440b57cec5SDimitry Andric 
collectUnexpandedParameterPacks(QualType T,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5450b57cec5SDimitry Andric void Sema::collectUnexpandedParameterPacks(QualType T,
5460b57cec5SDimitry Andric                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5470b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
5480b57cec5SDimitry Andric }
5490b57cec5SDimitry Andric 
collectUnexpandedParameterPacks(TypeLoc TL,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5500b57cec5SDimitry Andric void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
5510b57cec5SDimitry Andric                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5520b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric 
collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5550b57cec5SDimitry Andric void Sema::collectUnexpandedParameterPacks(
5560b57cec5SDimitry Andric     NestedNameSpecifierLoc NNS,
5570b57cec5SDimitry Andric     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5580b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5590b57cec5SDimitry Andric       .TraverseNestedNameSpecifierLoc(NNS);
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric 
collectUnexpandedParameterPacks(const DeclarationNameInfo & NameInfo,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5620b57cec5SDimitry Andric void Sema::collectUnexpandedParameterPacks(
5630b57cec5SDimitry Andric     const DeclarationNameInfo &NameInfo,
5640b57cec5SDimitry Andric     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5650b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5660b57cec5SDimitry Andric     .TraverseDeclarationNameInfo(NameInfo);
5670b57cec5SDimitry Andric }
5680b57cec5SDimitry Andric 
collectUnexpandedParameterPacks(Expr * E,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)569*0fca6ea1SDimitry Andric void Sema::collectUnexpandedParameterPacks(
570*0fca6ea1SDimitry Andric     Expr *E, SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
571*0fca6ea1SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
572*0fca6ea1SDimitry Andric }
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric ParsedTemplateArgument
ActOnPackExpansion(const ParsedTemplateArgument & Arg,SourceLocation EllipsisLoc)5750b57cec5SDimitry Andric Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
5760b57cec5SDimitry Andric                          SourceLocation EllipsisLoc) {
5770b57cec5SDimitry Andric   if (Arg.isInvalid())
5780b57cec5SDimitry Andric     return Arg;
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric   switch (Arg.getKind()) {
5810b57cec5SDimitry Andric   case ParsedTemplateArgument::Type: {
5820b57cec5SDimitry Andric     TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
5830b57cec5SDimitry Andric     if (Result.isInvalid())
5840b57cec5SDimitry Andric       return ParsedTemplateArgument();
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric     return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
5870b57cec5SDimitry Andric                                   Arg.getLocation());
5880b57cec5SDimitry Andric   }
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric   case ParsedTemplateArgument::NonType: {
5910b57cec5SDimitry Andric     ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
5920b57cec5SDimitry Andric     if (Result.isInvalid())
5930b57cec5SDimitry Andric       return ParsedTemplateArgument();
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric     return ParsedTemplateArgument(Arg.getKind(), Result.get(),
5960b57cec5SDimitry Andric                                   Arg.getLocation());
5970b57cec5SDimitry Andric   }
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric   case ParsedTemplateArgument::Template:
6000b57cec5SDimitry Andric     if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
6010b57cec5SDimitry Andric       SourceRange R(Arg.getLocation());
6020b57cec5SDimitry Andric       if (Arg.getScopeSpec().isValid())
6030b57cec5SDimitry Andric         R.setBegin(Arg.getScopeSpec().getBeginLoc());
6040b57cec5SDimitry Andric       Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
6050b57cec5SDimitry Andric         << R;
6060b57cec5SDimitry Andric       return ParsedTemplateArgument();
6070b57cec5SDimitry Andric     }
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric     return Arg.getTemplatePackExpansion(EllipsisLoc);
6100b57cec5SDimitry Andric   }
6110b57cec5SDimitry Andric   llvm_unreachable("Unhandled template argument kind?");
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
ActOnPackExpansion(ParsedType Type,SourceLocation EllipsisLoc)6140b57cec5SDimitry Andric TypeResult Sema::ActOnPackExpansion(ParsedType Type,
6150b57cec5SDimitry Andric                                     SourceLocation EllipsisLoc) {
6160b57cec5SDimitry Andric   TypeSourceInfo *TSInfo;
6170b57cec5SDimitry Andric   GetTypeFromParser(Type, &TSInfo);
6180b57cec5SDimitry Andric   if (!TSInfo)
6190b57cec5SDimitry Andric     return true;
6200b57cec5SDimitry Andric 
621bdd1243dSDimitry Andric   TypeSourceInfo *TSResult =
622bdd1243dSDimitry Andric       CheckPackExpansion(TSInfo, EllipsisLoc, std::nullopt);
6230b57cec5SDimitry Andric   if (!TSResult)
6240b57cec5SDimitry Andric     return true;
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric   return CreateParsedType(TSResult->getType(), TSResult);
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric 
6290b57cec5SDimitry Andric TypeSourceInfo *
CheckPackExpansion(TypeSourceInfo * Pattern,SourceLocation EllipsisLoc,std::optional<unsigned> NumExpansions)6300b57cec5SDimitry Andric Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc,
631bdd1243dSDimitry Andric                          std::optional<unsigned> NumExpansions) {
6320b57cec5SDimitry Andric   // Create the pack expansion type and source-location information.
6330b57cec5SDimitry Andric   QualType Result = CheckPackExpansion(Pattern->getType(),
6340b57cec5SDimitry Andric                                        Pattern->getTypeLoc().getSourceRange(),
6350b57cec5SDimitry Andric                                        EllipsisLoc, NumExpansions);
6360b57cec5SDimitry Andric   if (Result.isNull())
6370b57cec5SDimitry Andric     return nullptr;
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric   TypeLocBuilder TLB;
6400b57cec5SDimitry Andric   TLB.pushFullCopy(Pattern->getTypeLoc());
6410b57cec5SDimitry Andric   PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result);
6420b57cec5SDimitry Andric   TL.setEllipsisLoc(EllipsisLoc);
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   return TLB.getTypeSourceInfo(Context, Result);
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric 
CheckPackExpansion(QualType Pattern,SourceRange PatternRange,SourceLocation EllipsisLoc,std::optional<unsigned> NumExpansions)6470b57cec5SDimitry Andric QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
6480b57cec5SDimitry Andric                                   SourceLocation EllipsisLoc,
649bdd1243dSDimitry Andric                                   std::optional<unsigned> NumExpansions) {
6500b57cec5SDimitry Andric   // C++11 [temp.variadic]p5:
6510b57cec5SDimitry Andric   //   The pattern of a pack expansion shall name one or more
6520b57cec5SDimitry Andric   //   parameter packs that are not expanded by a nested pack
6530b57cec5SDimitry Andric   //   expansion.
6540b57cec5SDimitry Andric   //
6550b57cec5SDimitry Andric   // A pattern containing a deduced type can't occur "naturally" but arises in
6560b57cec5SDimitry Andric   // the desugaring of an init-capture pack.
6570b57cec5SDimitry Andric   if (!Pattern->containsUnexpandedParameterPack() &&
6580b57cec5SDimitry Andric       !Pattern->getContainedDeducedType()) {
6590b57cec5SDimitry Andric     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
6600b57cec5SDimitry Andric       << PatternRange;
6610b57cec5SDimitry Andric     return QualType();
6620b57cec5SDimitry Andric   }
6630b57cec5SDimitry Andric 
664e63539f3SDimitry Andric   return Context.getPackExpansionType(Pattern, NumExpansions,
665e63539f3SDimitry Andric                                       /*ExpectPackInType=*/false);
6660b57cec5SDimitry Andric }
6670b57cec5SDimitry Andric 
ActOnPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc)6680b57cec5SDimitry Andric ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
669bdd1243dSDimitry Andric   return CheckPackExpansion(Pattern, EllipsisLoc, std::nullopt);
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric 
CheckPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc,std::optional<unsigned> NumExpansions)6720b57cec5SDimitry Andric ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
673bdd1243dSDimitry Andric                                     std::optional<unsigned> NumExpansions) {
6740b57cec5SDimitry Andric   if (!Pattern)
6750b57cec5SDimitry Andric     return ExprError();
6760b57cec5SDimitry Andric 
6770b57cec5SDimitry Andric   // C++0x [temp.variadic]p5:
6780b57cec5SDimitry Andric   //   The pattern of a pack expansion shall name one or more
6790b57cec5SDimitry Andric   //   parameter packs that are not expanded by a nested pack
6800b57cec5SDimitry Andric   //   expansion.
6810b57cec5SDimitry Andric   if (!Pattern->containsUnexpandedParameterPack()) {
6820b57cec5SDimitry Andric     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
6830b57cec5SDimitry Andric     << Pattern->getSourceRange();
6840b57cec5SDimitry Andric     CorrectDelayedTyposInExpr(Pattern);
6850b57cec5SDimitry Andric     return ExprError();
6860b57cec5SDimitry Andric   }
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   // Create the pack expansion expression and source-location information.
6890b57cec5SDimitry Andric   return new (Context)
6900b57cec5SDimitry Andric     PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
6910b57cec5SDimitry Andric }
6920b57cec5SDimitry Andric 
CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,SourceRange PatternRange,ArrayRef<UnexpandedParameterPack> Unexpanded,const MultiLevelTemplateArgumentList & TemplateArgs,bool & ShouldExpand,bool & RetainExpansion,std::optional<unsigned> & NumExpansions)6930b57cec5SDimitry Andric bool Sema::CheckParameterPacksForExpansion(
6940b57cec5SDimitry Andric     SourceLocation EllipsisLoc, SourceRange PatternRange,
6950b57cec5SDimitry Andric     ArrayRef<UnexpandedParameterPack> Unexpanded,
6960b57cec5SDimitry Andric     const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
697bdd1243dSDimitry Andric     bool &RetainExpansion, std::optional<unsigned> &NumExpansions) {
6980b57cec5SDimitry Andric   ShouldExpand = true;
6990b57cec5SDimitry Andric   RetainExpansion = false;
7001ac55f4cSDimitry Andric   std::pair<IdentifierInfo *, SourceLocation> FirstPack;
7011ac55f4cSDimitry Andric   bool HaveFirstPack = false;
7021ac55f4cSDimitry Andric   std::optional<unsigned> NumPartialExpansions;
7031ac55f4cSDimitry Andric   SourceLocation PartiallySubstitutedPackLoc;
7040b57cec5SDimitry Andric 
7051ac55f4cSDimitry Andric   for (UnexpandedParameterPack ParmPack : Unexpanded) {
7060b57cec5SDimitry Andric     // Compute the depth and index for this parameter pack.
7071ac55f4cSDimitry Andric     unsigned Depth = 0, Index = 0;
7081ac55f4cSDimitry Andric     IdentifierInfo *Name;
7091ac55f4cSDimitry Andric     bool IsVarDeclPack = false;
7101ac55f4cSDimitry Andric 
7111ac55f4cSDimitry Andric     if (const TemplateTypeParmType *TTP =
7121ac55f4cSDimitry Andric             ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
7131ac55f4cSDimitry Andric       Depth = TTP->getDepth();
7141ac55f4cSDimitry Andric       Index = TTP->getIndex();
7151ac55f4cSDimitry Andric       Name = TTP->getIdentifier();
7161ac55f4cSDimitry Andric     } else {
7171ac55f4cSDimitry Andric       NamedDecl *ND = ParmPack.first.get<NamedDecl *>();
7181ac55f4cSDimitry Andric       if (isa<VarDecl>(ND))
7191ac55f4cSDimitry Andric         IsVarDeclPack = true;
7201ac55f4cSDimitry Andric       else
7211ac55f4cSDimitry Andric         std::tie(Depth, Index) = getDepthAndIndex(ND);
7221ac55f4cSDimitry Andric 
7231ac55f4cSDimitry Andric       Name = ND->getIdentifier();
7241ac55f4cSDimitry Andric     }
7251ac55f4cSDimitry Andric 
7261ac55f4cSDimitry Andric     // Determine the size of this argument pack.
7270b57cec5SDimitry Andric     unsigned NewPackSize;
7281ac55f4cSDimitry Andric     if (IsVarDeclPack) {
7291ac55f4cSDimitry Andric       // Figure out whether we're instantiating to an argument pack or not.
7301ac55f4cSDimitry Andric       typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
7311ac55f4cSDimitry Andric 
7321ac55f4cSDimitry Andric       llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
7331ac55f4cSDimitry Andric           CurrentInstantiationScope->findInstantiationOf(
7341ac55f4cSDimitry Andric               ParmPack.first.get<NamedDecl *>());
7351ac55f4cSDimitry Andric       if (Instantiation->is<DeclArgumentPack *>()) {
7361ac55f4cSDimitry Andric         // We could expand this function parameter pack.
7371ac55f4cSDimitry Andric         NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
7381ac55f4cSDimitry Andric       } else {
7390b57cec5SDimitry Andric         // We can't expand this function parameter pack, so we can't expand
7400b57cec5SDimitry Andric         // the pack expansion.
7410b57cec5SDimitry Andric         ShouldExpand = false;
7420b57cec5SDimitry Andric         continue;
7430b57cec5SDimitry Andric       }
7440b57cec5SDimitry Andric     } else {
7450b57cec5SDimitry Andric       // If we don't have a template argument at this depth/index, then we
7460b57cec5SDimitry Andric       // cannot expand the pack expansion. Make a note of this, but we still
7470b57cec5SDimitry Andric       // want to check any parameter packs we *do* have arguments for.
7481ac55f4cSDimitry Andric       if (Depth >= TemplateArgs.getNumLevels() ||
7491ac55f4cSDimitry Andric           !TemplateArgs.hasTemplateArgument(Depth, Index)) {
7500b57cec5SDimitry Andric         ShouldExpand = false;
7510b57cec5SDimitry Andric         continue;
7520b57cec5SDimitry Andric       }
7531ac55f4cSDimitry Andric 
7540b57cec5SDimitry Andric       // Determine the size of the argument pack.
7551ac55f4cSDimitry Andric       NewPackSize = TemplateArgs(Depth, Index).pack_size();
7561ac55f4cSDimitry Andric     }
7571ac55f4cSDimitry Andric 
7580b57cec5SDimitry Andric     // C++0x [temp.arg.explicit]p9:
7590b57cec5SDimitry Andric     //   Template argument deduction can extend the sequence of template
7600b57cec5SDimitry Andric     //   arguments corresponding to a template parameter pack, even when the
7610b57cec5SDimitry Andric     //   sequence contains explicitly specified template arguments.
7621ac55f4cSDimitry Andric     if (!IsVarDeclPack && CurrentInstantiationScope) {
7631ac55f4cSDimitry Andric       if (NamedDecl *PartialPack =
7641ac55f4cSDimitry Andric               CurrentInstantiationScope->getPartiallySubstitutedPack()) {
7651ac55f4cSDimitry Andric         unsigned PartialDepth, PartialIndex;
7661ac55f4cSDimitry Andric         std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
7671ac55f4cSDimitry Andric         if (PartialDepth == Depth && PartialIndex == Index) {
7680b57cec5SDimitry Andric           RetainExpansion = true;
7690b57cec5SDimitry Andric           // We don't actually know the new pack size yet.
7701ac55f4cSDimitry Andric           NumPartialExpansions = NewPackSize;
7711ac55f4cSDimitry Andric           PartiallySubstitutedPackLoc = ParmPack.second;
7720b57cec5SDimitry Andric           continue;
7730b57cec5SDimitry Andric         }
7740b57cec5SDimitry Andric       }
7751ac55f4cSDimitry Andric     }
7760b57cec5SDimitry Andric 
7771ac55f4cSDimitry Andric     if (!NumExpansions) {
7780b57cec5SDimitry Andric       // The is the first pack we've seen for which we have an argument.
7790b57cec5SDimitry Andric       // Record it.
7801ac55f4cSDimitry Andric       NumExpansions = NewPackSize;
7811ac55f4cSDimitry Andric       FirstPack.first = Name;
7821ac55f4cSDimitry Andric       FirstPack.second = ParmPack.second;
7831ac55f4cSDimitry Andric       HaveFirstPack = true;
7841ac55f4cSDimitry Andric       continue;
7851ac55f4cSDimitry Andric     }
7861ac55f4cSDimitry Andric 
7871ac55f4cSDimitry Andric     if (NewPackSize != *NumExpansions) {
7880b57cec5SDimitry Andric       // C++0x [temp.variadic]p5:
7890b57cec5SDimitry Andric       //   All of the parameter packs expanded by a pack expansion shall have
7900b57cec5SDimitry Andric       //   the same number of arguments specified.
7911ac55f4cSDimitry Andric       if (HaveFirstPack)
7920b57cec5SDimitry Andric         Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
7931ac55f4cSDimitry Andric             << FirstPack.first << Name << *NumExpansions << NewPackSize
7941ac55f4cSDimitry Andric             << SourceRange(FirstPack.second) << SourceRange(ParmPack.second);
7951ac55f4cSDimitry Andric       else
796bdd1243dSDimitry Andric         Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
7971ac55f4cSDimitry Andric             << Name << *NumExpansions << NewPackSize
7981ac55f4cSDimitry Andric             << SourceRange(ParmPack.second);
799bdd1243dSDimitry Andric       return true;
800bdd1243dSDimitry Andric     }
8011ac55f4cSDimitry Andric   }
802bdd1243dSDimitry Andric 
8030b57cec5SDimitry Andric   // If we're performing a partial expansion but we also have a full expansion,
8040b57cec5SDimitry Andric   // expand to the number of common arguments. For example, given:
8050b57cec5SDimitry Andric   //
8060b57cec5SDimitry Andric   //   template<typename ...T> struct A {
8070b57cec5SDimitry Andric   //     template<typename ...U> void f(pair<T, U>...);
8080b57cec5SDimitry Andric   //   };
8090b57cec5SDimitry Andric   //
8100b57cec5SDimitry Andric   // ... a call to 'A<int, int>().f<int>' should expand the pack once and
8110b57cec5SDimitry Andric   // retain an expansion.
8121ac55f4cSDimitry Andric   if (NumPartialExpansions) {
8131ac55f4cSDimitry Andric     if (NumExpansions && *NumExpansions < *NumPartialExpansions) {
8140b57cec5SDimitry Andric       NamedDecl *PartialPack =
8150b57cec5SDimitry Andric           CurrentInstantiationScope->getPartiallySubstitutedPack();
8160b57cec5SDimitry Andric       Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial)
8171ac55f4cSDimitry Andric           << PartialPack << *NumPartialExpansions << *NumExpansions
8181ac55f4cSDimitry Andric           << SourceRange(PartiallySubstitutedPackLoc);
8190b57cec5SDimitry Andric       return true;
8200b57cec5SDimitry Andric     }
8211ac55f4cSDimitry Andric 
8221ac55f4cSDimitry Andric     NumExpansions = NumPartialExpansions;
8230b57cec5SDimitry Andric   }
8240b57cec5SDimitry Andric 
8250b57cec5SDimitry Andric   return false;
8260b57cec5SDimitry Andric }
8270b57cec5SDimitry Andric 
getNumArgumentsInExpansion(QualType T,const MultiLevelTemplateArgumentList & TemplateArgs)828bdd1243dSDimitry Andric std::optional<unsigned> Sema::getNumArgumentsInExpansion(
829bdd1243dSDimitry Andric     QualType T, const MultiLevelTemplateArgumentList &TemplateArgs) {
8300b57cec5SDimitry Andric   QualType Pattern = cast<PackExpansionType>(T)->getPattern();
8310b57cec5SDimitry Andric   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8320b57cec5SDimitry Andric   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
8330b57cec5SDimitry Andric 
834bdd1243dSDimitry Andric   std::optional<unsigned> Result;
8351ac55f4cSDimitry Andric   for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
8361ac55f4cSDimitry Andric     // Compute the depth and index for this parameter pack.
8371ac55f4cSDimitry Andric     unsigned Depth;
8381ac55f4cSDimitry Andric     unsigned Index;
8391ac55f4cSDimitry Andric 
8401ac55f4cSDimitry Andric     if (const TemplateTypeParmType *TTP =
8411ac55f4cSDimitry Andric             Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
8421ac55f4cSDimitry Andric       Depth = TTP->getDepth();
8431ac55f4cSDimitry Andric       Index = TTP->getIndex();
8441ac55f4cSDimitry Andric     } else {
8451ac55f4cSDimitry Andric       NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
8461ac55f4cSDimitry Andric       if (isa<VarDecl>(ND)) {
8471ac55f4cSDimitry Andric         // Function parameter pack or init-capture pack.
8481ac55f4cSDimitry Andric         typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
8491ac55f4cSDimitry Andric 
8501ac55f4cSDimitry Andric         llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
8511ac55f4cSDimitry Andric             CurrentInstantiationScope->findInstantiationOf(
8521ac55f4cSDimitry Andric                 Unexpanded[I].first.get<NamedDecl *>());
8531ac55f4cSDimitry Andric         if (Instantiation->is<Decl *>())
8541ac55f4cSDimitry Andric           // The pattern refers to an unexpanded pack. We're not ready to expand
8551ac55f4cSDimitry Andric           // this pack yet.
8561ac55f4cSDimitry Andric           return std::nullopt;
8571ac55f4cSDimitry Andric 
8581ac55f4cSDimitry Andric         unsigned Size = Instantiation->get<DeclArgumentPack *>()->size();
8590b57cec5SDimitry Andric         assert((!Result || *Result == Size) && "inconsistent pack sizes");
8600b57cec5SDimitry Andric         Result = Size;
8611ac55f4cSDimitry Andric         continue;
8621ac55f4cSDimitry Andric       }
8631ac55f4cSDimitry Andric 
8641ac55f4cSDimitry Andric       std::tie(Depth, Index) = getDepthAndIndex(ND);
8651ac55f4cSDimitry Andric     }
8660b57cec5SDimitry Andric     if (Depth >= TemplateArgs.getNumLevels() ||
8670b57cec5SDimitry Andric         !TemplateArgs.hasTemplateArgument(Depth, Index))
8680b57cec5SDimitry Andric       // The pattern refers to an unknown template argument. We're not ready to
8690b57cec5SDimitry Andric       // expand this pack yet.
8701ac55f4cSDimitry Andric       return std::nullopt;
871bdd1243dSDimitry Andric 
8721ac55f4cSDimitry Andric     // Determine the size of the argument pack.
8731ac55f4cSDimitry Andric     unsigned Size = TemplateArgs(Depth, Index).pack_size();
8741ac55f4cSDimitry Andric     assert((!Result || *Result == Size) && "inconsistent pack sizes");
8751ac55f4cSDimitry Andric     Result = Size;
8760b57cec5SDimitry Andric   }
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric   return Result;
8790b57cec5SDimitry Andric }
8800b57cec5SDimitry Andric 
containsUnexpandedParameterPacks(Declarator & D)8810b57cec5SDimitry Andric bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
8820b57cec5SDimitry Andric   const DeclSpec &DS = D.getDeclSpec();
8830b57cec5SDimitry Andric   switch (DS.getTypeSpecType()) {
884*0fca6ea1SDimitry Andric   case TST_typename_pack_indexing:
8850b57cec5SDimitry Andric   case TST_typename:
886bdd1243dSDimitry Andric   case TST_typeof_unqualType:
8870b57cec5SDimitry Andric   case TST_typeofType:
888bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:
889bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def"
8900b57cec5SDimitry Andric   case TST_atomic: {
8910b57cec5SDimitry Andric     QualType T = DS.getRepAsType().get();
8920b57cec5SDimitry Andric     if (!T.isNull() && T->containsUnexpandedParameterPack())
8930b57cec5SDimitry Andric       return true;
8940b57cec5SDimitry Andric     break;
8950b57cec5SDimitry Andric   }
8960b57cec5SDimitry Andric 
897bdd1243dSDimitry Andric   case TST_typeof_unqualExpr:
8980b57cec5SDimitry Andric   case TST_typeofExpr:
8990b57cec5SDimitry Andric   case TST_decltype:
9000eae32dcSDimitry Andric   case TST_bitint:
9010b57cec5SDimitry Andric     if (DS.getRepAsExpr() &&
9020b57cec5SDimitry Andric         DS.getRepAsExpr()->containsUnexpandedParameterPack())
9030b57cec5SDimitry Andric       return true;
9040b57cec5SDimitry Andric     break;
9050b57cec5SDimitry Andric 
9060b57cec5SDimitry Andric   case TST_unspecified:
9070b57cec5SDimitry Andric   case TST_void:
9080b57cec5SDimitry Andric   case TST_char:
9090b57cec5SDimitry Andric   case TST_wchar:
9100b57cec5SDimitry Andric   case TST_char8:
9110b57cec5SDimitry Andric   case TST_char16:
9120b57cec5SDimitry Andric   case TST_char32:
9130b57cec5SDimitry Andric   case TST_int:
9140b57cec5SDimitry Andric   case TST_int128:
9150b57cec5SDimitry Andric   case TST_half:
9160b57cec5SDimitry Andric   case TST_float:
9170b57cec5SDimitry Andric   case TST_double:
9180b57cec5SDimitry Andric   case TST_Accum:
9190b57cec5SDimitry Andric   case TST_Fract:
9200b57cec5SDimitry Andric   case TST_Float16:
9210b57cec5SDimitry Andric   case TST_float128:
922349cc55cSDimitry Andric   case TST_ibm128:
9230b57cec5SDimitry Andric   case TST_bool:
9240b57cec5SDimitry Andric   case TST_decimal32:
9250b57cec5SDimitry Andric   case TST_decimal64:
9260b57cec5SDimitry Andric   case TST_decimal128:
9270b57cec5SDimitry Andric   case TST_enum:
9280b57cec5SDimitry Andric   case TST_union:
9290b57cec5SDimitry Andric   case TST_struct:
9300b57cec5SDimitry Andric   case TST_interface:
9310b57cec5SDimitry Andric   case TST_class:
9320b57cec5SDimitry Andric   case TST_auto:
9330b57cec5SDimitry Andric   case TST_auto_type:
9340b57cec5SDimitry Andric   case TST_decltype_auto:
9355ffd83dbSDimitry Andric   case TST_BFloat16:
9360b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:
9370b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def"
9380b57cec5SDimitry Andric   case TST_unknown_anytype:
9390b57cec5SDimitry Andric   case TST_error:
9400b57cec5SDimitry Andric     break;
9410b57cec5SDimitry Andric   }
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric   for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
9440b57cec5SDimitry Andric     const DeclaratorChunk &Chunk = D.getTypeObject(I);
9450b57cec5SDimitry Andric     switch (Chunk.Kind) {
9460b57cec5SDimitry Andric     case DeclaratorChunk::Pointer:
9470b57cec5SDimitry Andric     case DeclaratorChunk::Reference:
9480b57cec5SDimitry Andric     case DeclaratorChunk::Paren:
9490b57cec5SDimitry Andric     case DeclaratorChunk::Pipe:
9500b57cec5SDimitry Andric     case DeclaratorChunk::BlockPointer:
9510b57cec5SDimitry Andric       // These declarator chunks cannot contain any parameter packs.
9520b57cec5SDimitry Andric       break;
9530b57cec5SDimitry Andric 
9540b57cec5SDimitry Andric     case DeclaratorChunk::Array:
9550b57cec5SDimitry Andric       if (Chunk.Arr.NumElts &&
9560b57cec5SDimitry Andric           Chunk.Arr.NumElts->containsUnexpandedParameterPack())
9570b57cec5SDimitry Andric         return true;
9580b57cec5SDimitry Andric       break;
9590b57cec5SDimitry Andric     case DeclaratorChunk::Function:
9600b57cec5SDimitry Andric       for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) {
9610b57cec5SDimitry Andric         ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param);
9620b57cec5SDimitry Andric         QualType ParamTy = Param->getType();
9630b57cec5SDimitry Andric         assert(!ParamTy.isNull() && "Couldn't parse type?");
9640b57cec5SDimitry Andric         if (ParamTy->containsUnexpandedParameterPack()) return true;
9650b57cec5SDimitry Andric       }
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric       if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) {
9680b57cec5SDimitry Andric         for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) {
9690b57cec5SDimitry Andric           if (Chunk.Fun.Exceptions[i]
9700b57cec5SDimitry Andric                   .Ty.get()
9710b57cec5SDimitry Andric                   ->containsUnexpandedParameterPack())
9720b57cec5SDimitry Andric             return true;
9730b57cec5SDimitry Andric         }
9740b57cec5SDimitry Andric       } else if (isComputedNoexcept(Chunk.Fun.getExceptionSpecType()) &&
9750b57cec5SDimitry Andric                  Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack())
9760b57cec5SDimitry Andric         return true;
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric       if (Chunk.Fun.hasTrailingReturnType()) {
9790b57cec5SDimitry Andric         QualType T = Chunk.Fun.getTrailingReturnType().get();
9800b57cec5SDimitry Andric         if (!T.isNull() && T->containsUnexpandedParameterPack())
9810b57cec5SDimitry Andric           return true;
9820b57cec5SDimitry Andric       }
9830b57cec5SDimitry Andric       break;
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric     case DeclaratorChunk::MemberPointer:
9860b57cec5SDimitry Andric       if (Chunk.Mem.Scope().getScopeRep() &&
9870b57cec5SDimitry Andric           Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
9880b57cec5SDimitry Andric         return true;
9890b57cec5SDimitry Andric       break;
9900b57cec5SDimitry Andric     }
9910b57cec5SDimitry Andric   }
9920b57cec5SDimitry Andric 
993480093f4SDimitry Andric   if (Expr *TRC = D.getTrailingRequiresClause())
994480093f4SDimitry Andric     if (TRC->containsUnexpandedParameterPack())
995480093f4SDimitry Andric       return true;
996480093f4SDimitry Andric 
9970b57cec5SDimitry Andric   return false;
9980b57cec5SDimitry Andric }
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric namespace {
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric // Callback to only accept typo corrections that refer to parameter packs.
10030b57cec5SDimitry Andric class ParameterPackValidatorCCC final : public CorrectionCandidateCallback {
10040b57cec5SDimitry Andric  public:
ValidateCandidate(const TypoCorrection & candidate)10050b57cec5SDimitry Andric   bool ValidateCandidate(const TypoCorrection &candidate) override {
10060b57cec5SDimitry Andric     NamedDecl *ND = candidate.getCorrectionDecl();
10070b57cec5SDimitry Andric     return ND && ND->isParameterPack();
10080b57cec5SDimitry Andric   }
10090b57cec5SDimitry Andric 
clone()10100b57cec5SDimitry Andric   std::unique_ptr<CorrectionCandidateCallback> clone() override {
1011a7dea167SDimitry Andric     return std::make_unique<ParameterPackValidatorCCC>(*this);
10120b57cec5SDimitry Andric   }
10130b57cec5SDimitry Andric };
10140b57cec5SDimitry Andric 
10150b57cec5SDimitry Andric }
10160b57cec5SDimitry Andric 
ActOnSizeofParameterPackExpr(Scope * S,SourceLocation OpLoc,IdentifierInfo & Name,SourceLocation NameLoc,SourceLocation RParenLoc)10170b57cec5SDimitry Andric ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
10180b57cec5SDimitry Andric                                               SourceLocation OpLoc,
10190b57cec5SDimitry Andric                                               IdentifierInfo &Name,
10200b57cec5SDimitry Andric                                               SourceLocation NameLoc,
10210b57cec5SDimitry Andric                                               SourceLocation RParenLoc) {
10220b57cec5SDimitry Andric   // C++0x [expr.sizeof]p5:
10230b57cec5SDimitry Andric   //   The identifier in a sizeof... expression shall name a parameter pack.
10240b57cec5SDimitry Andric   LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
10250b57cec5SDimitry Andric   LookupName(R, S);
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric   NamedDecl *ParameterPack = nullptr;
10280b57cec5SDimitry Andric   switch (R.getResultKind()) {
10290b57cec5SDimitry Andric   case LookupResult::Found:
10300b57cec5SDimitry Andric     ParameterPack = R.getFoundDecl();
10310b57cec5SDimitry Andric     break;
10320b57cec5SDimitry Andric 
10330b57cec5SDimitry Andric   case LookupResult::NotFound:
10340b57cec5SDimitry Andric   case LookupResult::NotFoundInCurrentInstantiation: {
10350b57cec5SDimitry Andric     ParameterPackValidatorCCC CCC{};
10360b57cec5SDimitry Andric     if (TypoCorrection Corrected =
10370b57cec5SDimitry Andric             CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr,
10380b57cec5SDimitry Andric                         CCC, CTK_ErrorRecovery)) {
10390b57cec5SDimitry Andric       diagnoseTypo(Corrected,
10400b57cec5SDimitry Andric                    PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,
10410b57cec5SDimitry Andric                    PDiag(diag::note_parameter_pack_here));
10420b57cec5SDimitry Andric       ParameterPack = Corrected.getCorrectionDecl();
10430b57cec5SDimitry Andric     }
10440b57cec5SDimitry Andric     break;
10450b57cec5SDimitry Andric   }
10460b57cec5SDimitry Andric   case LookupResult::FoundOverloaded:
10470b57cec5SDimitry Andric   case LookupResult::FoundUnresolvedValue:
10480b57cec5SDimitry Andric     break;
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   case LookupResult::Ambiguous:
10510b57cec5SDimitry Andric     DiagnoseAmbiguousLookup(R);
10520b57cec5SDimitry Andric     return ExprError();
10530b57cec5SDimitry Andric   }
10540b57cec5SDimitry Andric 
10550b57cec5SDimitry Andric   if (!ParameterPack || !ParameterPack->isParameterPack()) {
1056*0fca6ea1SDimitry Andric     Diag(NameLoc, diag::err_expected_name_of_pack) << &Name;
10570b57cec5SDimitry Andric     return ExprError();
10580b57cec5SDimitry Andric   }
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric   MarkAnyDeclReferenced(OpLoc, ParameterPack, true);
10610b57cec5SDimitry Andric 
10620b57cec5SDimitry Andric   return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc,
10630b57cec5SDimitry Andric                                 RParenLoc);
10640b57cec5SDimitry Andric }
10650b57cec5SDimitry Andric 
isParameterPack(Expr * PackExpression)1066*0fca6ea1SDimitry Andric static bool isParameterPack(Expr *PackExpression) {
1067*0fca6ea1SDimitry Andric   if (auto *D = dyn_cast<DeclRefExpr>(PackExpression); D) {
1068*0fca6ea1SDimitry Andric     ValueDecl *VD = D->getDecl();
1069*0fca6ea1SDimitry Andric     return VD->isParameterPack();
1070*0fca6ea1SDimitry Andric   }
1071*0fca6ea1SDimitry Andric   return false;
1072*0fca6ea1SDimitry Andric }
1073*0fca6ea1SDimitry Andric 
ActOnPackIndexingExpr(Scope * S,Expr * PackExpression,SourceLocation EllipsisLoc,SourceLocation LSquareLoc,Expr * IndexExpr,SourceLocation RSquareLoc)1074*0fca6ea1SDimitry Andric ExprResult Sema::ActOnPackIndexingExpr(Scope *S, Expr *PackExpression,
1075*0fca6ea1SDimitry Andric                                        SourceLocation EllipsisLoc,
1076*0fca6ea1SDimitry Andric                                        SourceLocation LSquareLoc,
1077*0fca6ea1SDimitry Andric                                        Expr *IndexExpr,
1078*0fca6ea1SDimitry Andric                                        SourceLocation RSquareLoc) {
1079*0fca6ea1SDimitry Andric   bool isParameterPack = ::isParameterPack(PackExpression);
1080*0fca6ea1SDimitry Andric   if (!isParameterPack) {
1081*0fca6ea1SDimitry Andric     if (!PackExpression->containsErrors()) {
1082*0fca6ea1SDimitry Andric       CorrectDelayedTyposInExpr(IndexExpr);
1083*0fca6ea1SDimitry Andric       Diag(PackExpression->getBeginLoc(), diag::err_expected_name_of_pack)
1084*0fca6ea1SDimitry Andric           << PackExpression;
1085*0fca6ea1SDimitry Andric     }
1086*0fca6ea1SDimitry Andric     return ExprError();
1087*0fca6ea1SDimitry Andric   }
1088*0fca6ea1SDimitry Andric   ExprResult Res =
1089*0fca6ea1SDimitry Andric       BuildPackIndexingExpr(PackExpression, EllipsisLoc, IndexExpr, RSquareLoc);
1090*0fca6ea1SDimitry Andric   if (!Res.isInvalid())
1091*0fca6ea1SDimitry Andric     Diag(Res.get()->getBeginLoc(), getLangOpts().CPlusPlus26
1092*0fca6ea1SDimitry Andric                                        ? diag::warn_cxx23_pack_indexing
1093*0fca6ea1SDimitry Andric                                        : diag::ext_pack_indexing);
1094*0fca6ea1SDimitry Andric   return Res;
1095*0fca6ea1SDimitry Andric }
1096*0fca6ea1SDimitry Andric 
1097*0fca6ea1SDimitry Andric ExprResult
BuildPackIndexingExpr(Expr * PackExpression,SourceLocation EllipsisLoc,Expr * IndexExpr,SourceLocation RSquareLoc,ArrayRef<Expr * > ExpandedExprs,bool EmptyPack)1098*0fca6ea1SDimitry Andric Sema::BuildPackIndexingExpr(Expr *PackExpression, SourceLocation EllipsisLoc,
1099*0fca6ea1SDimitry Andric                             Expr *IndexExpr, SourceLocation RSquareLoc,
1100*0fca6ea1SDimitry Andric                             ArrayRef<Expr *> ExpandedExprs, bool EmptyPack) {
1101*0fca6ea1SDimitry Andric 
1102*0fca6ea1SDimitry Andric   std::optional<int64_t> Index;
1103*0fca6ea1SDimitry Andric   if (!IndexExpr->isInstantiationDependent()) {
1104*0fca6ea1SDimitry Andric     llvm::APSInt Value(Context.getIntWidth(Context.getSizeType()));
1105*0fca6ea1SDimitry Andric 
1106*0fca6ea1SDimitry Andric     ExprResult Res = CheckConvertedConstantExpression(
1107*0fca6ea1SDimitry Andric         IndexExpr, Context.getSizeType(), Value, CCEK_ArrayBound);
1108*0fca6ea1SDimitry Andric     if (!Res.isUsable())
1109*0fca6ea1SDimitry Andric       return ExprError();
1110*0fca6ea1SDimitry Andric     Index = Value.getExtValue();
1111*0fca6ea1SDimitry Andric     IndexExpr = Res.get();
1112*0fca6ea1SDimitry Andric   }
1113*0fca6ea1SDimitry Andric 
1114*0fca6ea1SDimitry Andric   if (Index && (!ExpandedExprs.empty() || EmptyPack)) {
1115*0fca6ea1SDimitry Andric     if (*Index < 0 || EmptyPack || *Index >= int64_t(ExpandedExprs.size())) {
1116*0fca6ea1SDimitry Andric       Diag(PackExpression->getBeginLoc(), diag::err_pack_index_out_of_bound)
1117*0fca6ea1SDimitry Andric           << *Index << PackExpression << ExpandedExprs.size();
1118*0fca6ea1SDimitry Andric       return ExprError();
1119*0fca6ea1SDimitry Andric     }
1120*0fca6ea1SDimitry Andric   }
1121*0fca6ea1SDimitry Andric 
1122*0fca6ea1SDimitry Andric   return PackIndexingExpr::Create(getASTContext(), EllipsisLoc, RSquareLoc,
1123*0fca6ea1SDimitry Andric                                   PackExpression, IndexExpr, Index,
1124*0fca6ea1SDimitry Andric                                   ExpandedExprs, EmptyPack);
1125*0fca6ea1SDimitry Andric }
1126*0fca6ea1SDimitry Andric 
getTemplateArgumentPackExpansionPattern(TemplateArgumentLoc OrigLoc,SourceLocation & Ellipsis,std::optional<unsigned> & NumExpansions) const1127bdd1243dSDimitry Andric TemplateArgumentLoc Sema::getTemplateArgumentPackExpansionPattern(
1128bdd1243dSDimitry Andric     TemplateArgumentLoc OrigLoc, SourceLocation &Ellipsis,
1129bdd1243dSDimitry Andric     std::optional<unsigned> &NumExpansions) const {
11300b57cec5SDimitry Andric   const TemplateArgument &Argument = OrigLoc.getArgument();
11310b57cec5SDimitry Andric   assert(Argument.isPackExpansion());
11320b57cec5SDimitry Andric   switch (Argument.getKind()) {
11330b57cec5SDimitry Andric   case TemplateArgument::Type: {
11340b57cec5SDimitry Andric     // FIXME: We shouldn't ever have to worry about missing
11350b57cec5SDimitry Andric     // type-source info!
11360b57cec5SDimitry Andric     TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo();
11370b57cec5SDimitry Andric     if (!ExpansionTSInfo)
11380b57cec5SDimitry Andric       ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(),
11390b57cec5SDimitry Andric                                                          Ellipsis);
11400b57cec5SDimitry Andric     PackExpansionTypeLoc Expansion =
11410b57cec5SDimitry Andric         ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>();
11420b57cec5SDimitry Andric     Ellipsis = Expansion.getEllipsisLoc();
11430b57cec5SDimitry Andric 
11440b57cec5SDimitry Andric     TypeLoc Pattern = Expansion.getPatternLoc();
11450b57cec5SDimitry Andric     NumExpansions = Expansion.getTypePtr()->getNumExpansions();
11460b57cec5SDimitry Andric 
11470b57cec5SDimitry Andric     // We need to copy the TypeLoc because TemplateArgumentLocs store a
11480b57cec5SDimitry Andric     // TypeSourceInfo.
11490b57cec5SDimitry Andric     // FIXME: Find some way to avoid the copy?
11500b57cec5SDimitry Andric     TypeLocBuilder TLB;
11510b57cec5SDimitry Andric     TLB.pushFullCopy(Pattern);
11520b57cec5SDimitry Andric     TypeSourceInfo *PatternTSInfo =
11530b57cec5SDimitry Andric         TLB.getTypeSourceInfo(Context, Pattern.getType());
11540b57cec5SDimitry Andric     return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
11550b57cec5SDimitry Andric                                PatternTSInfo);
11560b57cec5SDimitry Andric   }
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric   case TemplateArgument::Expression: {
11590b57cec5SDimitry Andric     PackExpansionExpr *Expansion
11600b57cec5SDimitry Andric       = cast<PackExpansionExpr>(Argument.getAsExpr());
11610b57cec5SDimitry Andric     Expr *Pattern = Expansion->getPattern();
11620b57cec5SDimitry Andric     Ellipsis = Expansion->getEllipsisLoc();
11630b57cec5SDimitry Andric     NumExpansions = Expansion->getNumExpansions();
11640b57cec5SDimitry Andric     return TemplateArgumentLoc(Pattern, Pattern);
11650b57cec5SDimitry Andric   }
11660b57cec5SDimitry Andric 
11670b57cec5SDimitry Andric   case TemplateArgument::TemplateExpansion:
11680b57cec5SDimitry Andric     Ellipsis = OrigLoc.getTemplateEllipsisLoc();
11690b57cec5SDimitry Andric     NumExpansions = Argument.getNumTemplateExpansions();
1170e8d8bef9SDimitry Andric     return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(),
11710b57cec5SDimitry Andric                                OrigLoc.getTemplateQualifierLoc(),
11720b57cec5SDimitry Andric                                OrigLoc.getTemplateNameLoc());
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric   case TemplateArgument::Declaration:
11750b57cec5SDimitry Andric   case TemplateArgument::NullPtr:
11760b57cec5SDimitry Andric   case TemplateArgument::Template:
11770b57cec5SDimitry Andric   case TemplateArgument::Integral:
11787a6dacacSDimitry Andric   case TemplateArgument::StructuralValue:
11790b57cec5SDimitry Andric   case TemplateArgument::Pack:
11800b57cec5SDimitry Andric   case TemplateArgument::Null:
11810b57cec5SDimitry Andric     return TemplateArgumentLoc();
11820b57cec5SDimitry Andric   }
11830b57cec5SDimitry Andric 
11840b57cec5SDimitry Andric   llvm_unreachable("Invalid TemplateArgument Kind!");
11850b57cec5SDimitry Andric }
11860b57cec5SDimitry Andric 
getFullyPackExpandedSize(TemplateArgument Arg)1187bdd1243dSDimitry Andric std::optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
11880b57cec5SDimitry Andric   assert(Arg.containsUnexpandedParameterPack());
11890b57cec5SDimitry Andric 
11900b57cec5SDimitry Andric   // If this is a substituted pack, grab that pack. If not, we don't know
11910b57cec5SDimitry Andric   // the size yet.
11920b57cec5SDimitry Andric   // FIXME: We could find a size in more cases by looking for a substituted
11930b57cec5SDimitry Andric   // pack anywhere within this argument, but that's not necessary in the common
11940b57cec5SDimitry Andric   // case for 'sizeof...(A)' handling.
11950b57cec5SDimitry Andric   TemplateArgument Pack;
11960b57cec5SDimitry Andric   switch (Arg.getKind()) {
11970b57cec5SDimitry Andric   case TemplateArgument::Type:
11980b57cec5SDimitry Andric     if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>())
11990b57cec5SDimitry Andric       Pack = Subst->getArgumentPack();
12000b57cec5SDimitry Andric     else
1201bdd1243dSDimitry Andric       return std::nullopt;
12020b57cec5SDimitry Andric     break;
12030b57cec5SDimitry Andric 
12040b57cec5SDimitry Andric   case TemplateArgument::Expression:
12050b57cec5SDimitry Andric     if (auto *Subst =
12060b57cec5SDimitry Andric             dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
12070b57cec5SDimitry Andric       Pack = Subst->getArgumentPack();
12080b57cec5SDimitry Andric     else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr()))  {
12090b57cec5SDimitry Andric       for (VarDecl *PD : *Subst)
12100b57cec5SDimitry Andric         if (PD->isParameterPack())
1211bdd1243dSDimitry Andric           return std::nullopt;
12120b57cec5SDimitry Andric       return Subst->getNumExpansions();
12130b57cec5SDimitry Andric     } else
1214bdd1243dSDimitry Andric       return std::nullopt;
12150b57cec5SDimitry Andric     break;
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric   case TemplateArgument::Template:
12180b57cec5SDimitry Andric     if (SubstTemplateTemplateParmPackStorage *Subst =
12190b57cec5SDimitry Andric             Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack())
12200b57cec5SDimitry Andric       Pack = Subst->getArgumentPack();
12210b57cec5SDimitry Andric     else
1222bdd1243dSDimitry Andric       return std::nullopt;
12230b57cec5SDimitry Andric     break;
12240b57cec5SDimitry Andric 
12250b57cec5SDimitry Andric   case TemplateArgument::Declaration:
12260b57cec5SDimitry Andric   case TemplateArgument::NullPtr:
12270b57cec5SDimitry Andric   case TemplateArgument::TemplateExpansion:
12280b57cec5SDimitry Andric   case TemplateArgument::Integral:
12297a6dacacSDimitry Andric   case TemplateArgument::StructuralValue:
12300b57cec5SDimitry Andric   case TemplateArgument::Pack:
12310b57cec5SDimitry Andric   case TemplateArgument::Null:
1232bdd1243dSDimitry Andric     return std::nullopt;
12330b57cec5SDimitry Andric   }
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric   // Check that no argument in the pack is itself a pack expansion.
12360b57cec5SDimitry Andric   for (TemplateArgument Elem : Pack.pack_elements()) {
12370b57cec5SDimitry Andric     // There's no point recursing in this case; we would have already
12380b57cec5SDimitry Andric     // expanded this pack expansion into the enclosing pack if we could.
12390b57cec5SDimitry Andric     if (Elem.isPackExpansion())
1240bdd1243dSDimitry Andric       return std::nullopt;
1241*0fca6ea1SDimitry Andric     // Don't guess the size of unexpanded packs. The pack within a template
1242*0fca6ea1SDimitry Andric     // argument may have yet to be of a PackExpansion type before we see the
1243*0fca6ea1SDimitry Andric     // ellipsis in the annotation stage.
1244*0fca6ea1SDimitry Andric     //
1245*0fca6ea1SDimitry Andric     // This doesn't mean we would invalidate the optimization: Arg can be an
1246*0fca6ea1SDimitry Andric     // unexpanded pack regardless of Elem's dependence. For instance,
1247*0fca6ea1SDimitry Andric     // A TemplateArgument that contains either a SubstTemplateTypeParmPackType
1248*0fca6ea1SDimitry Andric     // or SubstNonTypeTemplateParmPackExpr is always considered Unexpanded, but
1249*0fca6ea1SDimitry Andric     // the underlying TemplateArgument thereof may not.
1250*0fca6ea1SDimitry Andric     if (Elem.containsUnexpandedParameterPack())
1251*0fca6ea1SDimitry Andric       return std::nullopt;
12520b57cec5SDimitry Andric   }
12530b57cec5SDimitry Andric   return Pack.pack_size();
12540b57cec5SDimitry Andric }
12550b57cec5SDimitry Andric 
CheckFoldOperand(Sema & S,Expr * E)12560b57cec5SDimitry Andric static void CheckFoldOperand(Sema &S, Expr *E) {
12570b57cec5SDimitry Andric   if (!E)
12580b57cec5SDimitry Andric     return;
12590b57cec5SDimitry Andric 
12600b57cec5SDimitry Andric   E = E->IgnoreImpCasts();
12610b57cec5SDimitry Andric   auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
12620b57cec5SDimitry Andric   if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) ||
12630b57cec5SDimitry Andric       isa<AbstractConditionalOperator>(E)) {
12640b57cec5SDimitry Andric     S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand)
12650b57cec5SDimitry Andric         << E->getSourceRange()
12660b57cec5SDimitry Andric         << FixItHint::CreateInsertion(E->getBeginLoc(), "(")
12670b57cec5SDimitry Andric         << FixItHint::CreateInsertion(E->getEndLoc(), ")");
12680b57cec5SDimitry Andric   }
12690b57cec5SDimitry Andric }
12700b57cec5SDimitry Andric 
ActOnCXXFoldExpr(Scope * S,SourceLocation LParenLoc,Expr * LHS,tok::TokenKind Operator,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc)1271e8d8bef9SDimitry Andric ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS,
12720b57cec5SDimitry Andric                                   tok::TokenKind Operator,
12730b57cec5SDimitry Andric                                   SourceLocation EllipsisLoc, Expr *RHS,
12740b57cec5SDimitry Andric                                   SourceLocation RParenLoc) {
12750b57cec5SDimitry Andric   // LHS and RHS must be cast-expressions. We allow an arbitrary expression
12760b57cec5SDimitry Andric   // in the parser and reduce down to just cast-expressions here.
12770b57cec5SDimitry Andric   CheckFoldOperand(*this, LHS);
12780b57cec5SDimitry Andric   CheckFoldOperand(*this, RHS);
12790b57cec5SDimitry Andric 
12800b57cec5SDimitry Andric   auto DiscardOperands = [&] {
12810b57cec5SDimitry Andric     CorrectDelayedTyposInExpr(LHS);
12820b57cec5SDimitry Andric     CorrectDelayedTyposInExpr(RHS);
12830b57cec5SDimitry Andric   };
12840b57cec5SDimitry Andric 
12850b57cec5SDimitry Andric   // [expr.prim.fold]p3:
12860b57cec5SDimitry Andric   //   In a binary fold, op1 and op2 shall be the same fold-operator, and
12870b57cec5SDimitry Andric   //   either e1 shall contain an unexpanded parameter pack or e2 shall contain
12880b57cec5SDimitry Andric   //   an unexpanded parameter pack, but not both.
12890b57cec5SDimitry Andric   if (LHS && RHS &&
12900b57cec5SDimitry Andric       LHS->containsUnexpandedParameterPack() ==
12910b57cec5SDimitry Andric           RHS->containsUnexpandedParameterPack()) {
12920b57cec5SDimitry Andric     DiscardOperands();
12930b57cec5SDimitry Andric     return Diag(EllipsisLoc,
12940b57cec5SDimitry Andric                 LHS->containsUnexpandedParameterPack()
12950b57cec5SDimitry Andric                     ? diag::err_fold_expression_packs_both_sides
12960b57cec5SDimitry Andric                     : diag::err_pack_expansion_without_parameter_packs)
12970b57cec5SDimitry Andric         << LHS->getSourceRange() << RHS->getSourceRange();
12980b57cec5SDimitry Andric   }
12990b57cec5SDimitry Andric 
13000b57cec5SDimitry Andric   // [expr.prim.fold]p2:
13010b57cec5SDimitry Andric   //   In a unary fold, the cast-expression shall contain an unexpanded
13020b57cec5SDimitry Andric   //   parameter pack.
13030b57cec5SDimitry Andric   if (!LHS || !RHS) {
13040b57cec5SDimitry Andric     Expr *Pack = LHS ? LHS : RHS;
13050b57cec5SDimitry Andric     assert(Pack && "fold expression with neither LHS nor RHS");
130606c3fb27SDimitry Andric     if (!Pack->containsUnexpandedParameterPack()) {
13070b57cec5SDimitry Andric       DiscardOperands();
13080b57cec5SDimitry Andric       return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
13090b57cec5SDimitry Andric              << Pack->getSourceRange();
13100b57cec5SDimitry Andric     }
131106c3fb27SDimitry Andric   }
13120b57cec5SDimitry Andric 
13130b57cec5SDimitry Andric   BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator);
1314e8d8bef9SDimitry Andric 
1315e8d8bef9SDimitry Andric   // Perform first-phase name lookup now.
1316e8d8bef9SDimitry Andric   UnresolvedLookupExpr *ULE = nullptr;
1317e8d8bef9SDimitry Andric   {
1318e8d8bef9SDimitry Andric     UnresolvedSet<16> Functions;
1319e8d8bef9SDimitry Andric     LookupBinOp(S, EllipsisLoc, Opc, Functions);
1320e8d8bef9SDimitry Andric     if (!Functions.empty()) {
1321e8d8bef9SDimitry Andric       DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(
1322e8d8bef9SDimitry Andric           BinaryOperator::getOverloadedOperator(Opc));
1323e8d8bef9SDimitry Andric       ExprResult Callee = CreateUnresolvedLookupExpr(
1324e8d8bef9SDimitry Andric           /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
1325e8d8bef9SDimitry Andric           DeclarationNameInfo(OpName, EllipsisLoc), Functions);
1326e8d8bef9SDimitry Andric       if (Callee.isInvalid())
1327e8d8bef9SDimitry Andric         return ExprError();
1328e8d8bef9SDimitry Andric       ULE = cast<UnresolvedLookupExpr>(Callee.get());
1329e8d8bef9SDimitry Andric     }
1330e8d8bef9SDimitry Andric   }
1331e8d8bef9SDimitry Andric 
1332e8d8bef9SDimitry Andric   return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc,
1333bdd1243dSDimitry Andric                           std::nullopt);
13340b57cec5SDimitry Andric }
13350b57cec5SDimitry Andric 
BuildCXXFoldExpr(UnresolvedLookupExpr * Callee,SourceLocation LParenLoc,Expr * LHS,BinaryOperatorKind Operator,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc,std::optional<unsigned> NumExpansions)1336e8d8bef9SDimitry Andric ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee,
1337e8d8bef9SDimitry Andric                                   SourceLocation LParenLoc, Expr *LHS,
13380b57cec5SDimitry Andric                                   BinaryOperatorKind Operator,
13390b57cec5SDimitry Andric                                   SourceLocation EllipsisLoc, Expr *RHS,
13400b57cec5SDimitry Andric                                   SourceLocation RParenLoc,
1341bdd1243dSDimitry Andric                                   std::optional<unsigned> NumExpansions) {
1342e8d8bef9SDimitry Andric   return new (Context)
1343e8d8bef9SDimitry Andric       CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator,
1344e8d8bef9SDimitry Andric                   EllipsisLoc, RHS, RParenLoc, NumExpansions);
13450b57cec5SDimitry Andric }
13460b57cec5SDimitry Andric 
BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,BinaryOperatorKind Operator)13470b57cec5SDimitry Andric ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
13480b57cec5SDimitry Andric                                        BinaryOperatorKind Operator) {
13490b57cec5SDimitry Andric   // [temp.variadic]p9:
13500b57cec5SDimitry Andric   //   If N is zero for a unary fold-expression, the value of the expression is
13510b57cec5SDimitry Andric   //       &&  ->  true
13520b57cec5SDimitry Andric   //       ||  ->  false
13530b57cec5SDimitry Andric   //       ,   ->  void()
13540b57cec5SDimitry Andric   //   if the operator is not listed [above], the instantiation is ill-formed.
13550b57cec5SDimitry Andric   //
13560b57cec5SDimitry Andric   // Note that we need to use something like int() here, not merely 0, to
13570b57cec5SDimitry Andric   // prevent the result from being a null pointer constant.
13580b57cec5SDimitry Andric   QualType ScalarType;
13590b57cec5SDimitry Andric   switch (Operator) {
13600b57cec5SDimitry Andric   case BO_LOr:
13610b57cec5SDimitry Andric     return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false);
13620b57cec5SDimitry Andric   case BO_LAnd:
13630b57cec5SDimitry Andric     return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true);
13640b57cec5SDimitry Andric   case BO_Comma:
13650b57cec5SDimitry Andric     ScalarType = Context.VoidTy;
13660b57cec5SDimitry Andric     break;
13670b57cec5SDimitry Andric 
13680b57cec5SDimitry Andric   default:
13690b57cec5SDimitry Andric     return Diag(EllipsisLoc, diag::err_fold_expression_empty)
13700b57cec5SDimitry Andric         << BinaryOperator::getOpcodeStr(Operator);
13710b57cec5SDimitry Andric   }
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric   return new (Context) CXXScalarValueInitExpr(
13740b57cec5SDimitry Andric       ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc),
13750b57cec5SDimitry Andric       EllipsisLoc);
13760b57cec5SDimitry Andric }
1377