1b55fdf8cSDouglas Gregor //===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
2b55fdf8cSDouglas Gregor //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b55fdf8cSDouglas Gregor //===----------------------------------------------------------------------===/
7b55fdf8cSDouglas Gregor //
8b55fdf8cSDouglas Gregor //  This file implements semantic analysis for C++0x variadic templates.
9b55fdf8cSDouglas Gregor //===----------------------------------------------------------------------===/
10b55fdf8cSDouglas Gregor 
11b55fdf8cSDouglas Gregor #include "clang/Sema/Sema.h"
125553d0d4SChandler Carruth #include "TypeLocBuilder.h"
133a02247dSChandler Carruth #include "clang/AST/Expr.h"
143a02247dSChandler Carruth #include "clang/AST/RecursiveASTVisitor.h"
153a02247dSChandler Carruth #include "clang/AST/TypeLoc.h"
16820ba7baSDouglas Gregor #include "clang/Sema/Lookup.h"
17d2fa766aSDouglas Gregor #include "clang/Sema/ParsedTemplate.h"
182589b980SRichard Smith #include "clang/Sema/ScopeInfo.h"
19b55fdf8cSDouglas Gregor #include "clang/Sema/SemaInternal.h"
20840bd6ccSDouglas Gregor #include "clang/Sema/Template.h"
21b55fdf8cSDouglas Gregor 
22b55fdf8cSDouglas Gregor using namespace clang;
23b55fdf8cSDouglas Gregor 
241da294a9SDouglas Gregor //----------------------------------------------------------------------------
251da294a9SDouglas Gregor // Visitor that collects unexpanded parameter packs
261da294a9SDouglas Gregor //----------------------------------------------------------------------------
271da294a9SDouglas Gregor 
281da294a9SDouglas Gregor namespace {
299fc8faf9SAdrian Prantl   /// A class that collects unexpanded parameter packs.
301da294a9SDouglas Gregor   class CollectUnexpandedParameterPacksVisitor :
311da294a9SDouglas Gregor     public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
321da294a9SDouglas Gregor   {
331da294a9SDouglas Gregor     typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
341da294a9SDouglas Gregor       inherited;
351da294a9SDouglas Gregor 
360e62c1ccSChris Lattner     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
371da294a9SDouglas Gregor 
3878a07ba4SRichard Smith     bool InLambda = false;
3978a07ba4SRichard Smith     unsigned DepthLimit = (unsigned)-1;
4078a07ba4SRichard Smith 
addUnexpanded(NamedDecl * ND,SourceLocation Loc=SourceLocation ())4178a07ba4SRichard Smith     void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
42b2997f57SRichard Smith       if (auto *VD = dyn_cast<VarDecl>(ND)) {
4378a07ba4SRichard Smith         // For now, the only problematic case is a generic lambda's templated
4478a07ba4SRichard Smith         // call operator, so we don't need to look for all the other ways we
4578a07ba4SRichard Smith         // could have reached a dependent parameter pack.
46b2997f57SRichard Smith         auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext());
4778a07ba4SRichard Smith         auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;
4878a07ba4SRichard Smith         if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)
4978a07ba4SRichard Smith           return;
5078a07ba4SRichard Smith       } else if (getDepthAndIndex(ND).first >= DepthLimit)
5178a07ba4SRichard Smith         return;
5278a07ba4SRichard Smith 
5378a07ba4SRichard Smith       Unexpanded.push_back({ND, Loc});
5478a07ba4SRichard Smith     }
addUnexpanded(const TemplateTypeParmType * T,SourceLocation Loc=SourceLocation ())5578a07ba4SRichard Smith     void addUnexpanded(const TemplateTypeParmType *T,
5678a07ba4SRichard Smith                        SourceLocation Loc = SourceLocation()) {
5778a07ba4SRichard Smith       if (T->getDepth() < DepthLimit)
5878a07ba4SRichard Smith         Unexpanded.push_back({T, Loc});
5978a07ba4SRichard Smith     }
602589b980SRichard Smith 
611da294a9SDouglas Gregor   public:
CollectUnexpandedParameterPacksVisitor(SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)621da294a9SDouglas Gregor     explicit CollectUnexpandedParameterPacksVisitor(
630e62c1ccSChris Lattner         SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
6478a07ba4SRichard Smith         : Unexpanded(Unexpanded) {}
651da294a9SDouglas Gregor 
shouldWalkTypesOfTypeLocs() const6615b4ec22SDouglas Gregor     bool shouldWalkTypesOfTypeLocs() const { return false; }
6715b4ec22SDouglas Gregor 
681da294a9SDouglas Gregor     //------------------------------------------------------------------------
691da294a9SDouglas Gregor     // Recording occurrences of (unexpanded) parameter packs.
701da294a9SDouglas Gregor     //------------------------------------------------------------------------
711da294a9SDouglas Gregor 
729fc8faf9SAdrian Prantl     /// Record occurrences of template type parameter packs.
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)731da294a9SDouglas Gregor     bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
741da294a9SDouglas Gregor       if (TL.getTypePtr()->isParameterPack())
7578a07ba4SRichard Smith         addUnexpanded(TL.getTypePtr(), TL.getNameLoc());
761da294a9SDouglas Gregor       return true;
771da294a9SDouglas Gregor     }
781da294a9SDouglas Gregor 
799fc8faf9SAdrian Prantl     /// Record occurrences of template type parameter packs
801da294a9SDouglas Gregor     /// when we don't have proper source-location information for
811da294a9SDouglas Gregor     /// them.
821da294a9SDouglas Gregor     ///
831da294a9SDouglas Gregor     /// Ideally, this routine would never be used.
VisitTemplateTypeParmType(TemplateTypeParmType * T)841da294a9SDouglas Gregor     bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
851da294a9SDouglas Gregor       if (T->isParameterPack())
8678a07ba4SRichard Smith         addUnexpanded(T);
871da294a9SDouglas Gregor 
881da294a9SDouglas Gregor       return true;
891da294a9SDouglas Gregor     }
901da294a9SDouglas Gregor 
919fc8faf9SAdrian Prantl     /// Record occurrences of function and non-type template
92da3cc0d3SDouglas Gregor     /// parameter packs in an expression.
VisitDeclRefExpr(DeclRefExpr * E)93da3cc0d3SDouglas Gregor     bool VisitDeclRefExpr(DeclRefExpr *E) {
94f3010118SDouglas Gregor       if (E->getDecl()->isParameterPack())
9578a07ba4SRichard Smith         addUnexpanded(E->getDecl(), E->getLocation());
96da3cc0d3SDouglas Gregor 
97da3cc0d3SDouglas Gregor       return true;
98da3cc0d3SDouglas Gregor     }
99da3cc0d3SDouglas Gregor 
1009fc8faf9SAdrian Prantl     /// Record occurrences of template template parameter packs.
TraverseTemplateName(TemplateName Template)101f550077eSDouglas Gregor     bool TraverseTemplateName(TemplateName Template) {
10278a07ba4SRichard Smith       if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
10378a07ba4SRichard Smith               Template.getAsTemplateDecl())) {
104f550077eSDouglas Gregor         if (TTP->isParameterPack())
10578a07ba4SRichard Smith           addUnexpanded(TTP);
10678a07ba4SRichard Smith       }
107f550077eSDouglas Gregor 
108f550077eSDouglas Gregor       return inherited::TraverseTemplateName(Template);
109f550077eSDouglas Gregor     }
1101da294a9SDouglas Gregor 
1119fc8faf9SAdrian Prantl     /// Suppress traversal into Objective-C container literal
112e65b086eSTed Kremenek     /// elements that are pack expansions.
TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral * E)113e65b086eSTed Kremenek     bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
114e65b086eSTed Kremenek       if (!E->containsUnexpandedParameterPack())
115e65b086eSTed Kremenek         return true;
116e65b086eSTed Kremenek 
117e65b086eSTed Kremenek       for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
118e65b086eSTed Kremenek         ObjCDictionaryElement Element = E->getKeyValueElement(I);
119e65b086eSTed Kremenek         if (Element.isPackExpansion())
120e65b086eSTed Kremenek           continue;
121e65b086eSTed Kremenek 
122e65b086eSTed Kremenek         TraverseStmt(Element.Key);
123e65b086eSTed Kremenek         TraverseStmt(Element.Value);
124e65b086eSTed Kremenek       }
125e65b086eSTed Kremenek       return true;
126e65b086eSTed Kremenek     }
1271da294a9SDouglas Gregor     //------------------------------------------------------------------------
1281da294a9SDouglas Gregor     // Pruning the search for unexpanded parameter packs.
1291da294a9SDouglas Gregor     //------------------------------------------------------------------------
1301da294a9SDouglas Gregor 
1319fc8faf9SAdrian Prantl     /// Suppress traversal into statements and expressions that
1321da294a9SDouglas Gregor     /// do not contain unexpanded parameter packs.
TraverseStmt(Stmt * S)1331da294a9SDouglas Gregor     bool TraverseStmt(Stmt *S) {
1342589b980SRichard Smith       Expr *E = dyn_cast_or_null<Expr>(S);
1352589b980SRichard Smith       if ((E && E->containsUnexpandedParameterPack()) || InLambda)
1362589b980SRichard Smith         return inherited::TraverseStmt(S);
1371da294a9SDouglas Gregor 
1381da294a9SDouglas Gregor       return true;
1391da294a9SDouglas Gregor     }
1401da294a9SDouglas Gregor 
1419fc8faf9SAdrian Prantl     /// Suppress traversal into types that do not contain
1421da294a9SDouglas Gregor     /// unexpanded parameter packs.
TraverseType(QualType T)1431da294a9SDouglas Gregor     bool TraverseType(QualType T) {
1442589b980SRichard Smith       if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
1451da294a9SDouglas Gregor         return inherited::TraverseType(T);
1461da294a9SDouglas Gregor 
1471da294a9SDouglas Gregor       return true;
1481da294a9SDouglas Gregor     }
1491da294a9SDouglas Gregor 
1509fc8faf9SAdrian Prantl     /// Suppress traversal into types with location information
1511da294a9SDouglas Gregor     /// that do not contain unexpanded parameter packs.
TraverseTypeLoc(TypeLoc TL)1521da294a9SDouglas Gregor     bool TraverseTypeLoc(TypeLoc TL) {
1532589b980SRichard Smith       if ((!TL.getType().isNull() &&
1542589b980SRichard Smith            TL.getType()->containsUnexpandedParameterPack()) ||
1552589b980SRichard Smith           InLambda)
1561da294a9SDouglas Gregor         return inherited::TraverseTypeLoc(TL);
1571da294a9SDouglas Gregor 
1581da294a9SDouglas Gregor       return true;
1591da294a9SDouglas Gregor     }
1601da294a9SDouglas Gregor 
1619fc8faf9SAdrian Prantl     /// Suppress traversal of parameter packs.
TraverseDecl(Decl * D)162a8461bb4SDouglas Gregor     bool TraverseDecl(Decl *D) {
16378a07ba4SRichard Smith       // A function parameter pack is a pack expansion, so cannot contain
164f26d5513SRichard Smith       // an unexpanded parameter pack. Likewise for a template parameter
165f26d5513SRichard Smith       // pack that contains any references to other packs.
1667dda73a2SBrian Gesiak       if (D && D->isParameterPack())
16778a07ba4SRichard Smith         return true;
16878a07ba4SRichard Smith 
169a8461bb4SDouglas Gregor       return inherited::TraverseDecl(D);
170f26d5513SRichard Smith     }
171a8461bb4SDouglas Gregor 
1729fc8faf9SAdrian Prantl     /// Suppress traversal of pack-expanded attributes.
TraverseAttr(Attr * A)173f26d5513SRichard Smith     bool TraverseAttr(Attr *A) {
174f26d5513SRichard Smith       if (A->isPackExpansion())
175a8461bb4SDouglas Gregor         return true;
176f26d5513SRichard Smith 
177f26d5513SRichard Smith       return inherited::TraverseAttr(A);
178f26d5513SRichard Smith     }
179f26d5513SRichard Smith 
1809fc8faf9SAdrian Prantl     /// Suppress traversal of pack expansion expressions and types.
181f26d5513SRichard Smith     ///@{
TraversePackExpansionType(PackExpansionType * T)182f26d5513SRichard Smith     bool TraversePackExpansionType(PackExpansionType *T) { return true; }
TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL)183f26d5513SRichard Smith     bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; }
TraversePackExpansionExpr(PackExpansionExpr * E)184f26d5513SRichard Smith     bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; }
TraverseCXXFoldExpr(CXXFoldExpr * E)185f26d5513SRichard Smith     bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; }
186f26d5513SRichard Smith 
187f26d5513SRichard Smith     ///@}
188f26d5513SRichard Smith 
1899fc8faf9SAdrian Prantl     /// Suppress traversal of using-declaration pack expansion.
TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)190f26d5513SRichard Smith     bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
191f26d5513SRichard Smith       if (D->isPackExpansion())
192f26d5513SRichard Smith         return true;
193f26d5513SRichard Smith 
194f26d5513SRichard Smith       return inherited::TraverseUnresolvedUsingValueDecl(D);
195f26d5513SRichard Smith     }
196f26d5513SRichard Smith 
1979fc8faf9SAdrian Prantl     /// Suppress traversal of using-declaration pack expansion.
TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)198f26d5513SRichard Smith     bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
199f26d5513SRichard Smith       if (D->isPackExpansion())
200f26d5513SRichard Smith         return true;
201f26d5513SRichard Smith 
202f26d5513SRichard Smith       return inherited::TraverseUnresolvedUsingTypenameDecl(D);
203a8461bb4SDouglas Gregor     }
204eb29d18eSDouglas Gregor 
2059fc8faf9SAdrian Prantl     /// Suppress traversal of template argument pack expansions.
TraverseTemplateArgument(const TemplateArgument & Arg)206eb29d18eSDouglas Gregor     bool TraverseTemplateArgument(const TemplateArgument &Arg) {
207eb29d18eSDouglas Gregor       if (Arg.isPackExpansion())
208eb29d18eSDouglas Gregor         return true;
209eb29d18eSDouglas Gregor 
210eb29d18eSDouglas Gregor       return inherited::TraverseTemplateArgument(Arg);
211eb29d18eSDouglas Gregor     }
212eb29d18eSDouglas Gregor 
2139fc8faf9SAdrian Prantl     /// Suppress traversal of template argument pack expansions.
TraverseTemplateArgumentLoc(const TemplateArgumentLoc & ArgLoc)214eb29d18eSDouglas Gregor     bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
215eb29d18eSDouglas Gregor       if (ArgLoc.getArgument().isPackExpansion())
216eb29d18eSDouglas Gregor         return true;
217eb29d18eSDouglas Gregor 
218eb29d18eSDouglas Gregor       return inherited::TraverseTemplateArgumentLoc(ArgLoc);
219eb29d18eSDouglas Gregor     }
2202589b980SRichard Smith 
2219fc8faf9SAdrian Prantl     /// Suppress traversal of base specifier pack expansions.
TraverseCXXBaseSpecifier(const CXXBaseSpecifier & Base)222f26d5513SRichard Smith     bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
223f26d5513SRichard Smith       if (Base.isPackExpansion())
224f26d5513SRichard Smith         return true;
225f26d5513SRichard Smith 
226f26d5513SRichard Smith       return inherited::TraverseCXXBaseSpecifier(Base);
227f26d5513SRichard Smith     }
228f26d5513SRichard Smith 
2299fc8faf9SAdrian Prantl     /// Suppress traversal of mem-initializer pack expansions.
TraverseConstructorInitializer(CXXCtorInitializer * Init)230f26d5513SRichard Smith     bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
231f26d5513SRichard Smith       if (Init->isPackExpansion())
232f26d5513SRichard Smith         return true;
233f26d5513SRichard Smith 
234f26d5513SRichard Smith       return inherited::TraverseConstructorInitializer(Init);
235f26d5513SRichard Smith     }
236f26d5513SRichard Smith 
2379fc8faf9SAdrian Prantl     /// Note whether we're traversing a lambda containing an unexpanded
2382589b980SRichard Smith     /// parameter pack. In this case, the unexpanded pack can occur anywhere,
2392589b980SRichard Smith     /// including all the places where we normally wouldn't look. Within a
2402589b980SRichard Smith     /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
2412589b980SRichard Smith     /// outside an expression.
TraverseLambdaExpr(LambdaExpr * Lambda)2422589b980SRichard Smith     bool TraverseLambdaExpr(LambdaExpr *Lambda) {
2432589b980SRichard Smith       // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
2442589b980SRichard Smith       // even if it's contained within another lambda.
2452589b980SRichard Smith       if (!Lambda->containsUnexpandedParameterPack())
2462589b980SRichard Smith         return true;
2472589b980SRichard Smith 
2482589b980SRichard Smith       bool WasInLambda = InLambda;
24978a07ba4SRichard Smith       unsigned OldDepthLimit = DepthLimit;
2502589b980SRichard Smith 
25178a07ba4SRichard Smith       InLambda = true;
25278a07ba4SRichard Smith       if (auto *TPL = Lambda->getTemplateParameterList())
25378a07ba4SRichard Smith         DepthLimit = TPL->getDepth();
2542589b980SRichard Smith 
2552589b980SRichard Smith       inherited::TraverseLambdaExpr(Lambda);
2562589b980SRichard Smith 
2572589b980SRichard Smith       InLambda = WasInLambda;
25878a07ba4SRichard Smith       DepthLimit = OldDepthLimit;
2592589b980SRichard Smith       return true;
2602589b980SRichard Smith     }
26178a07ba4SRichard Smith 
26278a07ba4SRichard Smith     /// Suppress traversal within pack expansions in lambda captures.
TraverseLambdaCapture(LambdaExpr * Lambda,const LambdaCapture * C,Expr * Init)26378a07ba4SRichard Smith     bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C,
26478a07ba4SRichard Smith                                Expr *Init) {
26578a07ba4SRichard Smith       if (C->isPackExpansion())
26678a07ba4SRichard Smith         return true;
267f26d5513SRichard Smith 
26878a07ba4SRichard Smith       return inherited::TraverseLambdaCapture(Lambda, C, Init);
26978a07ba4SRichard Smith     }
2701da294a9SDouglas Gregor   };
271ab9db510SAlexander Kornienko }
2721da294a9SDouglas Gregor 
2739fc8faf9SAdrian Prantl /// Determine whether it's possible for an unexpanded parameter pack to
27436ee9fb2SRichard Smith /// be valid in this location. This only happens when we're in a declaration
27536ee9fb2SRichard Smith /// that is nested within an expression that could be expanded, such as a
27636ee9fb2SRichard Smith /// lambda-expression within a function call.
27736ee9fb2SRichard Smith ///
27836ee9fb2SRichard Smith /// This is conservatively correct, but may claim that some unexpanded packs are
27936ee9fb2SRichard Smith /// permitted when they are not.
isUnexpandedParameterPackPermitted()28036ee9fb2SRichard Smith bool Sema::isUnexpandedParameterPackPermitted() {
28136ee9fb2SRichard Smith   for (auto *SI : FunctionScopes)
28236ee9fb2SRichard Smith     if (isa<sema::LambdaScopeInfo>(SI))
28336ee9fb2SRichard Smith       return true;
28436ee9fb2SRichard Smith   return false;
28536ee9fb2SRichard Smith }
28636ee9fb2SRichard Smith 
2879fc8faf9SAdrian Prantl /// Diagnose all of the unexpanded parameter packs in the given
2881da294a9SDouglas Gregor /// vector.
2892589b980SRichard Smith bool
DiagnoseUnexpandedParameterPacks(SourceLocation Loc,UnexpandedParameterPackContext UPPC,ArrayRef<UnexpandedParameterPack> Unexpanded)2904a2a8f7fSDouglas Gregor Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
2914a2a8f7fSDouglas Gregor                                        UnexpandedParameterPackContext UPPC,
2928ac06afaSBill Wendling                                  ArrayRef<UnexpandedParameterPack> Unexpanded) {
2934a2a8f7fSDouglas Gregor   if (Unexpanded.empty())
2942589b980SRichard Smith     return false;
2952589b980SRichard Smith 
29678a07ba4SRichard Smith   // If we are within a lambda expression and referencing a pack that is not
297b26bc34eSRichard Smith   // declared within the lambda itself, that lambda contains an unexpanded
2982589b980SRichard Smith   // parameter pack, and we are done.
2992589b980SRichard Smith   // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
3002589b980SRichard Smith   // later.
301f26d5513SRichard Smith   SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences;
302b26bc34eSRichard Smith   if (auto *LSI = getEnclosingLambda()) {
303b2997f57SRichard Smith     for (auto &Pack : Unexpanded) {
304b26bc34eSRichard Smith       auto DeclaresThisPack = [&](NamedDecl *LocalPack) {
305b26bc34eSRichard Smith         if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) {
306b26bc34eSRichard Smith           auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack);
307b26bc34eSRichard Smith           return TTPD && TTPD->getTypeForDecl() == TTPT;
308b26bc34eSRichard Smith         }
309b26bc34eSRichard Smith         return declaresSameEntity(Pack.first.get<NamedDecl *>(), LocalPack);
310b26bc34eSRichard Smith       };
3114bd46501SKazu Hirata       if (llvm::any_of(LSI->LocalPacks, DeclaresThisPack))
312b2997f57SRichard Smith         LambdaParamPackReferences.push_back(Pack);
31378a07ba4SRichard Smith     }
31478a07ba4SRichard Smith 
315b26bc34eSRichard Smith     if (LambdaParamPackReferences.empty()) {
316b26bc34eSRichard Smith       // Construct in lambda only references packs declared outside the lambda.
317b26bc34eSRichard Smith       // That's OK for now, but the lambda itself is considered to contain an
318b26bc34eSRichard Smith       // unexpanded pack in this case, which will require expansion outside the
319b26bc34eSRichard Smith       // lambda.
320b26bc34eSRichard Smith 
321b26bc34eSRichard Smith       // We do not permit pack expansion that would duplicate a statement
322b26bc34eSRichard Smith       // expression, not even within a lambda.
323b26bc34eSRichard Smith       // FIXME: We could probably support this for statement expressions that
324b26bc34eSRichard Smith       // do not contain labels.
325b26bc34eSRichard Smith       // FIXME: This is insufficient to detect this problem; consider
326b26bc34eSRichard Smith       //   f( ({ bad: 0; }) + pack ... );
327b26bc34eSRichard Smith       bool EnclosingStmtExpr = false;
328b26bc34eSRichard Smith       for (unsigned N = FunctionScopes.size(); N; --N) {
329b26bc34eSRichard Smith         sema::FunctionScopeInfo *Func = FunctionScopes[N-1];
3304bd46501SKazu Hirata         if (llvm::any_of(
3314bd46501SKazu Hirata                 Func->CompoundScopes,
332b26bc34eSRichard Smith                 [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) {
333b26bc34eSRichard Smith           EnclosingStmtExpr = true;
334b26bc34eSRichard Smith           break;
335b26bc34eSRichard Smith         }
336b26bc34eSRichard Smith         // Coumpound-statements outside the lambda are OK for now; we'll check
337b26bc34eSRichard Smith         // for those when we finish handling the lambda.
338b26bc34eSRichard Smith         if (Func == LSI)
33978a07ba4SRichard Smith           break;
34078a07ba4SRichard Smith       }
34178a07ba4SRichard Smith 
342b26bc34eSRichard Smith       if (!EnclosingStmtExpr) {
3432589b980SRichard Smith         LSI->ContainsUnexpandedParameterPack = true;
3442589b980SRichard Smith         return false;
3452589b980SRichard Smith       }
346b26bc34eSRichard Smith     } else {
347b26bc34eSRichard Smith       Unexpanded = LambdaParamPackReferences;
348b26bc34eSRichard Smith     }
3492589b980SRichard Smith   }
3504a2a8f7fSDouglas Gregor 
3510e62c1ccSChris Lattner   SmallVector<SourceLocation, 4> Locations;
3520e62c1ccSChris Lattner   SmallVector<IdentifierInfo *, 4> Names;
3531da294a9SDouglas Gregor   llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
3541da294a9SDouglas Gregor 
3551da294a9SDouglas Gregor   for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
356c3ec149bSCraig Topper     IdentifierInfo *Name = nullptr;
3571da294a9SDouglas Gregor     if (const TemplateTypeParmType *TTP
3581da294a9SDouglas Gregor           = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
359dde65ea8SChandler Carruth       Name = TTP->getIdentifier();
3601da294a9SDouglas Gregor     else
3611da294a9SDouglas Gregor       Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
3621da294a9SDouglas Gregor 
36382e95a3cSDavid Blaikie     if (Name && NamesKnown.insert(Name).second)
3641da294a9SDouglas Gregor       Names.push_back(Name);
3651da294a9SDouglas Gregor 
3661da294a9SDouglas Gregor     if (Unexpanded[I].second.isValid())
3671da294a9SDouglas Gregor       Locations.push_back(Unexpanded[I].second);
3681da294a9SDouglas Gregor   }
3691da294a9SDouglas Gregor 
37052bcd691SYaxun (Sam) Liu   auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
3713a8650afSBenjamin Kramer             << (int)UPPC << (int)Names.size();
3723a8650afSBenjamin Kramer   for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)
3733a8650afSBenjamin Kramer     DB << Names[I];
3741da294a9SDouglas Gregor 
3751da294a9SDouglas Gregor   for (unsigned I = 0, N = Locations.size(); I != N; ++I)
3761da294a9SDouglas Gregor     DB << SourceRange(Locations[I]);
3772589b980SRichard Smith   return true;
3781da294a9SDouglas Gregor }
3791da294a9SDouglas Gregor 
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TypeSourceInfo * T,UnexpandedParameterPackContext UPPC)380b55fdf8cSDouglas Gregor bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
381b55fdf8cSDouglas Gregor                                            TypeSourceInfo *T,
382b55fdf8cSDouglas Gregor                                          UnexpandedParameterPackContext UPPC) {
383b55fdf8cSDouglas Gregor   // C++0x [temp.variadic]p5:
384b55fdf8cSDouglas Gregor   //   An appearance of a name of a parameter pack that is not expanded is
385b55fdf8cSDouglas Gregor   //   ill-formed.
386b55fdf8cSDouglas Gregor   if (!T->getType()->containsUnexpandedParameterPack())
387b55fdf8cSDouglas Gregor     return false;
388b55fdf8cSDouglas Gregor 
3890e62c1ccSChris Lattner   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
3901da294a9SDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
3911da294a9SDouglas Gregor                                                               T->getTypeLoc());
3921da294a9SDouglas Gregor   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
3932589b980SRichard Smith   return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
394b55fdf8cSDouglas Gregor }
395b55fdf8cSDouglas Gregor 
DiagnoseUnexpandedParameterPack(Expr * E,UnexpandedParameterPackContext UPPC)396b55fdf8cSDouglas Gregor bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
397b55fdf8cSDouglas Gregor                                         UnexpandedParameterPackContext UPPC) {
398b55fdf8cSDouglas Gregor   // C++0x [temp.variadic]p5:
399b55fdf8cSDouglas Gregor   //   An appearance of a name of a parameter pack that is not expanded is
400b55fdf8cSDouglas Gregor   //   ill-formed.
401b55fdf8cSDouglas Gregor   if (!E->containsUnexpandedParameterPack())
402b55fdf8cSDouglas Gregor     return false;
403b55fdf8cSDouglas Gregor 
4040e62c1ccSChris Lattner   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4051da294a9SDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
4061da294a9SDouglas Gregor   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
407f2ceec48SStephen Kelly   return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
408c4356539SDouglas Gregor }
409c4356539SDouglas Gregor 
DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr * RE)410fb943696SRichard Smith bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
411fb943696SRichard Smith   if (!RE->containsUnexpandedParameterPack())
412fb943696SRichard Smith     return false;
413fb943696SRichard Smith 
414fb943696SRichard Smith   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
415fb943696SRichard Smith   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE);
416fb943696SRichard Smith   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
417fb943696SRichard Smith 
418fb943696SRichard Smith   // We only care about unexpanded references to the RequiresExpr's own
419fb943696SRichard Smith   // parameter packs.
420fb943696SRichard Smith   auto Parms = RE->getLocalParameters();
421fb943696SRichard Smith   llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
422fb943696SRichard Smith   SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
423fb943696SRichard Smith   for (auto Parm : Unexpanded)
424fb943696SRichard Smith     if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl*>()))
425fb943696SRichard Smith       UnexpandedParms.push_back(Parm);
426fb943696SRichard Smith   if (UnexpandedParms.empty())
427fb943696SRichard Smith     return false;
428fb943696SRichard Smith 
429fb943696SRichard Smith   return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement,
430fb943696SRichard Smith                                           UnexpandedParms);
431fb943696SRichard Smith }
432fb943696SRichard Smith 
DiagnoseUnexpandedParameterPack(const CXXScopeSpec & SS,UnexpandedParameterPackContext UPPC)433c4356539SDouglas Gregor bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
434c4356539SDouglas Gregor                                         UnexpandedParameterPackContext UPPC) {
435c4356539SDouglas Gregor   // C++0x [temp.variadic]p5:
436c4356539SDouglas Gregor   //   An appearance of a name of a parameter pack that is not expanded is
437c4356539SDouglas Gregor   //   ill-formed.
438c4356539SDouglas Gregor   if (!SS.getScopeRep() ||
439c4356539SDouglas Gregor       !SS.getScopeRep()->containsUnexpandedParameterPack())
440c4356539SDouglas Gregor     return false;
441c4356539SDouglas Gregor 
4420e62c1ccSChris Lattner   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
443c4356539SDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded)
444c4356539SDouglas Gregor     .TraverseNestedNameSpecifier(SS.getScopeRep());
445c4356539SDouglas Gregor   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4462589b980SRichard Smith   return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
447c4356539SDouglas Gregor                                           UPPC, Unexpanded);
448c4356539SDouglas Gregor }
449c4356539SDouglas Gregor 
DiagnoseUnexpandedParameterPack(const DeclarationNameInfo & NameInfo,UnexpandedParameterPackContext UPPC)450c4356539SDouglas Gregor bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
451c4356539SDouglas Gregor                                          UnexpandedParameterPackContext UPPC) {
452c4356539SDouglas Gregor   // C++0x [temp.variadic]p5:
453c4356539SDouglas Gregor   //   An appearance of a name of a parameter pack that is not expanded is
454c4356539SDouglas Gregor   //   ill-formed.
455c4356539SDouglas Gregor   switch (NameInfo.getName().getNameKind()) {
456c4356539SDouglas Gregor   case DeclarationName::Identifier:
457c4356539SDouglas Gregor   case DeclarationName::ObjCZeroArgSelector:
458c4356539SDouglas Gregor   case DeclarationName::ObjCOneArgSelector:
459c4356539SDouglas Gregor   case DeclarationName::ObjCMultiArgSelector:
460c4356539SDouglas Gregor   case DeclarationName::CXXOperatorName:
461c4356539SDouglas Gregor   case DeclarationName::CXXLiteralOperatorName:
462c4356539SDouglas Gregor   case DeclarationName::CXXUsingDirective:
46335845150SRichard Smith   case DeclarationName::CXXDeductionGuideName:
464c4356539SDouglas Gregor     return false;
465c4356539SDouglas Gregor 
466c4356539SDouglas Gregor   case DeclarationName::CXXConstructorName:
467c4356539SDouglas Gregor   case DeclarationName::CXXDestructorName:
468c4356539SDouglas Gregor   case DeclarationName::CXXConversionFunctionName:
469062ecac8SDouglas Gregor     // FIXME: We shouldn't need this null check!
4706ab34afcSDouglas Gregor     if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
4716ab34afcSDouglas Gregor       return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
4726ab34afcSDouglas Gregor 
4736ab34afcSDouglas Gregor     if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
474c4356539SDouglas Gregor       return false;
4756ab34afcSDouglas Gregor 
476c4356539SDouglas Gregor     break;
477c4356539SDouglas Gregor   }
478c4356539SDouglas Gregor 
4790e62c1ccSChris Lattner   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
480c4356539SDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded)
4816ab34afcSDouglas Gregor     .TraverseType(NameInfo.getName().getCXXNameType());
482c4356539SDouglas Gregor   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4832589b980SRichard Smith   return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
484b55fdf8cSDouglas Gregor }
4856ff1fbf6SDouglas Gregor 
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TemplateName Template,UnexpandedParameterPackContext UPPC)4866ff1fbf6SDouglas Gregor bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
4876ff1fbf6SDouglas Gregor                                            TemplateName Template,
4886ff1fbf6SDouglas Gregor                                        UnexpandedParameterPackContext UPPC) {
4896ff1fbf6SDouglas Gregor 
4906ff1fbf6SDouglas Gregor   if (Template.isNull() || !Template.containsUnexpandedParameterPack())
4916ff1fbf6SDouglas Gregor     return false;
4926ff1fbf6SDouglas Gregor 
4930e62c1ccSChris Lattner   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4946ff1fbf6SDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded)
4956ff1fbf6SDouglas Gregor     .TraverseTemplateName(Template);
4966ff1fbf6SDouglas Gregor   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
4972589b980SRichard Smith   return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
4986ff1fbf6SDouglas Gregor }
4996ff1fbf6SDouglas Gregor 
DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,UnexpandedParameterPackContext UPPC)5001440693cSDouglas Gregor bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
5011440693cSDouglas Gregor                                          UnexpandedParameterPackContext UPPC) {
5021440693cSDouglas Gregor   if (Arg.getArgument().isNull() ||
5031440693cSDouglas Gregor       !Arg.getArgument().containsUnexpandedParameterPack())
5041440693cSDouglas Gregor     return false;
5051440693cSDouglas Gregor 
5060e62c1ccSChris Lattner   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5071440693cSDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5081440693cSDouglas Gregor     .TraverseTemplateArgumentLoc(Arg);
5091440693cSDouglas Gregor   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
5102589b980SRichard Smith   return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
5111440693cSDouglas Gregor }
5121440693cSDouglas Gregor 
collectUnexpandedParameterPacks(TemplateArgument Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)5130f3feb4eSDouglas Gregor void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
5140e62c1ccSChris Lattner                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5150f3feb4eSDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5160f3feb4eSDouglas Gregor     .TraverseTemplateArgument(Arg);
5170f3feb4eSDouglas Gregor }
5180f3feb4eSDouglas Gregor 
collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)519840bd6ccSDouglas Gregor void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
5200e62c1ccSChris Lattner                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
521840bd6ccSDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded)
522840bd6ccSDouglas Gregor     .TraverseTemplateArgumentLoc(Arg);
523840bd6ccSDouglas Gregor }
524840bd6ccSDouglas Gregor 
collectUnexpandedParameterPacks(QualType T,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)52576aca7b2SDouglas Gregor void Sema::collectUnexpandedParameterPacks(QualType T,
5260e62c1ccSChris Lattner                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
52776aca7b2SDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
52876aca7b2SDouglas Gregor }
52976aca7b2SDouglas Gregor 
collectUnexpandedParameterPacks(TypeLoc TL,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)530752a5956SDouglas Gregor void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
5310e62c1ccSChris Lattner                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
532752a5956SDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
533752a5956SDouglas Gregor }
534752a5956SDouglas Gregor 
collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)535151c4568SRichard Smith void Sema::collectUnexpandedParameterPacks(
536151c4568SRichard Smith     NestedNameSpecifierLoc NNS,
5374a2a8f7fSDouglas Gregor     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5384a2a8f7fSDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded)
539151c4568SRichard Smith       .TraverseNestedNameSpecifierLoc(NNS);
5404a2a8f7fSDouglas Gregor }
5414a2a8f7fSDouglas Gregor 
collectUnexpandedParameterPacks(const DeclarationNameInfo & NameInfo,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)542151c4568SRichard Smith void Sema::collectUnexpandedParameterPacks(
543151c4568SRichard Smith     const DeclarationNameInfo &NameInfo,
5444a2a8f7fSDouglas Gregor     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
5454a2a8f7fSDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded)
5464a2a8f7fSDouglas Gregor     .TraverseDeclarationNameInfo(NameInfo);
5474a2a8f7fSDouglas Gregor }
5484a2a8f7fSDouglas Gregor 
5494a2a8f7fSDouglas Gregor 
550d2fa766aSDouglas Gregor ParsedTemplateArgument
ActOnPackExpansion(const ParsedTemplateArgument & Arg,SourceLocation EllipsisLoc)551d2fa766aSDouglas Gregor Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
552d2fa766aSDouglas Gregor                          SourceLocation EllipsisLoc) {
553d2fa766aSDouglas Gregor   if (Arg.isInvalid())
554d2fa766aSDouglas Gregor     return Arg;
555d2fa766aSDouglas Gregor 
556d2fa766aSDouglas Gregor   switch (Arg.getKind()) {
557d2fa766aSDouglas Gregor   case ParsedTemplateArgument::Type: {
558d2fa766aSDouglas Gregor     TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
559d2fa766aSDouglas Gregor     if (Result.isInvalid())
560d2fa766aSDouglas Gregor       return ParsedTemplateArgument();
561d2fa766aSDouglas Gregor 
562d2fa766aSDouglas Gregor     return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
563d2fa766aSDouglas Gregor                                   Arg.getLocation());
564d2fa766aSDouglas Gregor   }
565d2fa766aSDouglas Gregor 
566e8e9dd62SDouglas Gregor   case ParsedTemplateArgument::NonType: {
567e8e9dd62SDouglas Gregor     ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
568e8e9dd62SDouglas Gregor     if (Result.isInvalid())
569d2fa766aSDouglas Gregor       return ParsedTemplateArgument();
570d2fa766aSDouglas Gregor 
571e8e9dd62SDouglas Gregor     return ParsedTemplateArgument(Arg.getKind(), Result.get(),
572e8e9dd62SDouglas Gregor                                   Arg.getLocation());
573e8e9dd62SDouglas Gregor   }
574e8e9dd62SDouglas Gregor 
575d2fa766aSDouglas Gregor   case ParsedTemplateArgument::Template:
576eb29d18eSDouglas Gregor     if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
577eb29d18eSDouglas Gregor       SourceRange R(Arg.getLocation());
578eb29d18eSDouglas Gregor       if (Arg.getScopeSpec().isValid())
579eb29d18eSDouglas Gregor         R.setBegin(Arg.getScopeSpec().getBeginLoc());
580eb29d18eSDouglas Gregor       Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
581eb29d18eSDouglas Gregor         << R;
582d2fa766aSDouglas Gregor       return ParsedTemplateArgument();
583d2fa766aSDouglas Gregor     }
584eb29d18eSDouglas Gregor 
585eb29d18eSDouglas Gregor     return Arg.getTemplatePackExpansion(EllipsisLoc);
586eb29d18eSDouglas Gregor   }
587d2fa766aSDouglas Gregor   llvm_unreachable("Unhandled template argument kind?");
588d2fa766aSDouglas Gregor }
589d2fa766aSDouglas Gregor 
ActOnPackExpansion(ParsedType Type,SourceLocation EllipsisLoc)590d2fa766aSDouglas Gregor TypeResult Sema::ActOnPackExpansion(ParsedType Type,
591d2fa766aSDouglas Gregor                                     SourceLocation EllipsisLoc) {
592d2fa766aSDouglas Gregor   TypeSourceInfo *TSInfo;
593d2fa766aSDouglas Gregor   GetTypeFromParser(Type, &TSInfo);
594d2fa766aSDouglas Gregor   if (!TSInfo)
595d2fa766aSDouglas Gregor     return true;
596d2fa766aSDouglas Gregor 
5977a30dc53SDavid Blaikie   TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None);
598840bd6ccSDouglas Gregor   if (!TSResult)
599840bd6ccSDouglas Gregor     return true;
600840bd6ccSDouglas Gregor 
601840bd6ccSDouglas Gregor   return CreateParsedType(TSResult->getType(), TSResult);
602840bd6ccSDouglas Gregor }
603840bd6ccSDouglas Gregor 
60405785d16SDavid Blaikie TypeSourceInfo *
CheckPackExpansion(TypeSourceInfo * Pattern,SourceLocation EllipsisLoc,Optional<unsigned> NumExpansions)60505785d16SDavid Blaikie Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc,
60605785d16SDavid Blaikie                          Optional<unsigned> NumExpansions) {
607d2fa766aSDouglas Gregor   // Create the pack expansion type and source-location information.
608822d0301SDouglas Gregor   QualType Result = CheckPackExpansion(Pattern->getType(),
609822d0301SDouglas Gregor                                        Pattern->getTypeLoc().getSourceRange(),
6100dca5fdbSDouglas Gregor                                        EllipsisLoc, NumExpansions);
611822d0301SDouglas Gregor   if (Result.isNull())
612c3ec149bSCraig Topper     return nullptr;
613822d0301SDouglas Gregor 
6147152fbe5SEli Friedman   TypeLocBuilder TLB;
6157152fbe5SEli Friedman   TLB.pushFullCopy(Pattern->getTypeLoc());
6167152fbe5SEli Friedman   PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result);
617d2fa766aSDouglas Gregor   TL.setEllipsisLoc(EllipsisLoc);
618d2fa766aSDouglas Gregor 
6197152fbe5SEli Friedman   return TLB.getTypeSourceInfo(Context, Result);
620d2fa766aSDouglas Gregor }
62176aca7b2SDouglas Gregor 
CheckPackExpansion(QualType Pattern,SourceRange PatternRange,SourceLocation EllipsisLoc,Optional<unsigned> NumExpansions)62205785d16SDavid Blaikie QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
6230dca5fdbSDouglas Gregor                                   SourceLocation EllipsisLoc,
62405785d16SDavid Blaikie                                   Optional<unsigned> NumExpansions) {
625b2997f57SRichard Smith   // C++11 [temp.variadic]p5:
626822d0301SDouglas Gregor   //   The pattern of a pack expansion shall name one or more
627822d0301SDouglas Gregor   //   parameter packs that are not expanded by a nested pack
628822d0301SDouglas Gregor   //   expansion.
629b2997f57SRichard Smith   //
630b2997f57SRichard Smith   // A pattern containing a deduced type can't occur "naturally" but arises in
631b2997f57SRichard Smith   // the desugaring of an init-capture pack.
632b2997f57SRichard Smith   if (!Pattern->containsUnexpandedParameterPack() &&
633b2997f57SRichard Smith       !Pattern->getContainedDeducedType()) {
634822d0301SDouglas Gregor     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
635822d0301SDouglas Gregor       << PatternRange;
636822d0301SDouglas Gregor     return QualType();
637822d0301SDouglas Gregor   }
638822d0301SDouglas Gregor 
639740a164dSRichard Smith   return Context.getPackExpansionType(Pattern, NumExpansions,
640740a164dSRichard Smith                                       /*ExpectPackInType=*/false);
641822d0301SDouglas Gregor }
642822d0301SDouglas Gregor 
ActOnPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc)643e8e9dd62SDouglas Gregor ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
6447a30dc53SDavid Blaikie   return CheckPackExpansion(Pattern, EllipsisLoc, None);
645b884000bSDouglas Gregor }
646b884000bSDouglas Gregor 
CheckPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc,Optional<unsigned> NumExpansions)647b884000bSDouglas Gregor ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
64805785d16SDavid Blaikie                                     Optional<unsigned> NumExpansions) {
649e8e9dd62SDouglas Gregor   if (!Pattern)
650e8e9dd62SDouglas Gregor     return ExprError();
651e8e9dd62SDouglas Gregor 
652e8e9dd62SDouglas Gregor   // C++0x [temp.variadic]p5:
653e8e9dd62SDouglas Gregor   //   The pattern of a pack expansion shall name one or more
654e8e9dd62SDouglas Gregor   //   parameter packs that are not expanded by a nested pack
655e8e9dd62SDouglas Gregor   //   expansion.
656e8e9dd62SDouglas Gregor   if (!Pattern->containsUnexpandedParameterPack()) {
657e8e9dd62SDouglas Gregor     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
658e8e9dd62SDouglas Gregor     << Pattern->getSourceRange();
6590afffab0SSam McCall     CorrectDelayedTyposInExpr(Pattern);
660e8e9dd62SDouglas Gregor     return ExprError();
661e8e9dd62SDouglas Gregor   }
662e8e9dd62SDouglas Gregor 
663e8e9dd62SDouglas Gregor   // Create the pack expansion expression and source-location information.
66403ff2596SNikola Smiljanic   return new (Context)
66503ff2596SNikola Smiljanic     PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
666e8e9dd62SDouglas Gregor }
66776aca7b2SDouglas Gregor 
CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,SourceRange PatternRange,ArrayRef<UnexpandedParameterPack> Unexpanded,const MultiLevelTemplateArgumentList & TemplateArgs,bool & ShouldExpand,bool & RetainExpansion,Optional<unsigned> & NumExpansions)66805785d16SDavid Blaikie bool Sema::CheckParameterPacksForExpansion(
66905785d16SDavid Blaikie     SourceLocation EllipsisLoc, SourceRange PatternRange,
670b9c168a2SDavid Blaikie     ArrayRef<UnexpandedParameterPack> Unexpanded,
67105785d16SDavid Blaikie     const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
67205785d16SDavid Blaikie     bool &RetainExpansion, Optional<unsigned> &NumExpansions) {
67376aca7b2SDouglas Gregor   ShouldExpand = true;
674a8bac7f5SDouglas Gregor   RetainExpansion = false;
67576aca7b2SDouglas Gregor   std::pair<IdentifierInfo *, SourceLocation> FirstPack;
67676aca7b2SDouglas Gregor   bool HaveFirstPack = false;
6774a8f3518SRichard Smith   Optional<unsigned> NumPartialExpansions;
6784a8f3518SRichard Smith   SourceLocation PartiallySubstitutedPackLoc;
67976aca7b2SDouglas Gregor 
680*3b3dd76dSJun Zhang   for (UnexpandedParameterPack ParmPack : Unexpanded) {
68176aca7b2SDouglas Gregor     // Compute the depth and index for this parameter pack.
682582a0999STed Kremenek     unsigned Depth = 0, Index = 0;
68376aca7b2SDouglas Gregor     IdentifierInfo *Name;
684b2997f57SRichard Smith     bool IsVarDeclPack = false;
68576aca7b2SDouglas Gregor 
686*3b3dd76dSJun Zhang     if (const TemplateTypeParmType *TTP =
687*3b3dd76dSJun Zhang             ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
68876aca7b2SDouglas Gregor       Depth = TTP->getDepth();
68976aca7b2SDouglas Gregor       Index = TTP->getIndex();
690dde65ea8SChandler Carruth       Name = TTP->getIdentifier();
69176aca7b2SDouglas Gregor     } else {
692*3b3dd76dSJun Zhang       NamedDecl *ND = ParmPack.first.get<NamedDecl *>();
693b2997f57SRichard Smith       if (isa<VarDecl>(ND))
694b2997f57SRichard Smith         IsVarDeclPack = true;
695a8bac7f5SDouglas Gregor       else
696867ea1d4SBenjamin Kramer         std::tie(Depth, Index) = getDepthAndIndex(ND);
697a8bac7f5SDouglas Gregor 
69876aca7b2SDouglas Gregor       Name = ND->getIdentifier();
69976aca7b2SDouglas Gregor     }
70076aca7b2SDouglas Gregor 
701f3010118SDouglas Gregor     // Determine the size of this argument pack.
702f3010118SDouglas Gregor     unsigned NewPackSize;
703b2997f57SRichard Smith     if (IsVarDeclPack) {
704f3010118SDouglas Gregor       // Figure out whether we're instantiating to an argument pack or not.
705f3010118SDouglas Gregor       typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
706f3010118SDouglas Gregor 
707*3b3dd76dSJun Zhang       llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
708*3b3dd76dSJun Zhang           CurrentInstantiationScope->findInstantiationOf(
709*3b3dd76dSJun Zhang               ParmPack.first.get<NamedDecl *>());
71015a776ffSChris Lattner       if (Instantiation->is<DeclArgumentPack *>()) {
711f3010118SDouglas Gregor         // We could expand this function parameter pack.
712f3010118SDouglas Gregor         NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
713f3010118SDouglas Gregor       } else {
714f3010118SDouglas Gregor         // We can't expand this function parameter pack, so we can't expand
715f3010118SDouglas Gregor         // the pack expansion.
716f3010118SDouglas Gregor         ShouldExpand = false;
717f3010118SDouglas Gregor         continue;
718f3010118SDouglas Gregor       }
719f3010118SDouglas Gregor     } else {
72076aca7b2SDouglas Gregor       // If we don't have a template argument at this depth/index, then we
72176aca7b2SDouglas Gregor       // cannot expand the pack expansion. Make a note of this, but we still
722eb5a39deSDouglas Gregor       // want to check any parameter packs we *do* have arguments for.
72398318c22SDouglas Gregor       if (Depth >= TemplateArgs.getNumLevels() ||
72498318c22SDouglas Gregor           !TemplateArgs.hasTemplateArgument(Depth, Index)) {
72576aca7b2SDouglas Gregor         ShouldExpand = false;
72676aca7b2SDouglas Gregor         continue;
72776aca7b2SDouglas Gregor       }
72876aca7b2SDouglas Gregor 
72976aca7b2SDouglas Gregor       // Determine the size of the argument pack.
730f3010118SDouglas Gregor       NewPackSize = TemplateArgs(Depth, Index).pack_size();
731f3010118SDouglas Gregor     }
732f3010118SDouglas Gregor 
733a8bac7f5SDouglas Gregor     // C++0x [temp.arg.explicit]p9:
734a8bac7f5SDouglas Gregor     //   Template argument deduction can extend the sequence of template
735a8bac7f5SDouglas Gregor     //   arguments corresponding to a template parameter pack, even when the
736a8bac7f5SDouglas Gregor     //   sequence contains explicitly specified template arguments.
737b2997f57SRichard Smith     if (!IsVarDeclPack && CurrentInstantiationScope) {
738a8bac7f5SDouglas Gregor       if (NamedDecl *PartialPack
739a8bac7f5SDouglas Gregor                     = CurrentInstantiationScope->getPartiallySubstitutedPack()){
740a8bac7f5SDouglas Gregor         unsigned PartialDepth, PartialIndex;
741867ea1d4SBenjamin Kramer         std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
7424a8f3518SRichard Smith         if (PartialDepth == Depth && PartialIndex == Index) {
743a8bac7f5SDouglas Gregor           RetainExpansion = true;
7444a8f3518SRichard Smith           // We don't actually know the new pack size yet.
7454a8f3518SRichard Smith           NumPartialExpansions = NewPackSize;
746*3b3dd76dSJun Zhang           PartiallySubstitutedPackLoc = ParmPack.second;
7474a8f3518SRichard Smith           continue;
7484a8f3518SRichard Smith         }
749a8bac7f5SDouglas Gregor       }
75063dad4d8SDouglas Gregor     }
751a8bac7f5SDouglas Gregor 
7520dca5fdbSDouglas Gregor     if (!NumExpansions) {
75376aca7b2SDouglas Gregor       // The is the first pack we've seen for which we have an argument.
75476aca7b2SDouglas Gregor       // Record it.
75576aca7b2SDouglas Gregor       NumExpansions = NewPackSize;
75676aca7b2SDouglas Gregor       FirstPack.first = Name;
757*3b3dd76dSJun Zhang       FirstPack.second = ParmPack.second;
75876aca7b2SDouglas Gregor       HaveFirstPack = true;
75976aca7b2SDouglas Gregor       continue;
76076aca7b2SDouglas Gregor     }
76176aca7b2SDouglas Gregor 
7620dca5fdbSDouglas Gregor     if (NewPackSize != *NumExpansions) {
76376aca7b2SDouglas Gregor       // C++0x [temp.variadic]p5:
76476aca7b2SDouglas Gregor       //   All of the parameter packs expanded by a pack expansion shall have
76576aca7b2SDouglas Gregor       //   the same number of arguments specified.
7660dca5fdbSDouglas Gregor       if (HaveFirstPack)
76776aca7b2SDouglas Gregor         Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
7680dca5fdbSDouglas Gregor             << FirstPack.first << Name << *NumExpansions << NewPackSize
769*3b3dd76dSJun Zhang             << SourceRange(FirstPack.second) << SourceRange(ParmPack.second);
7700dca5fdbSDouglas Gregor       else
7710dca5fdbSDouglas Gregor         Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
7720dca5fdbSDouglas Gregor             << Name << *NumExpansions << NewPackSize
773*3b3dd76dSJun Zhang             << SourceRange(ParmPack.second);
77476aca7b2SDouglas Gregor       return true;
77576aca7b2SDouglas Gregor     }
77676aca7b2SDouglas Gregor   }
77776aca7b2SDouglas Gregor 
7784a8f3518SRichard Smith   // If we're performing a partial expansion but we also have a full expansion,
7794a8f3518SRichard Smith   // expand to the number of common arguments. For example, given:
7804a8f3518SRichard Smith   //
7814a8f3518SRichard Smith   //   template<typename ...T> struct A {
7824a8f3518SRichard Smith   //     template<typename ...U> void f(pair<T, U>...);
7834a8f3518SRichard Smith   //   };
7844a8f3518SRichard Smith   //
7854a8f3518SRichard Smith   // ... a call to 'A<int, int>().f<int>' should expand the pack once and
7864a8f3518SRichard Smith   // retain an expansion.
7874a8f3518SRichard Smith   if (NumPartialExpansions) {
7884a8f3518SRichard Smith     if (NumExpansions && *NumExpansions < *NumPartialExpansions) {
7894a8f3518SRichard Smith       NamedDecl *PartialPack =
7904a8f3518SRichard Smith           CurrentInstantiationScope->getPartiallySubstitutedPack();
7914a8f3518SRichard Smith       Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial)
7924a8f3518SRichard Smith         << PartialPack << *NumPartialExpansions << *NumExpansions
7934a8f3518SRichard Smith         << SourceRange(PartiallySubstitutedPackLoc);
7944a8f3518SRichard Smith       return true;
7954a8f3518SRichard Smith     }
7964a8f3518SRichard Smith 
7974a8f3518SRichard Smith     NumExpansions = NumPartialExpansions;
7984a8f3518SRichard Smith   }
7994a8f3518SRichard Smith 
80076aca7b2SDouglas Gregor   return false;
80176aca7b2SDouglas Gregor }
80227b4c16fSDouglas Gregor 
getNumArgumentsInExpansion(QualType T,const MultiLevelTemplateArgumentList & TemplateArgs)80305785d16SDavid Blaikie Optional<unsigned> Sema::getNumArgumentsInExpansion(QualType T,
8045cde386eSDouglas Gregor                           const MultiLevelTemplateArgumentList &TemplateArgs) {
8055cde386eSDouglas Gregor   QualType Pattern = cast<PackExpansionType>(T)->getPattern();
8060e62c1ccSChris Lattner   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8075cde386eSDouglas Gregor   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
8085cde386eSDouglas Gregor 
80905785d16SDavid Blaikie   Optional<unsigned> Result;
8105cde386eSDouglas Gregor   for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
8115cde386eSDouglas Gregor     // Compute the depth and index for this parameter pack.
8125cde386eSDouglas Gregor     unsigned Depth;
8135cde386eSDouglas Gregor     unsigned Index;
8145cde386eSDouglas Gregor 
8155cde386eSDouglas Gregor     if (const TemplateTypeParmType *TTP
8165cde386eSDouglas Gregor           = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
8175cde386eSDouglas Gregor       Depth = TTP->getDepth();
8185cde386eSDouglas Gregor       Index = TTP->getIndex();
8195cde386eSDouglas Gregor     } else {
8205cde386eSDouglas Gregor       NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
821b2997f57SRichard Smith       if (isa<VarDecl>(ND)) {
822b2997f57SRichard Smith         // Function parameter pack or init-capture pack.
8235cde386eSDouglas Gregor         typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
8245cde386eSDouglas Gregor 
8255cde386eSDouglas Gregor         llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
8265cde386eSDouglas Gregor           = CurrentInstantiationScope->findInstantiationOf(
8275cde386eSDouglas Gregor                                         Unexpanded[I].first.get<NamedDecl *>());
828198223b7SRichard Smith         if (Instantiation->is<Decl*>())
829198223b7SRichard Smith           // The pattern refers to an unexpanded pack. We're not ready to expand
830198223b7SRichard Smith           // this pack yet.
8317a30dc53SDavid Blaikie           return None;
8325cde386eSDouglas Gregor 
833198223b7SRichard Smith         unsigned Size = Instantiation->get<DeclArgumentPack *>()->size();
834198223b7SRichard Smith         assert((!Result || *Result == Size) && "inconsistent pack sizes");
835198223b7SRichard Smith         Result = Size;
8365cde386eSDouglas Gregor         continue;
8375cde386eSDouglas Gregor       }
8385cde386eSDouglas Gregor 
839867ea1d4SBenjamin Kramer       std::tie(Depth, Index) = getDepthAndIndex(ND);
8405cde386eSDouglas Gregor     }
8415cde386eSDouglas Gregor     if (Depth >= TemplateArgs.getNumLevels() ||
8425cde386eSDouglas Gregor         !TemplateArgs.hasTemplateArgument(Depth, Index))
843198223b7SRichard Smith       // The pattern refers to an unknown template argument. We're not ready to
844198223b7SRichard Smith       // expand this pack yet.
8457a30dc53SDavid Blaikie       return None;
8465cde386eSDouglas Gregor 
8475cde386eSDouglas Gregor     // Determine the size of the argument pack.
848198223b7SRichard Smith     unsigned Size = TemplateArgs(Depth, Index).pack_size();
849198223b7SRichard Smith     assert((!Result || *Result == Size) && "inconsistent pack sizes");
850198223b7SRichard Smith     Result = Size;
8515cde386eSDouglas Gregor   }
8525cde386eSDouglas Gregor 
853198223b7SRichard Smith   return Result;
8545cde386eSDouglas Gregor }
8555cde386eSDouglas Gregor 
containsUnexpandedParameterPacks(Declarator & D)85627b4c16fSDouglas Gregor bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
85727b4c16fSDouglas Gregor   const DeclSpec &DS = D.getDeclSpec();
85827b4c16fSDouglas Gregor   switch (DS.getTypeSpecType()) {
859090da2d1SFaisal Vali   case TST_typename:
860090da2d1SFaisal Vali   case TST_typeofType:
861090da2d1SFaisal Vali   case TST_underlyingType:
862090da2d1SFaisal Vali   case TST_atomic: {
86327b4c16fSDouglas Gregor     QualType T = DS.getRepAsType().get();
86427b4c16fSDouglas Gregor     if (!T.isNull() && T->containsUnexpandedParameterPack())
86527b4c16fSDouglas Gregor       return true;
86627b4c16fSDouglas Gregor     break;
86727b4c16fSDouglas Gregor   }
86827b4c16fSDouglas Gregor 
869090da2d1SFaisal Vali   case TST_typeofExpr:
870090da2d1SFaisal Vali   case TST_decltype:
8716c75ab5fSAaron Ballman   case TST_bitint:
87227b4c16fSDouglas Gregor     if (DS.getRepAsExpr() &&
87327b4c16fSDouglas Gregor         DS.getRepAsExpr()->containsUnexpandedParameterPack())
87427b4c16fSDouglas Gregor       return true;
87527b4c16fSDouglas Gregor     break;
87627b4c16fSDouglas Gregor 
877090da2d1SFaisal Vali   case TST_unspecified:
878090da2d1SFaisal Vali   case TST_void:
879090da2d1SFaisal Vali   case TST_char:
880090da2d1SFaisal Vali   case TST_wchar:
8813a8244dfSRichard Smith   case TST_char8:
882090da2d1SFaisal Vali   case TST_char16:
883090da2d1SFaisal Vali   case TST_char32:
884090da2d1SFaisal Vali   case TST_int:
885090da2d1SFaisal Vali   case TST_int128:
886090da2d1SFaisal Vali   case TST_half:
887090da2d1SFaisal Vali   case TST_float:
888090da2d1SFaisal Vali   case TST_double:
889f921d854SLeonard Chan   case TST_Accum:
890ab80f3c8SLeonard Chan   case TST_Fract:
891090da2d1SFaisal Vali   case TST_Float16:
892090da2d1SFaisal Vali   case TST_float128:
893fae0dfa6SQiu Chaofan   case TST_ibm128:
894090da2d1SFaisal Vali   case TST_bool:
895090da2d1SFaisal Vali   case TST_decimal32:
896090da2d1SFaisal Vali   case TST_decimal64:
897090da2d1SFaisal Vali   case TST_decimal128:
898090da2d1SFaisal Vali   case TST_enum:
899090da2d1SFaisal Vali   case TST_union:
900090da2d1SFaisal Vali   case TST_struct:
901090da2d1SFaisal Vali   case TST_interface:
902090da2d1SFaisal Vali   case TST_class:
903090da2d1SFaisal Vali   case TST_auto:
904090da2d1SFaisal Vali   case TST_auto_type:
905090da2d1SFaisal Vali   case TST_decltype_auto:
906ecd682bbSTies Stuij   case TST_BFloat16:
907090da2d1SFaisal Vali #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:
908b62f1440SAlexey Bader #include "clang/Basic/OpenCLImageTypes.def"
909090da2d1SFaisal Vali   case TST_unknown_anytype:
910090da2d1SFaisal Vali   case TST_error:
91127b4c16fSDouglas Gregor     break;
91227b4c16fSDouglas Gregor   }
91327b4c16fSDouglas Gregor 
91427b4c16fSDouglas Gregor   for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
91527b4c16fSDouglas Gregor     const DeclaratorChunk &Chunk = D.getTypeObject(I);
91627b4c16fSDouglas Gregor     switch (Chunk.Kind) {
91727b4c16fSDouglas Gregor     case DeclaratorChunk::Pointer:
91827b4c16fSDouglas Gregor     case DeclaratorChunk::Reference:
91927b4c16fSDouglas Gregor     case DeclaratorChunk::Paren:
9209c14e282SXiuli Pan     case DeclaratorChunk::Pipe:
9212e846507SLarisse Voufo     case DeclaratorChunk::BlockPointer:
92227b4c16fSDouglas Gregor       // These declarator chunks cannot contain any parameter packs.
92327b4c16fSDouglas Gregor       break;
92427b4c16fSDouglas Gregor 
92527b4c16fSDouglas Gregor     case DeclaratorChunk::Array:
9262e846507SLarisse Voufo       if (Chunk.Arr.NumElts &&
9272e846507SLarisse Voufo           Chunk.Arr.NumElts->containsUnexpandedParameterPack())
9282e846507SLarisse Voufo         return true;
9292e846507SLarisse Voufo       break;
93027b4c16fSDouglas Gregor     case DeclaratorChunk::Function:
9312e846507SLarisse Voufo       for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) {
9322e846507SLarisse Voufo         ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param);
9332e846507SLarisse Voufo         QualType ParamTy = Param->getType();
9342e846507SLarisse Voufo         assert(!ParamTy.isNull() && "Couldn't parse type?");
9352e846507SLarisse Voufo         if (ParamTy->containsUnexpandedParameterPack()) return true;
9362e846507SLarisse Voufo       }
9372e846507SLarisse Voufo 
9382e846507SLarisse Voufo       if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) {
939078aea90SReid Kleckner         for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) {
9402e846507SLarisse Voufo           if (Chunk.Fun.Exceptions[i]
9412e846507SLarisse Voufo                   .Ty.get()
9422e846507SLarisse Voufo                   ->containsUnexpandedParameterPack())
9432e846507SLarisse Voufo             return true;
9442e846507SLarisse Voufo         }
945eaf11ad7SRichard Smith       } else if (isComputedNoexcept(Chunk.Fun.getExceptionSpecType()) &&
9462e846507SLarisse Voufo                  Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack())
9472e846507SLarisse Voufo         return true;
9482e846507SLarisse Voufo 
9498d26b72aSNico Weber       if (Chunk.Fun.hasTrailingReturnType()) {
9508d26b72aSNico Weber         QualType T = Chunk.Fun.getTrailingReturnType().get();
9518d26b72aSNico Weber         if (!T.isNull() && T->containsUnexpandedParameterPack())
9522e846507SLarisse Voufo           return true;
9538d26b72aSNico Weber       }
9542e846507SLarisse Voufo       break;
95527b4c16fSDouglas Gregor 
95627b4c16fSDouglas Gregor     case DeclaratorChunk::MemberPointer:
95727b4c16fSDouglas Gregor       if (Chunk.Mem.Scope().getScopeRep() &&
95827b4c16fSDouglas Gregor           Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
95927b4c16fSDouglas Gregor         return true;
96027b4c16fSDouglas Gregor       break;
96127b4c16fSDouglas Gregor     }
96227b4c16fSDouglas Gregor   }
96327b4c16fSDouglas Gregor 
964b65b1f32SSaar Raz   if (Expr *TRC = D.getTrailingRequiresClause())
965b65b1f32SSaar Raz     if (TRC->containsUnexpandedParameterPack())
966b65b1f32SSaar Raz       return true;
967b65b1f32SSaar Raz 
96827b4c16fSDouglas Gregor   return false;
96927b4c16fSDouglas Gregor }
970820ba7baSDouglas Gregor 
971637b5b32SKaelyn Uhrain namespace {
972637b5b32SKaelyn Uhrain 
973637b5b32SKaelyn Uhrain // Callback to only accept typo corrections that refer to parameter packs.
97470ad396bSBruno Ricci class ParameterPackValidatorCCC final : public CorrectionCandidateCallback {
975637b5b32SKaelyn Uhrain  public:
ValidateCandidate(const TypoCorrection & candidate)976e14c0f8eSCraig Topper   bool ValidateCandidate(const TypoCorrection &candidate) override {
977637b5b32SKaelyn Uhrain     NamedDecl *ND = candidate.getCorrectionDecl();
978637b5b32SKaelyn Uhrain     return ND && ND->isParameterPack();
979637b5b32SKaelyn Uhrain   }
98070ad396bSBruno Ricci 
clone()98170ad396bSBruno Ricci   std::unique_ptr<CorrectionCandidateCallback> clone() override {
9822b3d49b6SJonas Devlieghere     return std::make_unique<ParameterPackValidatorCCC>(*this);
98370ad396bSBruno Ricci   }
984637b5b32SKaelyn Uhrain };
985637b5b32SKaelyn Uhrain 
986ab9db510SAlexander Kornienko }
987637b5b32SKaelyn Uhrain 
9889fc8faf9SAdrian Prantl /// Called when an expression computing the size of a parameter pack
989820ba7baSDouglas Gregor /// is parsed.
990820ba7baSDouglas Gregor ///
991820ba7baSDouglas Gregor /// \code
992820ba7baSDouglas Gregor /// template<typename ...Types> struct count {
993820ba7baSDouglas Gregor ///   static const unsigned value = sizeof...(Types);
994820ba7baSDouglas Gregor /// };
995820ba7baSDouglas Gregor /// \endcode
996820ba7baSDouglas Gregor ///
997820ba7baSDouglas Gregor //
998820ba7baSDouglas Gregor /// \param OpLoc The location of the "sizeof" keyword.
999820ba7baSDouglas Gregor /// \param Name The name of the parameter pack whose size will be determined.
1000820ba7baSDouglas Gregor /// \param NameLoc The source location of the name of the parameter pack.
1001820ba7baSDouglas Gregor /// \param RParenLoc The location of the closing parentheses.
ActOnSizeofParameterPackExpr(Scope * S,SourceLocation OpLoc,IdentifierInfo & Name,SourceLocation NameLoc,SourceLocation RParenLoc)1002820ba7baSDouglas Gregor ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
1003820ba7baSDouglas Gregor                                               SourceLocation OpLoc,
1004820ba7baSDouglas Gregor                                               IdentifierInfo &Name,
1005820ba7baSDouglas Gregor                                               SourceLocation NameLoc,
1006820ba7baSDouglas Gregor                                               SourceLocation RParenLoc) {
1007820ba7baSDouglas Gregor   // C++0x [expr.sizeof]p5:
1008820ba7baSDouglas Gregor   //   The identifier in a sizeof... expression shall name a parameter pack.
1009820ba7baSDouglas Gregor   LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
1010820ba7baSDouglas Gregor   LookupName(R, S);
1011820ba7baSDouglas Gregor 
1012c3ec149bSCraig Topper   NamedDecl *ParameterPack = nullptr;
1013820ba7baSDouglas Gregor   switch (R.getResultKind()) {
1014820ba7baSDouglas Gregor   case LookupResult::Found:
1015820ba7baSDouglas Gregor     ParameterPack = R.getFoundDecl();
1016820ba7baSDouglas Gregor     break;
1017820ba7baSDouglas Gregor 
1018820ba7baSDouglas Gregor   case LookupResult::NotFound:
101970ad396bSBruno Ricci   case LookupResult::NotFoundInCurrentInstantiation: {
102070ad396bSBruno Ricci     ParameterPackValidatorCCC CCC{};
102189c881b5SKaelyn Takata     if (TypoCorrection Corrected =
102289c881b5SKaelyn Takata             CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr,
102370ad396bSBruno Ricci                         CCC, CTK_ErrorRecovery)) {
1024f9b15105SRichard Smith       diagnoseTypo(Corrected,
1025f9b15105SRichard Smith                    PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,
1026f9b15105SRichard Smith                    PDiag(diag::note_parameter_pack_here));
1027637b5b32SKaelyn Uhrain       ParameterPack = Corrected.getCorrectionDecl();
1028820ba7baSDouglas Gregor     }
10294dc0b1acSReid Kleckner     break;
103070ad396bSBruno Ricci   }
1031820ba7baSDouglas Gregor   case LookupResult::FoundOverloaded:
1032820ba7baSDouglas Gregor   case LookupResult::FoundUnresolvedValue:
1033820ba7baSDouglas Gregor     break;
1034820ba7baSDouglas Gregor 
1035820ba7baSDouglas Gregor   case LookupResult::Ambiguous:
1036820ba7baSDouglas Gregor     DiagnoseAmbiguousLookup(R);
1037820ba7baSDouglas Gregor     return ExprError();
1038820ba7baSDouglas Gregor   }
1039820ba7baSDouglas Gregor 
10403c6bd2adSDouglas Gregor   if (!ParameterPack || !ParameterPack->isParameterPack()) {
1041820ba7baSDouglas Gregor     Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
1042820ba7baSDouglas Gregor       << &Name;
1043820ba7baSDouglas Gregor     return ExprError();
1044820ba7baSDouglas Gregor   }
1045820ba7baSDouglas Gregor 
104645b50528SNick Lewycky   MarkAnyDeclReferenced(OpLoc, ParameterPack, true);
104723b1be99SEli Friedman 
1048d784e689SRichard Smith   return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc,
1049d784e689SRichard Smith                                 RParenLoc);
1050820ba7baSDouglas Gregor }
105194e9eaa4SEli Friedman 
105294e9eaa4SEli Friedman TemplateArgumentLoc
getTemplateArgumentPackExpansionPattern(TemplateArgumentLoc OrigLoc,SourceLocation & Ellipsis,Optional<unsigned> & NumExpansions) const105394e9eaa4SEli Friedman Sema::getTemplateArgumentPackExpansionPattern(
105494e9eaa4SEli Friedman       TemplateArgumentLoc OrigLoc,
105594e9eaa4SEli Friedman       SourceLocation &Ellipsis, Optional<unsigned> &NumExpansions) const {
105694e9eaa4SEli Friedman   const TemplateArgument &Argument = OrigLoc.getArgument();
105794e9eaa4SEli Friedman   assert(Argument.isPackExpansion());
105894e9eaa4SEli Friedman   switch (Argument.getKind()) {
105994e9eaa4SEli Friedman   case TemplateArgument::Type: {
106094e9eaa4SEli Friedman     // FIXME: We shouldn't ever have to worry about missing
106194e9eaa4SEli Friedman     // type-source info!
106294e9eaa4SEli Friedman     TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo();
106394e9eaa4SEli Friedman     if (!ExpansionTSInfo)
106494e9eaa4SEli Friedman       ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(),
106594e9eaa4SEli Friedman                                                          Ellipsis);
106694e9eaa4SEli Friedman     PackExpansionTypeLoc Expansion =
106794e9eaa4SEli Friedman         ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>();
106894e9eaa4SEli Friedman     Ellipsis = Expansion.getEllipsisLoc();
106994e9eaa4SEli Friedman 
107094e9eaa4SEli Friedman     TypeLoc Pattern = Expansion.getPatternLoc();
107194e9eaa4SEli Friedman     NumExpansions = Expansion.getTypePtr()->getNumExpansions();
107294e9eaa4SEli Friedman 
107394e9eaa4SEli Friedman     // We need to copy the TypeLoc because TemplateArgumentLocs store a
107494e9eaa4SEli Friedman     // TypeSourceInfo.
107594e9eaa4SEli Friedman     // FIXME: Find some way to avoid the copy?
107694e9eaa4SEli Friedman     TypeLocBuilder TLB;
107794e9eaa4SEli Friedman     TLB.pushFullCopy(Pattern);
107894e9eaa4SEli Friedman     TypeSourceInfo *PatternTSInfo =
107994e9eaa4SEli Friedman         TLB.getTypeSourceInfo(Context, Pattern.getType());
108094e9eaa4SEli Friedman     return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
108194e9eaa4SEli Friedman                                PatternTSInfo);
108294e9eaa4SEli Friedman   }
108394e9eaa4SEli Friedman 
108494e9eaa4SEli Friedman   case TemplateArgument::Expression: {
108594e9eaa4SEli Friedman     PackExpansionExpr *Expansion
108694e9eaa4SEli Friedman       = cast<PackExpansionExpr>(Argument.getAsExpr());
108794e9eaa4SEli Friedman     Expr *Pattern = Expansion->getPattern();
108894e9eaa4SEli Friedman     Ellipsis = Expansion->getEllipsisLoc();
108994e9eaa4SEli Friedman     NumExpansions = Expansion->getNumExpansions();
109094e9eaa4SEli Friedman     return TemplateArgumentLoc(Pattern, Pattern);
109194e9eaa4SEli Friedman   }
109294e9eaa4SEli Friedman 
109394e9eaa4SEli Friedman   case TemplateArgument::TemplateExpansion:
109494e9eaa4SEli Friedman     Ellipsis = OrigLoc.getTemplateEllipsisLoc();
109594e9eaa4SEli Friedman     NumExpansions = Argument.getNumTemplateExpansions();
1096af295916SHaojian Wu     return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(),
109794e9eaa4SEli Friedman                                OrigLoc.getTemplateQualifierLoc(),
109894e9eaa4SEli Friedman                                OrigLoc.getTemplateNameLoc());
109994e9eaa4SEli Friedman 
110094e9eaa4SEli Friedman   case TemplateArgument::Declaration:
110194e9eaa4SEli Friedman   case TemplateArgument::NullPtr:
110294e9eaa4SEli Friedman   case TemplateArgument::Template:
110394e9eaa4SEli Friedman   case TemplateArgument::Integral:
110494e9eaa4SEli Friedman   case TemplateArgument::Pack:
110594e9eaa4SEli Friedman   case TemplateArgument::Null:
110694e9eaa4SEli Friedman     return TemplateArgumentLoc();
110794e9eaa4SEli Friedman   }
110894e9eaa4SEli Friedman 
110994e9eaa4SEli Friedman   llvm_unreachable("Invalid TemplateArgument Kind!");
1110c5452ed9SRichard Smith }
1111c5452ed9SRichard Smith 
getFullyPackExpandedSize(TemplateArgument Arg)1112c5452ed9SRichard Smith Optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
1113c5452ed9SRichard Smith   assert(Arg.containsUnexpandedParameterPack());
1114c5452ed9SRichard Smith 
1115c5452ed9SRichard Smith   // If this is a substituted pack, grab that pack. If not, we don't know
1116c5452ed9SRichard Smith   // the size yet.
1117c5452ed9SRichard Smith   // FIXME: We could find a size in more cases by looking for a substituted
1118c5452ed9SRichard Smith   // pack anywhere within this argument, but that's not necessary in the common
1119c5452ed9SRichard Smith   // case for 'sizeof...(A)' handling.
1120c5452ed9SRichard Smith   TemplateArgument Pack;
1121c5452ed9SRichard Smith   switch (Arg.getKind()) {
1122c5452ed9SRichard Smith   case TemplateArgument::Type:
1123c5452ed9SRichard Smith     if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>())
1124c5452ed9SRichard Smith       Pack = Subst->getArgumentPack();
1125c5452ed9SRichard Smith     else
1126c5452ed9SRichard Smith       return None;
1127c5452ed9SRichard Smith     break;
1128c5452ed9SRichard Smith 
1129c5452ed9SRichard Smith   case TemplateArgument::Expression:
1130c5452ed9SRichard Smith     if (auto *Subst =
1131c5452ed9SRichard Smith             dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
1132c5452ed9SRichard Smith       Pack = Subst->getArgumentPack();
1133c5452ed9SRichard Smith     else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr()))  {
1134b2997f57SRichard Smith       for (VarDecl *PD : *Subst)
1135c5452ed9SRichard Smith         if (PD->isParameterPack())
1136c5452ed9SRichard Smith           return None;
1137c5452ed9SRichard Smith       return Subst->getNumExpansions();
1138c5452ed9SRichard Smith     } else
1139c5452ed9SRichard Smith       return None;
1140c5452ed9SRichard Smith     break;
1141c5452ed9SRichard Smith 
1142c5452ed9SRichard Smith   case TemplateArgument::Template:
1143c5452ed9SRichard Smith     if (SubstTemplateTemplateParmPackStorage *Subst =
1144c5452ed9SRichard Smith             Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack())
1145c5452ed9SRichard Smith       Pack = Subst->getArgumentPack();
1146c5452ed9SRichard Smith     else
1147c5452ed9SRichard Smith       return None;
1148c5452ed9SRichard Smith     break;
1149c5452ed9SRichard Smith 
1150c5452ed9SRichard Smith   case TemplateArgument::Declaration:
1151c5452ed9SRichard Smith   case TemplateArgument::NullPtr:
1152c5452ed9SRichard Smith   case TemplateArgument::TemplateExpansion:
1153c5452ed9SRichard Smith   case TemplateArgument::Integral:
1154c5452ed9SRichard Smith   case TemplateArgument::Pack:
1155c5452ed9SRichard Smith   case TemplateArgument::Null:
1156c5452ed9SRichard Smith     return None;
1157c5452ed9SRichard Smith   }
1158c5452ed9SRichard Smith 
1159c5452ed9SRichard Smith   // Check that no argument in the pack is itself a pack expansion.
1160c5452ed9SRichard Smith   for (TemplateArgument Elem : Pack.pack_elements()) {
1161c5452ed9SRichard Smith     // There's no point recursing in this case; we would have already
1162c5452ed9SRichard Smith     // expanded this pack expansion into the enclosing pack if we could.
1163c5452ed9SRichard Smith     if (Elem.isPackExpansion())
1164c5452ed9SRichard Smith       return None;
1165c5452ed9SRichard Smith   }
1166c5452ed9SRichard Smith   return Pack.pack_size();
116794e9eaa4SEli Friedman }
11680f0af19bSRichard Smith 
CheckFoldOperand(Sema & S,Expr * E)11690f0af19bSRichard Smith static void CheckFoldOperand(Sema &S, Expr *E) {
11700f0af19bSRichard Smith   if (!E)
11710f0af19bSRichard Smith     return;
11720f0af19bSRichard Smith 
11730f0af19bSRichard Smith   E = E->IgnoreImpCasts();
11746609443fSRichard Smith   auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
11756609443fSRichard Smith   if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) ||
11766609443fSRichard Smith       isa<AbstractConditionalOperator>(E)) {
11770f0af19bSRichard Smith     S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand)
11780f0af19bSRichard Smith         << E->getSourceRange()
1179f2ceec48SStephen Kelly         << FixItHint::CreateInsertion(E->getBeginLoc(), "(")
11801c301dcbSStephen Kelly         << FixItHint::CreateInsertion(E->getEndLoc(), ")");
11810f0af19bSRichard Smith   }
11820f0af19bSRichard Smith }
11830f0af19bSRichard Smith 
ActOnCXXFoldExpr(Scope * S,SourceLocation LParenLoc,Expr * LHS,tok::TokenKind Operator,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc)1184ed5a18fcSRichard Smith ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS,
11850f0af19bSRichard Smith                                   tok::TokenKind Operator,
11860f0af19bSRichard Smith                                   SourceLocation EllipsisLoc, Expr *RHS,
11870f0af19bSRichard Smith                                   SourceLocation RParenLoc) {
11880f0af19bSRichard Smith   // LHS and RHS must be cast-expressions. We allow an arbitrary expression
11890f0af19bSRichard Smith   // in the parser and reduce down to just cast-expressions here.
11900f0af19bSRichard Smith   CheckFoldOperand(*this, LHS);
11910f0af19bSRichard Smith   CheckFoldOperand(*this, RHS);
11920f0af19bSRichard Smith 
119390e043daSRichard Smith   auto DiscardOperands = [&] {
119490e043daSRichard Smith     CorrectDelayedTyposInExpr(LHS);
119590e043daSRichard Smith     CorrectDelayedTyposInExpr(RHS);
119690e043daSRichard Smith   };
119790e043daSRichard Smith 
11980f0af19bSRichard Smith   // [expr.prim.fold]p3:
11990f0af19bSRichard Smith   //   In a binary fold, op1 and op2 shall be the same fold-operator, and
12000f0af19bSRichard Smith   //   either e1 shall contain an unexpanded parameter pack or e2 shall contain
12010f0af19bSRichard Smith   //   an unexpanded parameter pack, but not both.
12020f0af19bSRichard Smith   if (LHS && RHS &&
12030f0af19bSRichard Smith       LHS->containsUnexpandedParameterPack() ==
12040f0af19bSRichard Smith           RHS->containsUnexpandedParameterPack()) {
120590e043daSRichard Smith     DiscardOperands();
12060f0af19bSRichard Smith     return Diag(EllipsisLoc,
12070f0af19bSRichard Smith                 LHS->containsUnexpandedParameterPack()
12080f0af19bSRichard Smith                     ? diag::err_fold_expression_packs_both_sides
12090f0af19bSRichard Smith                     : diag::err_pack_expansion_without_parameter_packs)
12100f0af19bSRichard Smith         << LHS->getSourceRange() << RHS->getSourceRange();
12110f0af19bSRichard Smith   }
12120f0af19bSRichard Smith 
12130f0af19bSRichard Smith   // [expr.prim.fold]p2:
12140f0af19bSRichard Smith   //   In a unary fold, the cast-expression shall contain an unexpanded
12150f0af19bSRichard Smith   //   parameter pack.
12160f0af19bSRichard Smith   if (!LHS || !RHS) {
12170f0af19bSRichard Smith     Expr *Pack = LHS ? LHS : RHS;
12180f0af19bSRichard Smith     assert(Pack && "fold expression with neither LHS nor RHS");
121990e043daSRichard Smith     DiscardOperands();
12200f0af19bSRichard Smith     if (!Pack->containsUnexpandedParameterPack())
12210f0af19bSRichard Smith       return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
12220f0af19bSRichard Smith              << Pack->getSourceRange();
12230f0af19bSRichard Smith   }
12240f0af19bSRichard Smith 
12250f0af19bSRichard Smith   BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator);
1226ed5a18fcSRichard Smith 
1227ed5a18fcSRichard Smith   // Perform first-phase name lookup now.
1228ed5a18fcSRichard Smith   UnresolvedLookupExpr *ULE = nullptr;
1229ed5a18fcSRichard Smith   {
1230ed5a18fcSRichard Smith     UnresolvedSet<16> Functions;
1231ed5a18fcSRichard Smith     LookupBinOp(S, EllipsisLoc, Opc, Functions);
1232ed5a18fcSRichard Smith     if (!Functions.empty()) {
1233ed5a18fcSRichard Smith       DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(
1234ed5a18fcSRichard Smith           BinaryOperator::getOverloadedOperator(Opc));
1235ed5a18fcSRichard Smith       ExprResult Callee = CreateUnresolvedLookupExpr(
1236ed5a18fcSRichard Smith           /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
1237ed5a18fcSRichard Smith           DeclarationNameInfo(OpName, EllipsisLoc), Functions);
1238ed5a18fcSRichard Smith       if (Callee.isInvalid())
1239ed5a18fcSRichard Smith         return ExprError();
1240ed5a18fcSRichard Smith       ULE = cast<UnresolvedLookupExpr>(Callee.get());
1241ed5a18fcSRichard Smith     }
1242ed5a18fcSRichard Smith   }
1243ed5a18fcSRichard Smith 
1244ed5a18fcSRichard Smith   return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc,
1245c7214f65SRichard Smith                           None);
12460f0af19bSRichard Smith }
12470f0af19bSRichard Smith 
BuildCXXFoldExpr(UnresolvedLookupExpr * Callee,SourceLocation LParenLoc,Expr * LHS,BinaryOperatorKind Operator,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc,Optional<unsigned> NumExpansions)1248ed5a18fcSRichard Smith ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee,
1249ed5a18fcSRichard Smith                                   SourceLocation LParenLoc, Expr *LHS,
12500f0af19bSRichard Smith                                   BinaryOperatorKind Operator,
12510f0af19bSRichard Smith                                   SourceLocation EllipsisLoc, Expr *RHS,
1252c7214f65SRichard Smith                                   SourceLocation RParenLoc,
1253c7214f65SRichard Smith                                   Optional<unsigned> NumExpansions) {
1254ed5a18fcSRichard Smith   return new (Context)
1255ed5a18fcSRichard Smith       CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator,
1256ed5a18fcSRichard Smith                   EllipsisLoc, RHS, RParenLoc, NumExpansions);
12570f0af19bSRichard Smith }
12580f0af19bSRichard Smith 
BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,BinaryOperatorKind Operator)12590f0af19bSRichard Smith ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
12600f0af19bSRichard Smith                                        BinaryOperatorKind Operator) {
12610f0af19bSRichard Smith   // [temp.variadic]p9:
12620f0af19bSRichard Smith   //   If N is zero for a unary fold-expression, the value of the expression is
12630f0af19bSRichard Smith   //       &&  ->  true
12640f0af19bSRichard Smith   //       ||  ->  false
12650f0af19bSRichard Smith   //       ,   ->  void()
12660f0af19bSRichard Smith   //   if the operator is not listed [above], the instantiation is ill-formed.
12670f0af19bSRichard Smith   //
12680f0af19bSRichard Smith   // Note that we need to use something like int() here, not merely 0, to
12690f0af19bSRichard Smith   // prevent the result from being a null pointer constant.
12700f0af19bSRichard Smith   QualType ScalarType;
12710f0af19bSRichard Smith   switch (Operator) {
12720f0af19bSRichard Smith   case BO_LOr:
12730f0af19bSRichard Smith     return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false);
12740f0af19bSRichard Smith   case BO_LAnd:
12750f0af19bSRichard Smith     return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true);
12760f0af19bSRichard Smith   case BO_Comma:
12770f0af19bSRichard Smith     ScalarType = Context.VoidTy;
12780f0af19bSRichard Smith     break;
12790f0af19bSRichard Smith 
12800f0af19bSRichard Smith   default:
12810f0af19bSRichard Smith     return Diag(EllipsisLoc, diag::err_fold_expression_empty)
12820f0af19bSRichard Smith         << BinaryOperator::getOpcodeStr(Operator);
12830f0af19bSRichard Smith   }
12840f0af19bSRichard Smith 
12850f0af19bSRichard Smith   return new (Context) CXXScalarValueInitExpr(
12860f0af19bSRichard Smith       ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc),
12870f0af19bSRichard Smith       EllipsisLoc);
12880f0af19bSRichard Smith }
1289