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