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