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