xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/Sema/SemaTemplateVariadic.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //===----------------------------------------------------------------------===/
77330f729Sjoerg //
87330f729Sjoerg //  This file implements semantic analysis for C++0x variadic templates.
97330f729Sjoerg //===----------------------------------------------------------------------===/
107330f729Sjoerg 
117330f729Sjoerg #include "clang/Sema/Sema.h"
127330f729Sjoerg #include "TypeLocBuilder.h"
137330f729Sjoerg #include "clang/AST/Expr.h"
147330f729Sjoerg #include "clang/AST/RecursiveASTVisitor.h"
157330f729Sjoerg #include "clang/AST/TypeLoc.h"
167330f729Sjoerg #include "clang/Sema/Lookup.h"
177330f729Sjoerg #include "clang/Sema/ParsedTemplate.h"
187330f729Sjoerg #include "clang/Sema/ScopeInfo.h"
197330f729Sjoerg #include "clang/Sema/SemaInternal.h"
207330f729Sjoerg #include "clang/Sema/Template.h"
217330f729Sjoerg 
227330f729Sjoerg using namespace clang;
237330f729Sjoerg 
247330f729Sjoerg //----------------------------------------------------------------------------
257330f729Sjoerg // Visitor that collects unexpanded parameter packs
267330f729Sjoerg //----------------------------------------------------------------------------
277330f729Sjoerg 
287330f729Sjoerg namespace {
297330f729Sjoerg   /// A class that collects unexpanded parameter packs.
307330f729Sjoerg   class CollectUnexpandedParameterPacksVisitor :
317330f729Sjoerg     public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
327330f729Sjoerg   {
337330f729Sjoerg     typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
347330f729Sjoerg       inherited;
357330f729Sjoerg 
367330f729Sjoerg     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
377330f729Sjoerg 
387330f729Sjoerg     bool InLambda = false;
397330f729Sjoerg     unsigned DepthLimit = (unsigned)-1;
407330f729Sjoerg 
addUnexpanded(NamedDecl * ND,SourceLocation Loc=SourceLocation ())417330f729Sjoerg     void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
427330f729Sjoerg       if (auto *VD = dyn_cast<VarDecl>(ND)) {
437330f729Sjoerg         // For now, the only problematic case is a generic lambda's templated
447330f729Sjoerg         // call operator, so we don't need to look for all the other ways we
457330f729Sjoerg         // could have reached a dependent parameter pack.
467330f729Sjoerg         auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext());
477330f729Sjoerg         auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;
487330f729Sjoerg         if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)
497330f729Sjoerg           return;
507330f729Sjoerg       } else if (getDepthAndIndex(ND).first >= DepthLimit)
517330f729Sjoerg         return;
527330f729Sjoerg 
537330f729Sjoerg       Unexpanded.push_back({ND, Loc});
547330f729Sjoerg     }
addUnexpanded(const TemplateTypeParmType * T,SourceLocation Loc=SourceLocation ())557330f729Sjoerg     void addUnexpanded(const TemplateTypeParmType *T,
567330f729Sjoerg                        SourceLocation Loc = SourceLocation()) {
577330f729Sjoerg       if (T->getDepth() < DepthLimit)
587330f729Sjoerg         Unexpanded.push_back({T, Loc});
597330f729Sjoerg     }
607330f729Sjoerg 
617330f729Sjoerg   public:
CollectUnexpandedParameterPacksVisitor(SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)627330f729Sjoerg     explicit CollectUnexpandedParameterPacksVisitor(
637330f729Sjoerg         SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
647330f729Sjoerg         : Unexpanded(Unexpanded) {}
657330f729Sjoerg 
shouldWalkTypesOfTypeLocs() const667330f729Sjoerg     bool shouldWalkTypesOfTypeLocs() const { return false; }
677330f729Sjoerg 
687330f729Sjoerg     //------------------------------------------------------------------------
697330f729Sjoerg     // Recording occurrences of (unexpanded) parameter packs.
707330f729Sjoerg     //------------------------------------------------------------------------
717330f729Sjoerg 
727330f729Sjoerg     /// Record occurrences of template type parameter packs.
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)737330f729Sjoerg     bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
747330f729Sjoerg       if (TL.getTypePtr()->isParameterPack())
757330f729Sjoerg         addUnexpanded(TL.getTypePtr(), TL.getNameLoc());
767330f729Sjoerg       return true;
777330f729Sjoerg     }
787330f729Sjoerg 
797330f729Sjoerg     /// Record occurrences of template type parameter packs
807330f729Sjoerg     /// when we don't have proper source-location information for
817330f729Sjoerg     /// them.
827330f729Sjoerg     ///
837330f729Sjoerg     /// Ideally, this routine would never be used.
VisitTemplateTypeParmType(TemplateTypeParmType * T)847330f729Sjoerg     bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
857330f729Sjoerg       if (T->isParameterPack())
867330f729Sjoerg         addUnexpanded(T);
877330f729Sjoerg 
887330f729Sjoerg       return true;
897330f729Sjoerg     }
907330f729Sjoerg 
917330f729Sjoerg     /// Record occurrences of function and non-type template
927330f729Sjoerg     /// parameter packs in an expression.
VisitDeclRefExpr(DeclRefExpr * E)937330f729Sjoerg     bool VisitDeclRefExpr(DeclRefExpr *E) {
947330f729Sjoerg       if (E->getDecl()->isParameterPack())
957330f729Sjoerg         addUnexpanded(E->getDecl(), E->getLocation());
967330f729Sjoerg 
977330f729Sjoerg       return true;
987330f729Sjoerg     }
997330f729Sjoerg 
1007330f729Sjoerg     /// Record occurrences of template template parameter packs.
TraverseTemplateName(TemplateName Template)1017330f729Sjoerg     bool TraverseTemplateName(TemplateName Template) {
1027330f729Sjoerg       if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
1037330f729Sjoerg               Template.getAsTemplateDecl())) {
1047330f729Sjoerg         if (TTP->isParameterPack())
1057330f729Sjoerg           addUnexpanded(TTP);
1067330f729Sjoerg       }
1077330f729Sjoerg 
1087330f729Sjoerg       return inherited::TraverseTemplateName(Template);
1097330f729Sjoerg     }
1107330f729Sjoerg 
1117330f729Sjoerg     /// Suppress traversal into Objective-C container literal
1127330f729Sjoerg     /// elements that are pack expansions.
TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral * E)1137330f729Sjoerg     bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1147330f729Sjoerg       if (!E->containsUnexpandedParameterPack())
1157330f729Sjoerg         return true;
1167330f729Sjoerg 
1177330f729Sjoerg       for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
1187330f729Sjoerg         ObjCDictionaryElement Element = E->getKeyValueElement(I);
1197330f729Sjoerg         if (Element.isPackExpansion())
1207330f729Sjoerg           continue;
1217330f729Sjoerg 
1227330f729Sjoerg         TraverseStmt(Element.Key);
1237330f729Sjoerg         TraverseStmt(Element.Value);
1247330f729Sjoerg       }
1257330f729Sjoerg       return true;
1267330f729Sjoerg     }
1277330f729Sjoerg     //------------------------------------------------------------------------
1287330f729Sjoerg     // Pruning the search for unexpanded parameter packs.
1297330f729Sjoerg     //------------------------------------------------------------------------
1307330f729Sjoerg 
1317330f729Sjoerg     /// Suppress traversal into statements and expressions that
1327330f729Sjoerg     /// do not contain unexpanded parameter packs.
TraverseStmt(Stmt * S)1337330f729Sjoerg     bool TraverseStmt(Stmt *S) {
1347330f729Sjoerg       Expr *E = dyn_cast_or_null<Expr>(S);
1357330f729Sjoerg       if ((E && E->containsUnexpandedParameterPack()) || InLambda)
1367330f729Sjoerg         return inherited::TraverseStmt(S);
1377330f729Sjoerg 
1387330f729Sjoerg       return true;
1397330f729Sjoerg     }
1407330f729Sjoerg 
1417330f729Sjoerg     /// Suppress traversal into types that do not contain
1427330f729Sjoerg     /// unexpanded parameter packs.
TraverseType(QualType T)1437330f729Sjoerg     bool TraverseType(QualType T) {
1447330f729Sjoerg       if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
1457330f729Sjoerg         return inherited::TraverseType(T);
1467330f729Sjoerg 
1477330f729Sjoerg       return true;
1487330f729Sjoerg     }
1497330f729Sjoerg 
1507330f729Sjoerg     /// Suppress traversal into types with location information
1517330f729Sjoerg     /// that do not contain unexpanded parameter packs.
TraverseTypeLoc(TypeLoc TL)1527330f729Sjoerg     bool TraverseTypeLoc(TypeLoc TL) {
1537330f729Sjoerg       if ((!TL.getType().isNull() &&
1547330f729Sjoerg            TL.getType()->containsUnexpandedParameterPack()) ||
1557330f729Sjoerg           InLambda)
1567330f729Sjoerg         return inherited::TraverseTypeLoc(TL);
1577330f729Sjoerg 
1587330f729Sjoerg       return true;
1597330f729Sjoerg     }
1607330f729Sjoerg 
1617330f729Sjoerg     /// Suppress traversal of parameter packs.
TraverseDecl(Decl * D)1627330f729Sjoerg     bool TraverseDecl(Decl *D) {
1637330f729Sjoerg       // A function parameter pack is a pack expansion, so cannot contain
1647330f729Sjoerg       // an unexpanded parameter pack. Likewise for a template parameter
1657330f729Sjoerg       // pack that contains any references to other packs.
1667330f729Sjoerg       if (D && D->isParameterPack())
1677330f729Sjoerg         return true;
1687330f729Sjoerg 
1697330f729Sjoerg       return inherited::TraverseDecl(D);
1707330f729Sjoerg     }
1717330f729Sjoerg 
1727330f729Sjoerg     /// Suppress traversal of pack-expanded attributes.
TraverseAttr(Attr * A)1737330f729Sjoerg     bool TraverseAttr(Attr *A) {
1747330f729Sjoerg       if (A->isPackExpansion())
1757330f729Sjoerg         return true;
1767330f729Sjoerg 
1777330f729Sjoerg       return inherited::TraverseAttr(A);
1787330f729Sjoerg     }
1797330f729Sjoerg 
1807330f729Sjoerg     /// Suppress traversal of pack expansion expressions and types.
1817330f729Sjoerg     ///@{
TraversePackExpansionType(PackExpansionType * T)1827330f729Sjoerg     bool TraversePackExpansionType(PackExpansionType *T) { return true; }
TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL)1837330f729Sjoerg     bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; }
TraversePackExpansionExpr(PackExpansionExpr * E)1847330f729Sjoerg     bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; }
TraverseCXXFoldExpr(CXXFoldExpr * E)1857330f729Sjoerg     bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; }
1867330f729Sjoerg 
1877330f729Sjoerg     ///@}
1887330f729Sjoerg 
1897330f729Sjoerg     /// Suppress traversal of using-declaration pack expansion.
TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)1907330f729Sjoerg     bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1917330f729Sjoerg       if (D->isPackExpansion())
1927330f729Sjoerg         return true;
1937330f729Sjoerg 
1947330f729Sjoerg       return inherited::TraverseUnresolvedUsingValueDecl(D);
1957330f729Sjoerg     }
1967330f729Sjoerg 
1977330f729Sjoerg     /// Suppress traversal of using-declaration pack expansion.
TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1987330f729Sjoerg     bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
1997330f729Sjoerg       if (D->isPackExpansion())
2007330f729Sjoerg         return true;
2017330f729Sjoerg 
2027330f729Sjoerg       return inherited::TraverseUnresolvedUsingTypenameDecl(D);
2037330f729Sjoerg     }
2047330f729Sjoerg 
2057330f729Sjoerg     /// Suppress traversal of template argument pack expansions.
TraverseTemplateArgument(const TemplateArgument & Arg)2067330f729Sjoerg     bool TraverseTemplateArgument(const TemplateArgument &Arg) {
2077330f729Sjoerg       if (Arg.isPackExpansion())
2087330f729Sjoerg         return true;
2097330f729Sjoerg 
2107330f729Sjoerg       return inherited::TraverseTemplateArgument(Arg);
2117330f729Sjoerg     }
2127330f729Sjoerg 
2137330f729Sjoerg     /// Suppress traversal of template argument pack expansions.
TraverseTemplateArgumentLoc(const TemplateArgumentLoc & ArgLoc)2147330f729Sjoerg     bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
2157330f729Sjoerg       if (ArgLoc.getArgument().isPackExpansion())
2167330f729Sjoerg         return true;
2177330f729Sjoerg 
2187330f729Sjoerg       return inherited::TraverseTemplateArgumentLoc(ArgLoc);
2197330f729Sjoerg     }
2207330f729Sjoerg 
2217330f729Sjoerg     /// Suppress traversal of base specifier pack expansions.
TraverseCXXBaseSpecifier(const CXXBaseSpecifier & Base)2227330f729Sjoerg     bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
2237330f729Sjoerg       if (Base.isPackExpansion())
2247330f729Sjoerg         return true;
2257330f729Sjoerg 
2267330f729Sjoerg       return inherited::TraverseCXXBaseSpecifier(Base);
2277330f729Sjoerg     }
2287330f729Sjoerg 
2297330f729Sjoerg     /// Suppress traversal of mem-initializer pack expansions.
TraverseConstructorInitializer(CXXCtorInitializer * Init)2307330f729Sjoerg     bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
2317330f729Sjoerg       if (Init->isPackExpansion())
2327330f729Sjoerg         return true;
2337330f729Sjoerg 
2347330f729Sjoerg       return inherited::TraverseConstructorInitializer(Init);
2357330f729Sjoerg     }
2367330f729Sjoerg 
2377330f729Sjoerg     /// Note whether we're traversing a lambda containing an unexpanded
2387330f729Sjoerg     /// parameter pack. In this case, the unexpanded pack can occur anywhere,
2397330f729Sjoerg     /// including all the places where we normally wouldn't look. Within a
2407330f729Sjoerg     /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
2417330f729Sjoerg     /// outside an expression.
TraverseLambdaExpr(LambdaExpr * Lambda)2427330f729Sjoerg     bool TraverseLambdaExpr(LambdaExpr *Lambda) {
2437330f729Sjoerg       // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
2447330f729Sjoerg       // even if it's contained within another lambda.
2457330f729Sjoerg       if (!Lambda->containsUnexpandedParameterPack())
2467330f729Sjoerg         return true;
2477330f729Sjoerg 
2487330f729Sjoerg       bool WasInLambda = InLambda;
2497330f729Sjoerg       unsigned OldDepthLimit = DepthLimit;
2507330f729Sjoerg 
2517330f729Sjoerg       InLambda = true;
2527330f729Sjoerg       if (auto *TPL = Lambda->getTemplateParameterList())
2537330f729Sjoerg         DepthLimit = TPL->getDepth();
2547330f729Sjoerg 
2557330f729Sjoerg       inherited::TraverseLambdaExpr(Lambda);
2567330f729Sjoerg 
2577330f729Sjoerg       InLambda = WasInLambda;
2587330f729Sjoerg       DepthLimit = OldDepthLimit;
2597330f729Sjoerg       return true;
2607330f729Sjoerg     }
2617330f729Sjoerg 
2627330f729Sjoerg     /// Suppress traversal within pack expansions in lambda captures.
TraverseLambdaCapture(LambdaExpr * Lambda,const LambdaCapture * C,Expr * Init)2637330f729Sjoerg     bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C,
2647330f729Sjoerg                                Expr *Init) {
2657330f729Sjoerg       if (C->isPackExpansion())
2667330f729Sjoerg         return true;
2677330f729Sjoerg 
2687330f729Sjoerg       return inherited::TraverseLambdaCapture(Lambda, C, Init);
2697330f729Sjoerg     }
2707330f729Sjoerg   };
2717330f729Sjoerg }
2727330f729Sjoerg 
2737330f729Sjoerg /// Determine whether it's possible for an unexpanded parameter pack to
2747330f729Sjoerg /// be valid in this location. This only happens when we're in a declaration
2757330f729Sjoerg /// that is nested within an expression that could be expanded, such as a
2767330f729Sjoerg /// lambda-expression within a function call.
2777330f729Sjoerg ///
2787330f729Sjoerg /// This is conservatively correct, but may claim that some unexpanded packs are
2797330f729Sjoerg /// permitted when they are not.
isUnexpandedParameterPackPermitted()2807330f729Sjoerg bool Sema::isUnexpandedParameterPackPermitted() {
2817330f729Sjoerg   for (auto *SI : FunctionScopes)
2827330f729Sjoerg     if (isa<sema::LambdaScopeInfo>(SI))
2837330f729Sjoerg       return true;
2847330f729Sjoerg   return false;
2857330f729Sjoerg }
2867330f729Sjoerg 
2877330f729Sjoerg /// Diagnose all of the unexpanded parameter packs in the given
2887330f729Sjoerg /// vector.
2897330f729Sjoerg bool
DiagnoseUnexpandedParameterPacks(SourceLocation Loc,UnexpandedParameterPackContext UPPC,ArrayRef<UnexpandedParameterPack> Unexpanded)2907330f729Sjoerg Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
2917330f729Sjoerg                                        UnexpandedParameterPackContext UPPC,
2927330f729Sjoerg                                  ArrayRef<UnexpandedParameterPack> Unexpanded) {
2937330f729Sjoerg   if (Unexpanded.empty())
2947330f729Sjoerg     return false;
2957330f729Sjoerg 
2967330f729Sjoerg   // If we are within a lambda expression and referencing a pack that is not
2977330f729Sjoerg   // declared within the lambda itself, that lambda contains an unexpanded
2987330f729Sjoerg   // parameter pack, and we are done.
2997330f729Sjoerg   // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
3007330f729Sjoerg   // later.
3017330f729Sjoerg   SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences;
3027330f729Sjoerg   if (auto *LSI = getEnclosingLambda()) {
3037330f729Sjoerg     for (auto &Pack : Unexpanded) {
3047330f729Sjoerg       auto DeclaresThisPack = [&](NamedDecl *LocalPack) {
3057330f729Sjoerg         if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) {
3067330f729Sjoerg           auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack);
3077330f729Sjoerg           return TTPD && TTPD->getTypeForDecl() == TTPT;
3087330f729Sjoerg         }
3097330f729Sjoerg         return declaresSameEntity(Pack.first.get<NamedDecl *>(), LocalPack);
3107330f729Sjoerg       };
3117330f729Sjoerg       if (std::find_if(LSI->LocalPacks.begin(), LSI->LocalPacks.end(),
3127330f729Sjoerg                        DeclaresThisPack) != LSI->LocalPacks.end())
3137330f729Sjoerg         LambdaParamPackReferences.push_back(Pack);
3147330f729Sjoerg     }
3157330f729Sjoerg 
3167330f729Sjoerg     if (LambdaParamPackReferences.empty()) {
3177330f729Sjoerg       // Construct in lambda only references packs declared outside the lambda.
3187330f729Sjoerg       // That's OK for now, but the lambda itself is considered to contain an
3197330f729Sjoerg       // unexpanded pack in this case, which will require expansion outside the
3207330f729Sjoerg       // lambda.
3217330f729Sjoerg 
3227330f729Sjoerg       // We do not permit pack expansion that would duplicate a statement
3237330f729Sjoerg       // expression, not even within a lambda.
3247330f729Sjoerg       // FIXME: We could probably support this for statement expressions that
3257330f729Sjoerg       // do not contain labels.
3267330f729Sjoerg       // FIXME: This is insufficient to detect this problem; consider
3277330f729Sjoerg       //   f( ({ bad: 0; }) + pack ... );
3287330f729Sjoerg       bool EnclosingStmtExpr = false;
3297330f729Sjoerg       for (unsigned N = FunctionScopes.size(); N; --N) {
3307330f729Sjoerg         sema::FunctionScopeInfo *Func = FunctionScopes[N-1];
3317330f729Sjoerg         if (std::any_of(
3327330f729Sjoerg                 Func->CompoundScopes.begin(), Func->CompoundScopes.end(),
3337330f729Sjoerg                 [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) {
3347330f729Sjoerg           EnclosingStmtExpr = true;
3357330f729Sjoerg           break;
3367330f729Sjoerg         }
3377330f729Sjoerg         // Coumpound-statements outside the lambda are OK for now; we'll check
3387330f729Sjoerg         // for those when we finish handling the lambda.
3397330f729Sjoerg         if (Func == LSI)
3407330f729Sjoerg           break;
3417330f729Sjoerg       }
3427330f729Sjoerg 
3437330f729Sjoerg       if (!EnclosingStmtExpr) {
3447330f729Sjoerg         LSI->ContainsUnexpandedParameterPack = true;
3457330f729Sjoerg         return false;
3467330f729Sjoerg       }
3477330f729Sjoerg     } else {
3487330f729Sjoerg       Unexpanded = LambdaParamPackReferences;
3497330f729Sjoerg     }
3507330f729Sjoerg   }
3517330f729Sjoerg 
3527330f729Sjoerg   SmallVector<SourceLocation, 4> Locations;
3537330f729Sjoerg   SmallVector<IdentifierInfo *, 4> Names;
3547330f729Sjoerg   llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
3557330f729Sjoerg 
3567330f729Sjoerg   for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
3577330f729Sjoerg     IdentifierInfo *Name = nullptr;
3587330f729Sjoerg     if (const TemplateTypeParmType *TTP
3597330f729Sjoerg           = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
3607330f729Sjoerg       Name = TTP->getIdentifier();
3617330f729Sjoerg     else
3627330f729Sjoerg       Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
3637330f729Sjoerg 
3647330f729Sjoerg     if (Name && NamesKnown.insert(Name).second)
3657330f729Sjoerg       Names.push_back(Name);
3667330f729Sjoerg 
3677330f729Sjoerg     if (Unexpanded[I].second.isValid())
3687330f729Sjoerg       Locations.push_back(Unexpanded[I].second);
3697330f729Sjoerg   }
3707330f729Sjoerg 
371*e038c9c4Sjoerg   auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
3727330f729Sjoerg             << (int)UPPC << (int)Names.size();
3737330f729Sjoerg   for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)
3747330f729Sjoerg     DB << Names[I];
3757330f729Sjoerg 
3767330f729Sjoerg   for (unsigned I = 0, N = Locations.size(); I != N; ++I)
3777330f729Sjoerg     DB << SourceRange(Locations[I]);
3787330f729Sjoerg   return true;
3797330f729Sjoerg }
3807330f729Sjoerg 
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TypeSourceInfo * T,UnexpandedParameterPackContext UPPC)3817330f729Sjoerg bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
3827330f729Sjoerg                                            TypeSourceInfo *T,
3837330f729Sjoerg                                          UnexpandedParameterPackContext UPPC) {
3847330f729Sjoerg   // C++0x [temp.variadic]p5:
3857330f729Sjoerg   //   An appearance of a name of a parameter pack that is not expanded is
3867330f729Sjoerg   //   ill-formed.
3877330f729Sjoerg   if (!T->getType()->containsUnexpandedParameterPack())
3887330f729Sjoerg     return false;
3897330f729Sjoerg 
3907330f729Sjoerg   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
3917330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
3927330f729Sjoerg                                                               T->getTypeLoc());
3937330f729Sjoerg   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
3947330f729Sjoerg   return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
3957330f729Sjoerg }
3967330f729Sjoerg 
DiagnoseUnexpandedParameterPack(Expr * E,UnexpandedParameterPackContext UPPC)3977330f729Sjoerg bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
3987330f729Sjoerg                                         UnexpandedParameterPackContext UPPC) {
3997330f729Sjoerg   // C++0x [temp.variadic]p5:
4007330f729Sjoerg   //   An appearance of a name of a parameter pack that is not expanded is
4017330f729Sjoerg   //   ill-formed.
4027330f729Sjoerg   if (!E->containsUnexpandedParameterPack())
4037330f729Sjoerg     return false;
4047330f729Sjoerg 
4057330f729Sjoerg   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4067330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
4077330f729Sjoerg   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4087330f729Sjoerg   return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
4097330f729Sjoerg }
4107330f729Sjoerg 
DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr * RE)411*e038c9c4Sjoerg bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
412*e038c9c4Sjoerg   if (!RE->containsUnexpandedParameterPack())
413*e038c9c4Sjoerg     return false;
414*e038c9c4Sjoerg 
415*e038c9c4Sjoerg   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
416*e038c9c4Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE);
417*e038c9c4Sjoerg   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
418*e038c9c4Sjoerg 
419*e038c9c4Sjoerg   // We only care about unexpanded references to the RequiresExpr's own
420*e038c9c4Sjoerg   // parameter packs.
421*e038c9c4Sjoerg   auto Parms = RE->getLocalParameters();
422*e038c9c4Sjoerg   llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
423*e038c9c4Sjoerg   SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
424*e038c9c4Sjoerg   for (auto Parm : Unexpanded)
425*e038c9c4Sjoerg     if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl*>()))
426*e038c9c4Sjoerg       UnexpandedParms.push_back(Parm);
427*e038c9c4Sjoerg   if (UnexpandedParms.empty())
428*e038c9c4Sjoerg     return false;
429*e038c9c4Sjoerg 
430*e038c9c4Sjoerg   return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement,
431*e038c9c4Sjoerg                                           UnexpandedParms);
432*e038c9c4Sjoerg }
433*e038c9c4Sjoerg 
DiagnoseUnexpandedParameterPack(const CXXScopeSpec & SS,UnexpandedParameterPackContext UPPC)4347330f729Sjoerg bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
4357330f729Sjoerg                                         UnexpandedParameterPackContext UPPC) {
4367330f729Sjoerg   // C++0x [temp.variadic]p5:
4377330f729Sjoerg   //   An appearance of a name of a parameter pack that is not expanded is
4387330f729Sjoerg   //   ill-formed.
4397330f729Sjoerg   if (!SS.getScopeRep() ||
4407330f729Sjoerg       !SS.getScopeRep()->containsUnexpandedParameterPack())
4417330f729Sjoerg     return false;
4427330f729Sjoerg 
4437330f729Sjoerg   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4447330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded)
4457330f729Sjoerg     .TraverseNestedNameSpecifier(SS.getScopeRep());
4467330f729Sjoerg   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4477330f729Sjoerg   return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
4487330f729Sjoerg                                           UPPC, Unexpanded);
4497330f729Sjoerg }
4507330f729Sjoerg 
DiagnoseUnexpandedParameterPack(const DeclarationNameInfo & NameInfo,UnexpandedParameterPackContext UPPC)4517330f729Sjoerg bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
4527330f729Sjoerg                                          UnexpandedParameterPackContext UPPC) {
4537330f729Sjoerg   // C++0x [temp.variadic]p5:
4547330f729Sjoerg   //   An appearance of a name of a parameter pack that is not expanded is
4557330f729Sjoerg   //   ill-formed.
4567330f729Sjoerg   switch (NameInfo.getName().getNameKind()) {
4577330f729Sjoerg   case DeclarationName::Identifier:
4587330f729Sjoerg   case DeclarationName::ObjCZeroArgSelector:
4597330f729Sjoerg   case DeclarationName::ObjCOneArgSelector:
4607330f729Sjoerg   case DeclarationName::ObjCMultiArgSelector:
4617330f729Sjoerg   case DeclarationName::CXXOperatorName:
4627330f729Sjoerg   case DeclarationName::CXXLiteralOperatorName:
4637330f729Sjoerg   case DeclarationName::CXXUsingDirective:
4647330f729Sjoerg   case DeclarationName::CXXDeductionGuideName:
4657330f729Sjoerg     return false;
4667330f729Sjoerg 
4677330f729Sjoerg   case DeclarationName::CXXConstructorName:
4687330f729Sjoerg   case DeclarationName::CXXDestructorName:
4697330f729Sjoerg   case DeclarationName::CXXConversionFunctionName:
4707330f729Sjoerg     // FIXME: We shouldn't need this null check!
4717330f729Sjoerg     if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
4727330f729Sjoerg       return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
4737330f729Sjoerg 
4747330f729Sjoerg     if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
4757330f729Sjoerg       return false;
4767330f729Sjoerg 
4777330f729Sjoerg     break;
4787330f729Sjoerg   }
4797330f729Sjoerg 
4807330f729Sjoerg   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4817330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded)
4827330f729Sjoerg     .TraverseType(NameInfo.getName().getCXXNameType());
4837330f729Sjoerg   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4847330f729Sjoerg   return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
4857330f729Sjoerg }
4867330f729Sjoerg 
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TemplateName Template,UnexpandedParameterPackContext UPPC)4877330f729Sjoerg bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
4887330f729Sjoerg                                            TemplateName Template,
4897330f729Sjoerg                                        UnexpandedParameterPackContext UPPC) {
4907330f729Sjoerg 
4917330f729Sjoerg   if (Template.isNull() || !Template.containsUnexpandedParameterPack())
4927330f729Sjoerg     return false;
4937330f729Sjoerg 
4947330f729Sjoerg   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4957330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded)
4967330f729Sjoerg     .TraverseTemplateName(Template);
4977330f729Sjoerg   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4987330f729Sjoerg   return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
4997330f729Sjoerg }
5007330f729Sjoerg 
DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,UnexpandedParameterPackContext UPPC)5017330f729Sjoerg bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
5027330f729Sjoerg                                          UnexpandedParameterPackContext UPPC) {
5037330f729Sjoerg   if (Arg.getArgument().isNull() ||
5047330f729Sjoerg       !Arg.getArgument().containsUnexpandedParameterPack())
5057330f729Sjoerg     return false;
5067330f729Sjoerg 
5077330f729Sjoerg   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5087330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5097330f729Sjoerg     .TraverseTemplateArgumentLoc(Arg);
5107330f729Sjoerg   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
5117330f729Sjoerg   return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
5127330f729Sjoerg }
5137330f729Sjoerg 
collectUnexpandedParameterPacks(TemplateArgument Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5147330f729Sjoerg void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
5157330f729Sjoerg                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5167330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5177330f729Sjoerg     .TraverseTemplateArgument(Arg);
5187330f729Sjoerg }
5197330f729Sjoerg 
collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5207330f729Sjoerg void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
5217330f729Sjoerg                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5227330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5237330f729Sjoerg     .TraverseTemplateArgumentLoc(Arg);
5247330f729Sjoerg }
5257330f729Sjoerg 
collectUnexpandedParameterPacks(QualType T,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5267330f729Sjoerg void Sema::collectUnexpandedParameterPacks(QualType T,
5277330f729Sjoerg                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5287330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
5297330f729Sjoerg }
5307330f729Sjoerg 
collectUnexpandedParameterPacks(TypeLoc TL,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5317330f729Sjoerg void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
5327330f729Sjoerg                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5337330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
5347330f729Sjoerg }
5357330f729Sjoerg 
collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5367330f729Sjoerg void Sema::collectUnexpandedParameterPacks(
5377330f729Sjoerg     NestedNameSpecifierLoc NNS,
5387330f729Sjoerg     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5397330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5407330f729Sjoerg       .TraverseNestedNameSpecifierLoc(NNS);
5417330f729Sjoerg }
5427330f729Sjoerg 
collectUnexpandedParameterPacks(const DeclarationNameInfo & NameInfo,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5437330f729Sjoerg void Sema::collectUnexpandedParameterPacks(
5447330f729Sjoerg     const DeclarationNameInfo &NameInfo,
5457330f729Sjoerg     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5467330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5477330f729Sjoerg     .TraverseDeclarationNameInfo(NameInfo);
5487330f729Sjoerg }
5497330f729Sjoerg 
5507330f729Sjoerg 
5517330f729Sjoerg ParsedTemplateArgument
ActOnPackExpansion(const ParsedTemplateArgument & Arg,SourceLocation EllipsisLoc)5527330f729Sjoerg Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
5537330f729Sjoerg                          SourceLocation EllipsisLoc) {
5547330f729Sjoerg   if (Arg.isInvalid())
5557330f729Sjoerg     return Arg;
5567330f729Sjoerg 
5577330f729Sjoerg   switch (Arg.getKind()) {
5587330f729Sjoerg   case ParsedTemplateArgument::Type: {
5597330f729Sjoerg     TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
5607330f729Sjoerg     if (Result.isInvalid())
5617330f729Sjoerg       return ParsedTemplateArgument();
5627330f729Sjoerg 
5637330f729Sjoerg     return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
5647330f729Sjoerg                                   Arg.getLocation());
5657330f729Sjoerg   }
5667330f729Sjoerg 
5677330f729Sjoerg   case ParsedTemplateArgument::NonType: {
5687330f729Sjoerg     ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
5697330f729Sjoerg     if (Result.isInvalid())
5707330f729Sjoerg       return ParsedTemplateArgument();
5717330f729Sjoerg 
5727330f729Sjoerg     return ParsedTemplateArgument(Arg.getKind(), Result.get(),
5737330f729Sjoerg                                   Arg.getLocation());
5747330f729Sjoerg   }
5757330f729Sjoerg 
5767330f729Sjoerg   case ParsedTemplateArgument::Template:
5777330f729Sjoerg     if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
5787330f729Sjoerg       SourceRange R(Arg.getLocation());
5797330f729Sjoerg       if (Arg.getScopeSpec().isValid())
5807330f729Sjoerg         R.setBegin(Arg.getScopeSpec().getBeginLoc());
5817330f729Sjoerg       Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
5827330f729Sjoerg         << R;
5837330f729Sjoerg       return ParsedTemplateArgument();
5847330f729Sjoerg     }
5857330f729Sjoerg 
5867330f729Sjoerg     return Arg.getTemplatePackExpansion(EllipsisLoc);
5877330f729Sjoerg   }
5887330f729Sjoerg   llvm_unreachable("Unhandled template argument kind?");
5897330f729Sjoerg }
5907330f729Sjoerg 
ActOnPackExpansion(ParsedType Type,SourceLocation EllipsisLoc)5917330f729Sjoerg TypeResult Sema::ActOnPackExpansion(ParsedType Type,
5927330f729Sjoerg                                     SourceLocation EllipsisLoc) {
5937330f729Sjoerg   TypeSourceInfo *TSInfo;
5947330f729Sjoerg   GetTypeFromParser(Type, &TSInfo);
5957330f729Sjoerg   if (!TSInfo)
5967330f729Sjoerg     return true;
5977330f729Sjoerg 
5987330f729Sjoerg   TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None);
5997330f729Sjoerg   if (!TSResult)
6007330f729Sjoerg     return true;
6017330f729Sjoerg 
6027330f729Sjoerg   return CreateParsedType(TSResult->getType(), TSResult);
6037330f729Sjoerg }
6047330f729Sjoerg 
6057330f729Sjoerg TypeSourceInfo *
CheckPackExpansion(TypeSourceInfo * Pattern,SourceLocation EllipsisLoc,Optional<unsigned> NumExpansions)6067330f729Sjoerg Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc,
6077330f729Sjoerg                          Optional<unsigned> NumExpansions) {
6087330f729Sjoerg   // Create the pack expansion type and source-location information.
6097330f729Sjoerg   QualType Result = CheckPackExpansion(Pattern->getType(),
6107330f729Sjoerg                                        Pattern->getTypeLoc().getSourceRange(),
6117330f729Sjoerg                                        EllipsisLoc, NumExpansions);
6127330f729Sjoerg   if (Result.isNull())
6137330f729Sjoerg     return nullptr;
6147330f729Sjoerg 
6157330f729Sjoerg   TypeLocBuilder TLB;
6167330f729Sjoerg   TLB.pushFullCopy(Pattern->getTypeLoc());
6177330f729Sjoerg   PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result);
6187330f729Sjoerg   TL.setEllipsisLoc(EllipsisLoc);
6197330f729Sjoerg 
6207330f729Sjoerg   return TLB.getTypeSourceInfo(Context, Result);
6217330f729Sjoerg }
6227330f729Sjoerg 
CheckPackExpansion(QualType Pattern,SourceRange PatternRange,SourceLocation EllipsisLoc,Optional<unsigned> NumExpansions)6237330f729Sjoerg QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
6247330f729Sjoerg                                   SourceLocation EllipsisLoc,
6257330f729Sjoerg                                   Optional<unsigned> NumExpansions) {
6267330f729Sjoerg   // C++11 [temp.variadic]p5:
6277330f729Sjoerg   //   The pattern of a pack expansion shall name one or more
6287330f729Sjoerg   //   parameter packs that are not expanded by a nested pack
6297330f729Sjoerg   //   expansion.
6307330f729Sjoerg   //
6317330f729Sjoerg   // A pattern containing a deduced type can't occur "naturally" but arises in
6327330f729Sjoerg   // the desugaring of an init-capture pack.
6337330f729Sjoerg   if (!Pattern->containsUnexpandedParameterPack() &&
6347330f729Sjoerg       !Pattern->getContainedDeducedType()) {
6357330f729Sjoerg     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
6367330f729Sjoerg       << PatternRange;
6377330f729Sjoerg     return QualType();
6387330f729Sjoerg   }
6397330f729Sjoerg 
640*e038c9c4Sjoerg   return Context.getPackExpansionType(Pattern, NumExpansions,
641*e038c9c4Sjoerg                                       /*ExpectPackInType=*/false);
6427330f729Sjoerg }
6437330f729Sjoerg 
ActOnPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc)6447330f729Sjoerg ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
6457330f729Sjoerg   return CheckPackExpansion(Pattern, EllipsisLoc, None);
6467330f729Sjoerg }
6477330f729Sjoerg 
CheckPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc,Optional<unsigned> NumExpansions)6487330f729Sjoerg ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
6497330f729Sjoerg                                     Optional<unsigned> NumExpansions) {
6507330f729Sjoerg   if (!Pattern)
6517330f729Sjoerg     return ExprError();
6527330f729Sjoerg 
6537330f729Sjoerg   // C++0x [temp.variadic]p5:
6547330f729Sjoerg   //   The pattern of a pack expansion shall name one or more
6557330f729Sjoerg   //   parameter packs that are not expanded by a nested pack
6567330f729Sjoerg   //   expansion.
6577330f729Sjoerg   if (!Pattern->containsUnexpandedParameterPack()) {
6587330f729Sjoerg     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
6597330f729Sjoerg     << Pattern->getSourceRange();
6607330f729Sjoerg     CorrectDelayedTyposInExpr(Pattern);
6617330f729Sjoerg     return ExprError();
6627330f729Sjoerg   }
6637330f729Sjoerg 
6647330f729Sjoerg   // Create the pack expansion expression and source-location information.
6657330f729Sjoerg   return new (Context)
6667330f729Sjoerg     PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
6677330f729Sjoerg }
6687330f729Sjoerg 
CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,SourceRange PatternRange,ArrayRef<UnexpandedParameterPack> Unexpanded,const MultiLevelTemplateArgumentList & TemplateArgs,bool & ShouldExpand,bool & RetainExpansion,Optional<unsigned> & NumExpansions)6697330f729Sjoerg bool Sema::CheckParameterPacksForExpansion(
6707330f729Sjoerg     SourceLocation EllipsisLoc, SourceRange PatternRange,
6717330f729Sjoerg     ArrayRef<UnexpandedParameterPack> Unexpanded,
6727330f729Sjoerg     const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
6737330f729Sjoerg     bool &RetainExpansion, Optional<unsigned> &NumExpansions) {
6747330f729Sjoerg   ShouldExpand = true;
6757330f729Sjoerg   RetainExpansion = false;
6767330f729Sjoerg   std::pair<IdentifierInfo *, SourceLocation> FirstPack;
6777330f729Sjoerg   bool HaveFirstPack = false;
6787330f729Sjoerg   Optional<unsigned> NumPartialExpansions;
6797330f729Sjoerg   SourceLocation PartiallySubstitutedPackLoc;
6807330f729Sjoerg 
6817330f729Sjoerg   for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(),
6827330f729Sjoerg                                                  end = Unexpanded.end();
6837330f729Sjoerg                                                   i != end; ++i) {
6847330f729Sjoerg     // Compute the depth and index for this parameter pack.
6857330f729Sjoerg     unsigned Depth = 0, Index = 0;
6867330f729Sjoerg     IdentifierInfo *Name;
6877330f729Sjoerg     bool IsVarDeclPack = false;
6887330f729Sjoerg 
6897330f729Sjoerg     if (const TemplateTypeParmType *TTP
6907330f729Sjoerg         = i->first.dyn_cast<const TemplateTypeParmType *>()) {
6917330f729Sjoerg       Depth = TTP->getDepth();
6927330f729Sjoerg       Index = TTP->getIndex();
6937330f729Sjoerg       Name = TTP->getIdentifier();
6947330f729Sjoerg     } else {
6957330f729Sjoerg       NamedDecl *ND = i->first.get<NamedDecl *>();
6967330f729Sjoerg       if (isa<VarDecl>(ND))
6977330f729Sjoerg         IsVarDeclPack = true;
6987330f729Sjoerg       else
6997330f729Sjoerg         std::tie(Depth, Index) = getDepthAndIndex(ND);
7007330f729Sjoerg 
7017330f729Sjoerg       Name = ND->getIdentifier();
7027330f729Sjoerg     }
7037330f729Sjoerg 
7047330f729Sjoerg     // Determine the size of this argument pack.
7057330f729Sjoerg     unsigned NewPackSize;
7067330f729Sjoerg     if (IsVarDeclPack) {
7077330f729Sjoerg       // Figure out whether we're instantiating to an argument pack or not.
7087330f729Sjoerg       typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
7097330f729Sjoerg 
7107330f729Sjoerg       llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
7117330f729Sjoerg         = CurrentInstantiationScope->findInstantiationOf(
7127330f729Sjoerg                                         i->first.get<NamedDecl *>());
7137330f729Sjoerg       if (Instantiation->is<DeclArgumentPack *>()) {
7147330f729Sjoerg         // We could expand this function parameter pack.
7157330f729Sjoerg         NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
7167330f729Sjoerg       } else {
7177330f729Sjoerg         // We can't expand this function parameter pack, so we can't expand
7187330f729Sjoerg         // the pack expansion.
7197330f729Sjoerg         ShouldExpand = false;
7207330f729Sjoerg         continue;
7217330f729Sjoerg       }
7227330f729Sjoerg     } else {
7237330f729Sjoerg       // If we don't have a template argument at this depth/index, then we
7247330f729Sjoerg       // cannot expand the pack expansion. Make a note of this, but we still
7257330f729Sjoerg       // want to check any parameter packs we *do* have arguments for.
7267330f729Sjoerg       if (Depth >= TemplateArgs.getNumLevels() ||
7277330f729Sjoerg           !TemplateArgs.hasTemplateArgument(Depth, Index)) {
7287330f729Sjoerg         ShouldExpand = false;
7297330f729Sjoerg         continue;
7307330f729Sjoerg       }
7317330f729Sjoerg 
7327330f729Sjoerg       // Determine the size of the argument pack.
7337330f729Sjoerg       NewPackSize = TemplateArgs(Depth, Index).pack_size();
7347330f729Sjoerg     }
7357330f729Sjoerg 
7367330f729Sjoerg     // C++0x [temp.arg.explicit]p9:
7377330f729Sjoerg     //   Template argument deduction can extend the sequence of template
7387330f729Sjoerg     //   arguments corresponding to a template parameter pack, even when the
7397330f729Sjoerg     //   sequence contains explicitly specified template arguments.
7407330f729Sjoerg     if (!IsVarDeclPack && CurrentInstantiationScope) {
7417330f729Sjoerg       if (NamedDecl *PartialPack
7427330f729Sjoerg                     = CurrentInstantiationScope->getPartiallySubstitutedPack()){
7437330f729Sjoerg         unsigned PartialDepth, PartialIndex;
7447330f729Sjoerg         std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
7457330f729Sjoerg         if (PartialDepth == Depth && PartialIndex == Index) {
7467330f729Sjoerg           RetainExpansion = true;
7477330f729Sjoerg           // We don't actually know the new pack size yet.
7487330f729Sjoerg           NumPartialExpansions = NewPackSize;
7497330f729Sjoerg           PartiallySubstitutedPackLoc = i->second;
7507330f729Sjoerg           continue;
7517330f729Sjoerg         }
7527330f729Sjoerg       }
7537330f729Sjoerg     }
7547330f729Sjoerg 
7557330f729Sjoerg     if (!NumExpansions) {
7567330f729Sjoerg       // The is the first pack we've seen for which we have an argument.
7577330f729Sjoerg       // Record it.
7587330f729Sjoerg       NumExpansions = NewPackSize;
7597330f729Sjoerg       FirstPack.first = Name;
7607330f729Sjoerg       FirstPack.second = i->second;
7617330f729Sjoerg       HaveFirstPack = true;
7627330f729Sjoerg       continue;
7637330f729Sjoerg     }
7647330f729Sjoerg 
7657330f729Sjoerg     if (NewPackSize != *NumExpansions) {
7667330f729Sjoerg       // C++0x [temp.variadic]p5:
7677330f729Sjoerg       //   All of the parameter packs expanded by a pack expansion shall have
7687330f729Sjoerg       //   the same number of arguments specified.
7697330f729Sjoerg       if (HaveFirstPack)
7707330f729Sjoerg         Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
7717330f729Sjoerg           << FirstPack.first << Name << *NumExpansions << NewPackSize
7727330f729Sjoerg           << SourceRange(FirstPack.second) << SourceRange(i->second);
7737330f729Sjoerg       else
7747330f729Sjoerg         Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
7757330f729Sjoerg           << Name << *NumExpansions << NewPackSize
7767330f729Sjoerg           << SourceRange(i->second);
7777330f729Sjoerg       return true;
7787330f729Sjoerg     }
7797330f729Sjoerg   }
7807330f729Sjoerg 
7817330f729Sjoerg   // If we're performing a partial expansion but we also have a full expansion,
7827330f729Sjoerg   // expand to the number of common arguments. For example, given:
7837330f729Sjoerg   //
7847330f729Sjoerg   //   template<typename ...T> struct A {
7857330f729Sjoerg   //     template<typename ...U> void f(pair<T, U>...);
7867330f729Sjoerg   //   };
7877330f729Sjoerg   //
7887330f729Sjoerg   // ... a call to 'A<int, int>().f<int>' should expand the pack once and
7897330f729Sjoerg   // retain an expansion.
7907330f729Sjoerg   if (NumPartialExpansions) {
7917330f729Sjoerg     if (NumExpansions && *NumExpansions < *NumPartialExpansions) {
7927330f729Sjoerg       NamedDecl *PartialPack =
7937330f729Sjoerg           CurrentInstantiationScope->getPartiallySubstitutedPack();
7947330f729Sjoerg       Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial)
7957330f729Sjoerg         << PartialPack << *NumPartialExpansions << *NumExpansions
7967330f729Sjoerg         << SourceRange(PartiallySubstitutedPackLoc);
7977330f729Sjoerg       return true;
7987330f729Sjoerg     }
7997330f729Sjoerg 
8007330f729Sjoerg     NumExpansions = NumPartialExpansions;
8017330f729Sjoerg   }
8027330f729Sjoerg 
8037330f729Sjoerg   return false;
8047330f729Sjoerg }
8057330f729Sjoerg 
getNumArgumentsInExpansion(QualType T,const MultiLevelTemplateArgumentList & TemplateArgs)8067330f729Sjoerg Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T,
8077330f729Sjoerg                           const MultiLevelTemplateArgumentList &TemplateArgs) {
8087330f729Sjoerg   QualType Pattern = cast<PackExpansionType>(T)->getPattern();
8097330f729Sjoerg   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8107330f729Sjoerg   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
8117330f729Sjoerg 
8127330f729Sjoerg   Optional<unsigned> Result;
8137330f729Sjoerg   for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
8147330f729Sjoerg     // Compute the depth and index for this parameter pack.
8157330f729Sjoerg     unsigned Depth;
8167330f729Sjoerg     unsigned Index;
8177330f729Sjoerg 
8187330f729Sjoerg     if (const TemplateTypeParmType *TTP
8197330f729Sjoerg           = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
8207330f729Sjoerg       Depth = TTP->getDepth();
8217330f729Sjoerg       Index = TTP->getIndex();
8227330f729Sjoerg     } else {
8237330f729Sjoerg       NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
8247330f729Sjoerg       if (isa<VarDecl>(ND)) {
8257330f729Sjoerg         // Function parameter pack or init-capture pack.
8267330f729Sjoerg         typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
8277330f729Sjoerg 
8287330f729Sjoerg         llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
8297330f729Sjoerg           = CurrentInstantiationScope->findInstantiationOf(
8307330f729Sjoerg                                         Unexpanded[I].first.get<NamedDecl *>());
8317330f729Sjoerg         if (Instantiation->is<Decl*>())
8327330f729Sjoerg           // The pattern refers to an unexpanded pack. We're not ready to expand
8337330f729Sjoerg           // this pack yet.
8347330f729Sjoerg           return None;
8357330f729Sjoerg 
8367330f729Sjoerg         unsigned Size = Instantiation->get<DeclArgumentPack *>()->size();
8377330f729Sjoerg         assert((!Result || *Result == Size) && "inconsistent pack sizes");
8387330f729Sjoerg         Result = Size;
8397330f729Sjoerg         continue;
8407330f729Sjoerg       }
8417330f729Sjoerg 
8427330f729Sjoerg       std::tie(Depth, Index) = getDepthAndIndex(ND);
8437330f729Sjoerg     }
8447330f729Sjoerg     if (Depth >= TemplateArgs.getNumLevels() ||
8457330f729Sjoerg         !TemplateArgs.hasTemplateArgument(Depth, Index))
8467330f729Sjoerg       // The pattern refers to an unknown template argument. We're not ready to
8477330f729Sjoerg       // expand this pack yet.
8487330f729Sjoerg       return None;
8497330f729Sjoerg 
8507330f729Sjoerg     // Determine the size of the argument pack.
8517330f729Sjoerg     unsigned Size = TemplateArgs(Depth, Index).pack_size();
8527330f729Sjoerg     assert((!Result || *Result == Size) && "inconsistent pack sizes");
8537330f729Sjoerg     Result = Size;
8547330f729Sjoerg   }
8557330f729Sjoerg 
8567330f729Sjoerg   return Result;
8577330f729Sjoerg }
8587330f729Sjoerg 
containsUnexpandedParameterPacks(Declarator & D)8597330f729Sjoerg bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
8607330f729Sjoerg   const DeclSpec &DS = D.getDeclSpec();
8617330f729Sjoerg   switch (DS.getTypeSpecType()) {
8627330f729Sjoerg   case TST_typename:
8637330f729Sjoerg   case TST_typeofType:
8647330f729Sjoerg   case TST_underlyingType:
8657330f729Sjoerg   case TST_atomic: {
8667330f729Sjoerg     QualType T = DS.getRepAsType().get();
8677330f729Sjoerg     if (!T.isNull() && T->containsUnexpandedParameterPack())
8687330f729Sjoerg       return true;
8697330f729Sjoerg     break;
8707330f729Sjoerg   }
8717330f729Sjoerg 
8727330f729Sjoerg   case TST_typeofExpr:
8737330f729Sjoerg   case TST_decltype:
874*e038c9c4Sjoerg   case TST_extint:
8757330f729Sjoerg     if (DS.getRepAsExpr() &&
8767330f729Sjoerg         DS.getRepAsExpr()->containsUnexpandedParameterPack())
8777330f729Sjoerg       return true;
8787330f729Sjoerg     break;
8797330f729Sjoerg 
8807330f729Sjoerg   case TST_unspecified:
8817330f729Sjoerg   case TST_void:
8827330f729Sjoerg   case TST_char:
8837330f729Sjoerg   case TST_wchar:
8847330f729Sjoerg   case TST_char8:
8857330f729Sjoerg   case TST_char16:
8867330f729Sjoerg   case TST_char32:
8877330f729Sjoerg   case TST_int:
8887330f729Sjoerg   case TST_int128:
8897330f729Sjoerg   case TST_half:
8907330f729Sjoerg   case TST_float:
8917330f729Sjoerg   case TST_double:
8927330f729Sjoerg   case TST_Accum:
8937330f729Sjoerg   case TST_Fract:
8947330f729Sjoerg   case TST_Float16:
8957330f729Sjoerg   case TST_float128:
8967330f729Sjoerg   case TST_bool:
8977330f729Sjoerg   case TST_decimal32:
8987330f729Sjoerg   case TST_decimal64:
8997330f729Sjoerg   case TST_decimal128:
9007330f729Sjoerg   case TST_enum:
9017330f729Sjoerg   case TST_union:
9027330f729Sjoerg   case TST_struct:
9037330f729Sjoerg   case TST_interface:
9047330f729Sjoerg   case TST_class:
9057330f729Sjoerg   case TST_auto:
9067330f729Sjoerg   case TST_auto_type:
9077330f729Sjoerg   case TST_decltype_auto:
908*e038c9c4Sjoerg   case TST_BFloat16:
9097330f729Sjoerg #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:
9107330f729Sjoerg #include "clang/Basic/OpenCLImageTypes.def"
9117330f729Sjoerg   case TST_unknown_anytype:
9127330f729Sjoerg   case TST_error:
9137330f729Sjoerg     break;
9147330f729Sjoerg   }
9157330f729Sjoerg 
9167330f729Sjoerg   for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
9177330f729Sjoerg     const DeclaratorChunk &Chunk = D.getTypeObject(I);
9187330f729Sjoerg     switch (Chunk.Kind) {
9197330f729Sjoerg     case DeclaratorChunk::Pointer:
9207330f729Sjoerg     case DeclaratorChunk::Reference:
9217330f729Sjoerg     case DeclaratorChunk::Paren:
9227330f729Sjoerg     case DeclaratorChunk::Pipe:
9237330f729Sjoerg     case DeclaratorChunk::BlockPointer:
9247330f729Sjoerg       // These declarator chunks cannot contain any parameter packs.
9257330f729Sjoerg       break;
9267330f729Sjoerg 
9277330f729Sjoerg     case DeclaratorChunk::Array:
9287330f729Sjoerg       if (Chunk.Arr.NumElts &&
9297330f729Sjoerg           Chunk.Arr.NumElts->containsUnexpandedParameterPack())
9307330f729Sjoerg         return true;
9317330f729Sjoerg       break;
9327330f729Sjoerg     case DeclaratorChunk::Function:
9337330f729Sjoerg       for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) {
9347330f729Sjoerg         ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param);
9357330f729Sjoerg         QualType ParamTy = Param->getType();
9367330f729Sjoerg         assert(!ParamTy.isNull() && "Couldn't parse type?");
9377330f729Sjoerg         if (ParamTy->containsUnexpandedParameterPack()) return true;
9387330f729Sjoerg       }
9397330f729Sjoerg 
9407330f729Sjoerg       if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) {
9417330f729Sjoerg         for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) {
9427330f729Sjoerg           if (Chunk.Fun.Exceptions[i]
9437330f729Sjoerg                   .Ty.get()
9447330f729Sjoerg                   ->containsUnexpandedParameterPack())
9457330f729Sjoerg             return true;
9467330f729Sjoerg         }
9477330f729Sjoerg       } else if (isComputedNoexcept(Chunk.Fun.getExceptionSpecType()) &&
9487330f729Sjoerg                  Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack())
9497330f729Sjoerg         return true;
9507330f729Sjoerg 
9517330f729Sjoerg       if (Chunk.Fun.hasTrailingReturnType()) {
9527330f729Sjoerg         QualType T = Chunk.Fun.getTrailingReturnType().get();
9537330f729Sjoerg         if (!T.isNull() && T->containsUnexpandedParameterPack())
9547330f729Sjoerg           return true;
9557330f729Sjoerg       }
9567330f729Sjoerg       break;
9577330f729Sjoerg 
9587330f729Sjoerg     case DeclaratorChunk::MemberPointer:
9597330f729Sjoerg       if (Chunk.Mem.Scope().getScopeRep() &&
9607330f729Sjoerg           Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
9617330f729Sjoerg         return true;
9627330f729Sjoerg       break;
9637330f729Sjoerg     }
9647330f729Sjoerg   }
9657330f729Sjoerg 
966*e038c9c4Sjoerg   if (Expr *TRC = D.getTrailingRequiresClause())
967*e038c9c4Sjoerg     if (TRC->containsUnexpandedParameterPack())
968*e038c9c4Sjoerg       return true;
969*e038c9c4Sjoerg 
9707330f729Sjoerg   return false;
9717330f729Sjoerg }
9727330f729Sjoerg 
9737330f729Sjoerg namespace {
9747330f729Sjoerg 
9757330f729Sjoerg // Callback to only accept typo corrections that refer to parameter packs.
9767330f729Sjoerg class ParameterPackValidatorCCC final : public CorrectionCandidateCallback {
9777330f729Sjoerg  public:
ValidateCandidate(const TypoCorrection & candidate)9787330f729Sjoerg   bool ValidateCandidate(const TypoCorrection &candidate) override {
9797330f729Sjoerg     NamedDecl *ND = candidate.getCorrectionDecl();
9807330f729Sjoerg     return ND && ND->isParameterPack();
9817330f729Sjoerg   }
9827330f729Sjoerg 
clone()9837330f729Sjoerg   std::unique_ptr<CorrectionCandidateCallback> clone() override {
9847330f729Sjoerg     return std::make_unique<ParameterPackValidatorCCC>(*this);
9857330f729Sjoerg   }
9867330f729Sjoerg };
9877330f729Sjoerg 
9887330f729Sjoerg }
9897330f729Sjoerg 
9907330f729Sjoerg /// Called when an expression computing the size of a parameter pack
9917330f729Sjoerg /// is parsed.
9927330f729Sjoerg ///
9937330f729Sjoerg /// \code
9947330f729Sjoerg /// template<typename ...Types> struct count {
9957330f729Sjoerg ///   static const unsigned value = sizeof...(Types);
9967330f729Sjoerg /// };
9977330f729Sjoerg /// \endcode
9987330f729Sjoerg ///
9997330f729Sjoerg //
10007330f729Sjoerg /// \param OpLoc The location of the "sizeof" keyword.
10017330f729Sjoerg /// \param Name The name of the parameter pack whose size will be determined.
10027330f729Sjoerg /// \param NameLoc The source location of the name of the parameter pack.
10037330f729Sjoerg /// \param RParenLoc The location of the closing parentheses.
ActOnSizeofParameterPackExpr(Scope * S,SourceLocation OpLoc,IdentifierInfo & Name,SourceLocation NameLoc,SourceLocation RParenLoc)10047330f729Sjoerg ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
10057330f729Sjoerg                                               SourceLocation OpLoc,
10067330f729Sjoerg                                               IdentifierInfo &Name,
10077330f729Sjoerg                                               SourceLocation NameLoc,
10087330f729Sjoerg                                               SourceLocation RParenLoc) {
10097330f729Sjoerg   // C++0x [expr.sizeof]p5:
10107330f729Sjoerg   //   The identifier in a sizeof... expression shall name a parameter pack.
10117330f729Sjoerg   LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
10127330f729Sjoerg   LookupName(R, S);
10137330f729Sjoerg 
10147330f729Sjoerg   NamedDecl *ParameterPack = nullptr;
10157330f729Sjoerg   switch (R.getResultKind()) {
10167330f729Sjoerg   case LookupResult::Found:
10177330f729Sjoerg     ParameterPack = R.getFoundDecl();
10187330f729Sjoerg     break;
10197330f729Sjoerg 
10207330f729Sjoerg   case LookupResult::NotFound:
10217330f729Sjoerg   case LookupResult::NotFoundInCurrentInstantiation: {
10227330f729Sjoerg     ParameterPackValidatorCCC CCC{};
10237330f729Sjoerg     if (TypoCorrection Corrected =
10247330f729Sjoerg             CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr,
10257330f729Sjoerg                         CCC, CTK_ErrorRecovery)) {
10267330f729Sjoerg       diagnoseTypo(Corrected,
10277330f729Sjoerg                    PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,
10287330f729Sjoerg                    PDiag(diag::note_parameter_pack_here));
10297330f729Sjoerg       ParameterPack = Corrected.getCorrectionDecl();
10307330f729Sjoerg     }
10317330f729Sjoerg     break;
10327330f729Sjoerg   }
10337330f729Sjoerg   case LookupResult::FoundOverloaded:
10347330f729Sjoerg   case LookupResult::FoundUnresolvedValue:
10357330f729Sjoerg     break;
10367330f729Sjoerg 
10377330f729Sjoerg   case LookupResult::Ambiguous:
10387330f729Sjoerg     DiagnoseAmbiguousLookup(R);
10397330f729Sjoerg     return ExprError();
10407330f729Sjoerg   }
10417330f729Sjoerg 
10427330f729Sjoerg   if (!ParameterPack || !ParameterPack->isParameterPack()) {
10437330f729Sjoerg     Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
10447330f729Sjoerg       << &Name;
10457330f729Sjoerg     return ExprError();
10467330f729Sjoerg   }
10477330f729Sjoerg 
10487330f729Sjoerg   MarkAnyDeclReferenced(OpLoc, ParameterPack, true);
10497330f729Sjoerg 
10507330f729Sjoerg   return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc,
10517330f729Sjoerg                                 RParenLoc);
10527330f729Sjoerg }
10537330f729Sjoerg 
10547330f729Sjoerg TemplateArgumentLoc
getTemplateArgumentPackExpansionPattern(TemplateArgumentLoc OrigLoc,SourceLocation & Ellipsis,Optional<unsigned> & NumExpansions) const10557330f729Sjoerg Sema::getTemplateArgumentPackExpansionPattern(
10567330f729Sjoerg       TemplateArgumentLoc OrigLoc,
10577330f729Sjoerg       SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const {
10587330f729Sjoerg   const TemplateArgument &Argument = OrigLoc.getArgument();
10597330f729Sjoerg   assert(Argument.isPackExpansion());
10607330f729Sjoerg   switch (Argument.getKind()) {
10617330f729Sjoerg   case TemplateArgument::Type: {
10627330f729Sjoerg     // FIXME: We shouldn't ever have to worry about missing
10637330f729Sjoerg     // type-source info!
10647330f729Sjoerg     TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo();
10657330f729Sjoerg     if (!ExpansionTSInfo)
10667330f729Sjoerg       ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(),
10677330f729Sjoerg                                                          Ellipsis);
10687330f729Sjoerg     PackExpansionTypeLoc Expansion =
10697330f729Sjoerg         ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>();
10707330f729Sjoerg     Ellipsis = Expansion.getEllipsisLoc();
10717330f729Sjoerg 
10727330f729Sjoerg     TypeLoc Pattern = Expansion.getPatternLoc();
10737330f729Sjoerg     NumExpansions = Expansion.getTypePtr()->getNumExpansions();
10747330f729Sjoerg 
10757330f729Sjoerg     // We need to copy the TypeLoc because TemplateArgumentLocs store a
10767330f729Sjoerg     // TypeSourceInfo.
10777330f729Sjoerg     // FIXME: Find some way to avoid the copy?
10787330f729Sjoerg     TypeLocBuilder TLB;
10797330f729Sjoerg     TLB.pushFullCopy(Pattern);
10807330f729Sjoerg     TypeSourceInfo *PatternTSInfo =
10817330f729Sjoerg         TLB.getTypeSourceInfo(Context, Pattern.getType());
10827330f729Sjoerg     return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
10837330f729Sjoerg                                PatternTSInfo);
10847330f729Sjoerg   }
10857330f729Sjoerg 
10867330f729Sjoerg   case TemplateArgument::Expression: {
10877330f729Sjoerg     PackExpansionExpr *Expansion
10887330f729Sjoerg       = cast<PackExpansionExpr>(Argument.getAsExpr());
10897330f729Sjoerg     Expr *Pattern = Expansion->getPattern();
10907330f729Sjoerg     Ellipsis = Expansion->getEllipsisLoc();
10917330f729Sjoerg     NumExpansions = Expansion->getNumExpansions();
10927330f729Sjoerg     return TemplateArgumentLoc(Pattern, Pattern);
10937330f729Sjoerg   }
10947330f729Sjoerg 
10957330f729Sjoerg   case TemplateArgument::TemplateExpansion:
10967330f729Sjoerg     Ellipsis = OrigLoc.getTemplateEllipsisLoc();
10977330f729Sjoerg     NumExpansions = Argument.getNumTemplateExpansions();
1098*e038c9c4Sjoerg     return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(),
10997330f729Sjoerg                                OrigLoc.getTemplateQualifierLoc(),
11007330f729Sjoerg                                OrigLoc.getTemplateNameLoc());
11017330f729Sjoerg 
11027330f729Sjoerg   case TemplateArgument::Declaration:
11037330f729Sjoerg   case TemplateArgument::NullPtr:
11047330f729Sjoerg   case TemplateArgument::Template:
11057330f729Sjoerg   case TemplateArgument::Integral:
11067330f729Sjoerg   case TemplateArgument::Pack:
11077330f729Sjoerg   case TemplateArgument::Null:
11087330f729Sjoerg     return TemplateArgumentLoc();
11097330f729Sjoerg   }
11107330f729Sjoerg 
11117330f729Sjoerg   llvm_unreachable("Invalid TemplateArgument Kind!");
11127330f729Sjoerg }
11137330f729Sjoerg 
getFullyPackExpandedSize(TemplateArgument Arg)11147330f729Sjoerg Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
11157330f729Sjoerg   assert(Arg.containsUnexpandedParameterPack());
11167330f729Sjoerg 
11177330f729Sjoerg   // If this is a substituted pack, grab that pack. If not, we don't know
11187330f729Sjoerg   // the size yet.
11197330f729Sjoerg   // FIXME: We could find a size in more cases by looking for a substituted
11207330f729Sjoerg   // pack anywhere within this argument, but that's not necessary in the common
11217330f729Sjoerg   // case for 'sizeof...(A)' handling.
11227330f729Sjoerg   TemplateArgument Pack;
11237330f729Sjoerg   switch (Arg.getKind()) {
11247330f729Sjoerg   case TemplateArgument::Type:
11257330f729Sjoerg     if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>())
11267330f729Sjoerg       Pack = Subst->getArgumentPack();
11277330f729Sjoerg     else
11287330f729Sjoerg       return None;
11297330f729Sjoerg     break;
11307330f729Sjoerg 
11317330f729Sjoerg   case TemplateArgument::Expression:
11327330f729Sjoerg     if (auto *Subst =
11337330f729Sjoerg             dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
11347330f729Sjoerg       Pack = Subst->getArgumentPack();
11357330f729Sjoerg     else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr()))  {
11367330f729Sjoerg       for (VarDecl *PD : *Subst)
11377330f729Sjoerg         if (PD->isParameterPack())
11387330f729Sjoerg           return None;
11397330f729Sjoerg       return Subst->getNumExpansions();
11407330f729Sjoerg     } else
11417330f729Sjoerg       return None;
11427330f729Sjoerg     break;
11437330f729Sjoerg 
11447330f729Sjoerg   case TemplateArgument::Template:
11457330f729Sjoerg     if (SubstTemplateTemplateParmPackStorage *Subst =
11467330f729Sjoerg             Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack())
11477330f729Sjoerg       Pack = Subst->getArgumentPack();
11487330f729Sjoerg     else
11497330f729Sjoerg       return None;
11507330f729Sjoerg     break;
11517330f729Sjoerg 
11527330f729Sjoerg   case TemplateArgument::Declaration:
11537330f729Sjoerg   case TemplateArgument::NullPtr:
11547330f729Sjoerg   case TemplateArgument::TemplateExpansion:
11557330f729Sjoerg   case TemplateArgument::Integral:
11567330f729Sjoerg   case TemplateArgument::Pack:
11577330f729Sjoerg   case TemplateArgument::Null:
11587330f729Sjoerg     return None;
11597330f729Sjoerg   }
11607330f729Sjoerg 
11617330f729Sjoerg   // Check that no argument in the pack is itself a pack expansion.
11627330f729Sjoerg   for (TemplateArgument Elem : Pack.pack_elements()) {
11637330f729Sjoerg     // There's no point recursing in this case; we would have already
11647330f729Sjoerg     // expanded this pack expansion into the enclosing pack if we could.
11657330f729Sjoerg     if (Elem.isPackExpansion())
11667330f729Sjoerg       return None;
11677330f729Sjoerg   }
11687330f729Sjoerg   return Pack.pack_size();
11697330f729Sjoerg }
11707330f729Sjoerg 
CheckFoldOperand(Sema & S,Expr * E)11717330f729Sjoerg static void CheckFoldOperand(Sema &S, Expr *E) {
11727330f729Sjoerg   if (!E)
11737330f729Sjoerg     return;
11747330f729Sjoerg 
11757330f729Sjoerg   E = E->IgnoreImpCasts();
11767330f729Sjoerg   auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
11777330f729Sjoerg   if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) ||
11787330f729Sjoerg       isa<AbstractConditionalOperator>(E)) {
11797330f729Sjoerg     S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand)
11807330f729Sjoerg         << E->getSourceRange()
11817330f729Sjoerg         << FixItHint::CreateInsertion(E->getBeginLoc(), "(")
11827330f729Sjoerg         << FixItHint::CreateInsertion(E->getEndLoc(), ")");
11837330f729Sjoerg   }
11847330f729Sjoerg }
11857330f729Sjoerg 
ActOnCXXFoldExpr(Scope * S,SourceLocation LParenLoc,Expr * LHS,tok::TokenKind Operator,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc)1186*e038c9c4Sjoerg ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS,
11877330f729Sjoerg                                   tok::TokenKind Operator,
11887330f729Sjoerg                                   SourceLocation EllipsisLoc, Expr *RHS,
11897330f729Sjoerg                                   SourceLocation RParenLoc) {
11907330f729Sjoerg   // LHS and RHS must be cast-expressions. We allow an arbitrary expression
11917330f729Sjoerg   // in the parser and reduce down to just cast-expressions here.
11927330f729Sjoerg   CheckFoldOperand(*this, LHS);
11937330f729Sjoerg   CheckFoldOperand(*this, RHS);
11947330f729Sjoerg 
11957330f729Sjoerg   auto DiscardOperands = [&] {
11967330f729Sjoerg     CorrectDelayedTyposInExpr(LHS);
11977330f729Sjoerg     CorrectDelayedTyposInExpr(RHS);
11987330f729Sjoerg   };
11997330f729Sjoerg 
12007330f729Sjoerg   // [expr.prim.fold]p3:
12017330f729Sjoerg   //   In a binary fold, op1 and op2 shall be the same fold-operator, and
12027330f729Sjoerg   //   either e1 shall contain an unexpanded parameter pack or e2 shall contain
12037330f729Sjoerg   //   an unexpanded parameter pack, but not both.
12047330f729Sjoerg   if (LHS && RHS &&
12057330f729Sjoerg       LHS->containsUnexpandedParameterPack() ==
12067330f729Sjoerg           RHS->containsUnexpandedParameterPack()) {
12077330f729Sjoerg     DiscardOperands();
12087330f729Sjoerg     return Diag(EllipsisLoc,
12097330f729Sjoerg                 LHS->containsUnexpandedParameterPack()
12107330f729Sjoerg                     ? diag::err_fold_expression_packs_both_sides
12117330f729Sjoerg                     : diag::err_pack_expansion_without_parameter_packs)
12127330f729Sjoerg         << LHS->getSourceRange() << RHS->getSourceRange();
12137330f729Sjoerg   }
12147330f729Sjoerg 
12157330f729Sjoerg   // [expr.prim.fold]p2:
12167330f729Sjoerg   //   In a unary fold, the cast-expression shall contain an unexpanded
12177330f729Sjoerg   //   parameter pack.
12187330f729Sjoerg   if (!LHS || !RHS) {
12197330f729Sjoerg     Expr *Pack = LHS ? LHS : RHS;
12207330f729Sjoerg     assert(Pack && "fold expression with neither LHS nor RHS");
12217330f729Sjoerg     DiscardOperands();
12227330f729Sjoerg     if (!Pack->containsUnexpandedParameterPack())
12237330f729Sjoerg       return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
12247330f729Sjoerg              << Pack->getSourceRange();
12257330f729Sjoerg   }
12267330f729Sjoerg 
12277330f729Sjoerg   BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator);
1228*e038c9c4Sjoerg 
1229*e038c9c4Sjoerg   // Perform first-phase name lookup now.
1230*e038c9c4Sjoerg   UnresolvedLookupExpr *ULE = nullptr;
1231*e038c9c4Sjoerg   {
1232*e038c9c4Sjoerg     UnresolvedSet<16> Functions;
1233*e038c9c4Sjoerg     LookupBinOp(S, EllipsisLoc, Opc, Functions);
1234*e038c9c4Sjoerg     if (!Functions.empty()) {
1235*e038c9c4Sjoerg       DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(
1236*e038c9c4Sjoerg           BinaryOperator::getOverloadedOperator(Opc));
1237*e038c9c4Sjoerg       ExprResult Callee = CreateUnresolvedLookupExpr(
1238*e038c9c4Sjoerg           /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
1239*e038c9c4Sjoerg           DeclarationNameInfo(OpName, EllipsisLoc), Functions);
1240*e038c9c4Sjoerg       if (Callee.isInvalid())
1241*e038c9c4Sjoerg         return ExprError();
1242*e038c9c4Sjoerg       ULE = cast<UnresolvedLookupExpr>(Callee.get());
1243*e038c9c4Sjoerg     }
1244*e038c9c4Sjoerg   }
1245*e038c9c4Sjoerg 
1246*e038c9c4Sjoerg   return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc,
12477330f729Sjoerg                           None);
12487330f729Sjoerg }
12497330f729Sjoerg 
BuildCXXFoldExpr(UnresolvedLookupExpr * Callee,SourceLocation LParenLoc,Expr * LHS,BinaryOperatorKind Operator,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc,Optional<unsigned> NumExpansions)1250*e038c9c4Sjoerg ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee,
1251*e038c9c4Sjoerg                                   SourceLocation LParenLoc, Expr *LHS,
12527330f729Sjoerg                                   BinaryOperatorKind Operator,
12537330f729Sjoerg                                   SourceLocation EllipsisLoc, Expr *RHS,
12547330f729Sjoerg                                   SourceLocation RParenLoc,
12557330f729Sjoerg                                   Optional<unsigned> NumExpansions) {
1256*e038c9c4Sjoerg   return new (Context)
1257*e038c9c4Sjoerg       CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator,
1258*e038c9c4Sjoerg                   EllipsisLoc, RHS, RParenLoc, NumExpansions);
12597330f729Sjoerg }
12607330f729Sjoerg 
BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,BinaryOperatorKind Operator)12617330f729Sjoerg ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
12627330f729Sjoerg                                        BinaryOperatorKind Operator) {
12637330f729Sjoerg   // [temp.variadic]p9:
12647330f729Sjoerg   //   If N is zero for a unary fold-expression, the value of the expression is
12657330f729Sjoerg   //       &&  ->  true
12667330f729Sjoerg   //       ||  ->  false
12677330f729Sjoerg   //       ,   ->  void()
12687330f729Sjoerg   //   if the operator is not listed [above], the instantiation is ill-formed.
12697330f729Sjoerg   //
12707330f729Sjoerg   // Note that we need to use something like int() here, not merely 0, to
12717330f729Sjoerg   // prevent the result from being a null pointer constant.
12727330f729Sjoerg   QualType ScalarType;
12737330f729Sjoerg   switch (Operator) {
12747330f729Sjoerg   case BO_LOr:
12757330f729Sjoerg     return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false);
12767330f729Sjoerg   case BO_LAnd:
12777330f729Sjoerg     return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true);
12787330f729Sjoerg   case BO_Comma:
12797330f729Sjoerg     ScalarType = Context.VoidTy;
12807330f729Sjoerg     break;
12817330f729Sjoerg 
12827330f729Sjoerg   default:
12837330f729Sjoerg     return Diag(EllipsisLoc, diag::err_fold_expression_empty)
12847330f729Sjoerg         << BinaryOperator::getOpcodeStr(Operator);
12857330f729Sjoerg   }
12867330f729Sjoerg 
12877330f729Sjoerg   return new (Context) CXXScalarValueInitExpr(
12887330f729Sjoerg       ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc),
12897330f729Sjoerg       EllipsisLoc);
12907330f729Sjoerg }
1291