1e5dd7070Spatrick //===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //===----------------------------------------------------------------------===/
7e5dd7070Spatrick //
8e5dd7070Spatrick // This file implements semantic analysis for C++0x variadic templates.
9e5dd7070Spatrick //===----------------------------------------------------------------------===/
10e5dd7070Spatrick
11e5dd7070Spatrick #include "clang/Sema/Sema.h"
12e5dd7070Spatrick #include "TypeLocBuilder.h"
13e5dd7070Spatrick #include "clang/AST/Expr.h"
14e5dd7070Spatrick #include "clang/AST/RecursiveASTVisitor.h"
15e5dd7070Spatrick #include "clang/AST/TypeLoc.h"
16e5dd7070Spatrick #include "clang/Sema/Lookup.h"
17e5dd7070Spatrick #include "clang/Sema/ParsedTemplate.h"
18e5dd7070Spatrick #include "clang/Sema/ScopeInfo.h"
19e5dd7070Spatrick #include "clang/Sema/SemaInternal.h"
20e5dd7070Spatrick #include "clang/Sema/Template.h"
21*12c85518Srobert #include <optional>
22e5dd7070Spatrick
23e5dd7070Spatrick using namespace clang;
24e5dd7070Spatrick
25e5dd7070Spatrick //----------------------------------------------------------------------------
26e5dd7070Spatrick // Visitor that collects unexpanded parameter packs
27e5dd7070Spatrick //----------------------------------------------------------------------------
28e5dd7070Spatrick
29e5dd7070Spatrick namespace {
30e5dd7070Spatrick /// A class that collects unexpanded parameter packs.
31e5dd7070Spatrick class CollectUnexpandedParameterPacksVisitor :
32e5dd7070Spatrick public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
33e5dd7070Spatrick {
34e5dd7070Spatrick typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
35e5dd7070Spatrick inherited;
36e5dd7070Spatrick
37e5dd7070Spatrick SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
38e5dd7070Spatrick
39e5dd7070Spatrick bool InLambda = false;
40e5dd7070Spatrick unsigned DepthLimit = (unsigned)-1;
41e5dd7070Spatrick
addUnexpanded(NamedDecl * ND,SourceLocation Loc=SourceLocation ())42e5dd7070Spatrick void addUnexpanded(NamedDecl *ND, SourceLocation Loc = SourceLocation()) {
43e5dd7070Spatrick if (auto *VD = dyn_cast<VarDecl>(ND)) {
44e5dd7070Spatrick // For now, the only problematic case is a generic lambda's templated
45e5dd7070Spatrick // call operator, so we don't need to look for all the other ways we
46e5dd7070Spatrick // could have reached a dependent parameter pack.
47e5dd7070Spatrick auto *FD = dyn_cast<FunctionDecl>(VD->getDeclContext());
48e5dd7070Spatrick auto *FTD = FD ? FD->getDescribedFunctionTemplate() : nullptr;
49e5dd7070Spatrick if (FTD && FTD->getTemplateParameters()->getDepth() >= DepthLimit)
50e5dd7070Spatrick return;
51e5dd7070Spatrick } else if (getDepthAndIndex(ND).first >= DepthLimit)
52e5dd7070Spatrick return;
53e5dd7070Spatrick
54e5dd7070Spatrick Unexpanded.push_back({ND, Loc});
55e5dd7070Spatrick }
addUnexpanded(const TemplateTypeParmType * T,SourceLocation Loc=SourceLocation ())56e5dd7070Spatrick void addUnexpanded(const TemplateTypeParmType *T,
57e5dd7070Spatrick SourceLocation Loc = SourceLocation()) {
58e5dd7070Spatrick if (T->getDepth() < DepthLimit)
59e5dd7070Spatrick Unexpanded.push_back({T, Loc});
60e5dd7070Spatrick }
61e5dd7070Spatrick
62e5dd7070Spatrick public:
CollectUnexpandedParameterPacksVisitor(SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)63e5dd7070Spatrick explicit CollectUnexpandedParameterPacksVisitor(
64e5dd7070Spatrick SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
65e5dd7070Spatrick : Unexpanded(Unexpanded) {}
66e5dd7070Spatrick
shouldWalkTypesOfTypeLocs() const67e5dd7070Spatrick bool shouldWalkTypesOfTypeLocs() const { return false; }
68e5dd7070Spatrick
69e5dd7070Spatrick //------------------------------------------------------------------------
70e5dd7070Spatrick // Recording occurrences of (unexpanded) parameter packs.
71e5dd7070Spatrick //------------------------------------------------------------------------
72e5dd7070Spatrick
73e5dd7070Spatrick /// Record occurrences of template type parameter packs.
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)74e5dd7070Spatrick bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
75e5dd7070Spatrick if (TL.getTypePtr()->isParameterPack())
76e5dd7070Spatrick addUnexpanded(TL.getTypePtr(), TL.getNameLoc());
77e5dd7070Spatrick return true;
78e5dd7070Spatrick }
79e5dd7070Spatrick
80e5dd7070Spatrick /// Record occurrences of template type parameter packs
81e5dd7070Spatrick /// when we don't have proper source-location information for
82e5dd7070Spatrick /// them.
83e5dd7070Spatrick ///
84e5dd7070Spatrick /// Ideally, this routine would never be used.
VisitTemplateTypeParmType(TemplateTypeParmType * T)85e5dd7070Spatrick bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
86e5dd7070Spatrick if (T->isParameterPack())
87e5dd7070Spatrick addUnexpanded(T);
88e5dd7070Spatrick
89e5dd7070Spatrick return true;
90e5dd7070Spatrick }
91e5dd7070Spatrick
92e5dd7070Spatrick /// Record occurrences of function and non-type template
93e5dd7070Spatrick /// parameter packs in an expression.
VisitDeclRefExpr(DeclRefExpr * E)94e5dd7070Spatrick bool VisitDeclRefExpr(DeclRefExpr *E) {
95e5dd7070Spatrick if (E->getDecl()->isParameterPack())
96e5dd7070Spatrick addUnexpanded(E->getDecl(), E->getLocation());
97e5dd7070Spatrick
98e5dd7070Spatrick return true;
99e5dd7070Spatrick }
100e5dd7070Spatrick
101e5dd7070Spatrick /// Record occurrences of template template parameter packs.
TraverseTemplateName(TemplateName Template)102e5dd7070Spatrick bool TraverseTemplateName(TemplateName Template) {
103e5dd7070Spatrick if (auto *TTP = dyn_cast_or_null<TemplateTemplateParmDecl>(
104e5dd7070Spatrick Template.getAsTemplateDecl())) {
105e5dd7070Spatrick if (TTP->isParameterPack())
106e5dd7070Spatrick addUnexpanded(TTP);
107e5dd7070Spatrick }
108e5dd7070Spatrick
109e5dd7070Spatrick return inherited::TraverseTemplateName(Template);
110e5dd7070Spatrick }
111e5dd7070Spatrick
112e5dd7070Spatrick /// Suppress traversal into Objective-C container literal
113e5dd7070Spatrick /// elements that are pack expansions.
TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral * E)114e5dd7070Spatrick bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
115e5dd7070Spatrick if (!E->containsUnexpandedParameterPack())
116e5dd7070Spatrick return true;
117e5dd7070Spatrick
118e5dd7070Spatrick for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
119e5dd7070Spatrick ObjCDictionaryElement Element = E->getKeyValueElement(I);
120e5dd7070Spatrick if (Element.isPackExpansion())
121e5dd7070Spatrick continue;
122e5dd7070Spatrick
123e5dd7070Spatrick TraverseStmt(Element.Key);
124e5dd7070Spatrick TraverseStmt(Element.Value);
125e5dd7070Spatrick }
126e5dd7070Spatrick return true;
127e5dd7070Spatrick }
128e5dd7070Spatrick //------------------------------------------------------------------------
129e5dd7070Spatrick // Pruning the search for unexpanded parameter packs.
130e5dd7070Spatrick //------------------------------------------------------------------------
131e5dd7070Spatrick
132e5dd7070Spatrick /// Suppress traversal into statements and expressions that
133e5dd7070Spatrick /// do not contain unexpanded parameter packs.
TraverseStmt(Stmt * S)134e5dd7070Spatrick bool TraverseStmt(Stmt *S) {
135e5dd7070Spatrick Expr *E = dyn_cast_or_null<Expr>(S);
136e5dd7070Spatrick if ((E && E->containsUnexpandedParameterPack()) || InLambda)
137e5dd7070Spatrick return inherited::TraverseStmt(S);
138e5dd7070Spatrick
139e5dd7070Spatrick return true;
140e5dd7070Spatrick }
141e5dd7070Spatrick
142e5dd7070Spatrick /// Suppress traversal into types that do not contain
143e5dd7070Spatrick /// unexpanded parameter packs.
TraverseType(QualType T)144e5dd7070Spatrick bool TraverseType(QualType T) {
145e5dd7070Spatrick if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
146e5dd7070Spatrick return inherited::TraverseType(T);
147e5dd7070Spatrick
148e5dd7070Spatrick return true;
149e5dd7070Spatrick }
150e5dd7070Spatrick
151e5dd7070Spatrick /// Suppress traversal into types with location information
152e5dd7070Spatrick /// that do not contain unexpanded parameter packs.
TraverseTypeLoc(TypeLoc TL)153e5dd7070Spatrick bool TraverseTypeLoc(TypeLoc TL) {
154e5dd7070Spatrick if ((!TL.getType().isNull() &&
155e5dd7070Spatrick TL.getType()->containsUnexpandedParameterPack()) ||
156e5dd7070Spatrick InLambda)
157e5dd7070Spatrick return inherited::TraverseTypeLoc(TL);
158e5dd7070Spatrick
159e5dd7070Spatrick return true;
160e5dd7070Spatrick }
161e5dd7070Spatrick
162e5dd7070Spatrick /// Suppress traversal of parameter packs.
TraverseDecl(Decl * D)163e5dd7070Spatrick bool TraverseDecl(Decl *D) {
164e5dd7070Spatrick // A function parameter pack is a pack expansion, so cannot contain
165e5dd7070Spatrick // an unexpanded parameter pack. Likewise for a template parameter
166e5dd7070Spatrick // pack that contains any references to other packs.
167e5dd7070Spatrick if (D && D->isParameterPack())
168e5dd7070Spatrick return true;
169e5dd7070Spatrick
170e5dd7070Spatrick return inherited::TraverseDecl(D);
171e5dd7070Spatrick }
172e5dd7070Spatrick
173e5dd7070Spatrick /// Suppress traversal of pack-expanded attributes.
TraverseAttr(Attr * A)174e5dd7070Spatrick bool TraverseAttr(Attr *A) {
175e5dd7070Spatrick if (A->isPackExpansion())
176e5dd7070Spatrick return true;
177e5dd7070Spatrick
178e5dd7070Spatrick return inherited::TraverseAttr(A);
179e5dd7070Spatrick }
180e5dd7070Spatrick
181e5dd7070Spatrick /// Suppress traversal of pack expansion expressions and types.
182e5dd7070Spatrick ///@{
TraversePackExpansionType(PackExpansionType * T)183e5dd7070Spatrick bool TraversePackExpansionType(PackExpansionType *T) { return true; }
TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL)184e5dd7070Spatrick bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) { return true; }
TraversePackExpansionExpr(PackExpansionExpr * E)185e5dd7070Spatrick bool TraversePackExpansionExpr(PackExpansionExpr *E) { return true; }
TraverseCXXFoldExpr(CXXFoldExpr * E)186e5dd7070Spatrick bool TraverseCXXFoldExpr(CXXFoldExpr *E) { return true; }
187e5dd7070Spatrick
188e5dd7070Spatrick ///@}
189e5dd7070Spatrick
190e5dd7070Spatrick /// Suppress traversal of using-declaration pack expansion.
TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)191e5dd7070Spatrick bool TraverseUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
192e5dd7070Spatrick if (D->isPackExpansion())
193e5dd7070Spatrick return true;
194e5dd7070Spatrick
195e5dd7070Spatrick return inherited::TraverseUnresolvedUsingValueDecl(D);
196e5dd7070Spatrick }
197e5dd7070Spatrick
198e5dd7070Spatrick /// Suppress traversal of using-declaration pack expansion.
TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)199e5dd7070Spatrick bool TraverseUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
200e5dd7070Spatrick if (D->isPackExpansion())
201e5dd7070Spatrick return true;
202e5dd7070Spatrick
203e5dd7070Spatrick return inherited::TraverseUnresolvedUsingTypenameDecl(D);
204e5dd7070Spatrick }
205e5dd7070Spatrick
206e5dd7070Spatrick /// Suppress traversal of template argument pack expansions.
TraverseTemplateArgument(const TemplateArgument & Arg)207e5dd7070Spatrick bool TraverseTemplateArgument(const TemplateArgument &Arg) {
208e5dd7070Spatrick if (Arg.isPackExpansion())
209e5dd7070Spatrick return true;
210e5dd7070Spatrick
211e5dd7070Spatrick return inherited::TraverseTemplateArgument(Arg);
212e5dd7070Spatrick }
213e5dd7070Spatrick
214e5dd7070Spatrick /// Suppress traversal of template argument pack expansions.
TraverseTemplateArgumentLoc(const TemplateArgumentLoc & ArgLoc)215e5dd7070Spatrick bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
216e5dd7070Spatrick if (ArgLoc.getArgument().isPackExpansion())
217e5dd7070Spatrick return true;
218e5dd7070Spatrick
219e5dd7070Spatrick return inherited::TraverseTemplateArgumentLoc(ArgLoc);
220e5dd7070Spatrick }
221e5dd7070Spatrick
222e5dd7070Spatrick /// Suppress traversal of base specifier pack expansions.
TraverseCXXBaseSpecifier(const CXXBaseSpecifier & Base)223e5dd7070Spatrick bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base) {
224e5dd7070Spatrick if (Base.isPackExpansion())
225e5dd7070Spatrick return true;
226e5dd7070Spatrick
227e5dd7070Spatrick return inherited::TraverseCXXBaseSpecifier(Base);
228e5dd7070Spatrick }
229e5dd7070Spatrick
230e5dd7070Spatrick /// Suppress traversal of mem-initializer pack expansions.
TraverseConstructorInitializer(CXXCtorInitializer * Init)231e5dd7070Spatrick bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
232e5dd7070Spatrick if (Init->isPackExpansion())
233e5dd7070Spatrick return true;
234e5dd7070Spatrick
235e5dd7070Spatrick return inherited::TraverseConstructorInitializer(Init);
236e5dd7070Spatrick }
237e5dd7070Spatrick
238e5dd7070Spatrick /// Note whether we're traversing a lambda containing an unexpanded
239e5dd7070Spatrick /// parameter pack. In this case, the unexpanded pack can occur anywhere,
240e5dd7070Spatrick /// including all the places where we normally wouldn't look. Within a
241e5dd7070Spatrick /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
242e5dd7070Spatrick /// outside an expression.
TraverseLambdaExpr(LambdaExpr * Lambda)243e5dd7070Spatrick bool TraverseLambdaExpr(LambdaExpr *Lambda) {
244e5dd7070Spatrick // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
245e5dd7070Spatrick // even if it's contained within another lambda.
246e5dd7070Spatrick if (!Lambda->containsUnexpandedParameterPack())
247e5dd7070Spatrick return true;
248e5dd7070Spatrick
249e5dd7070Spatrick bool WasInLambda = InLambda;
250e5dd7070Spatrick unsigned OldDepthLimit = DepthLimit;
251e5dd7070Spatrick
252e5dd7070Spatrick InLambda = true;
253e5dd7070Spatrick if (auto *TPL = Lambda->getTemplateParameterList())
254e5dd7070Spatrick DepthLimit = TPL->getDepth();
255e5dd7070Spatrick
256e5dd7070Spatrick inherited::TraverseLambdaExpr(Lambda);
257e5dd7070Spatrick
258e5dd7070Spatrick InLambda = WasInLambda;
259e5dd7070Spatrick DepthLimit = OldDepthLimit;
260e5dd7070Spatrick return true;
261e5dd7070Spatrick }
262e5dd7070Spatrick
263e5dd7070Spatrick /// Suppress traversal within pack expansions in lambda captures.
TraverseLambdaCapture(LambdaExpr * Lambda,const LambdaCapture * C,Expr * Init)264e5dd7070Spatrick bool TraverseLambdaCapture(LambdaExpr *Lambda, const LambdaCapture *C,
265e5dd7070Spatrick Expr *Init) {
266e5dd7070Spatrick if (C->isPackExpansion())
267e5dd7070Spatrick return true;
268e5dd7070Spatrick
269e5dd7070Spatrick return inherited::TraverseLambdaCapture(Lambda, C, Init);
270e5dd7070Spatrick }
271e5dd7070Spatrick };
272e5dd7070Spatrick }
273e5dd7070Spatrick
274e5dd7070Spatrick /// Determine whether it's possible for an unexpanded parameter pack to
275e5dd7070Spatrick /// be valid in this location. This only happens when we're in a declaration
276e5dd7070Spatrick /// that is nested within an expression that could be expanded, such as a
277e5dd7070Spatrick /// lambda-expression within a function call.
278e5dd7070Spatrick ///
279e5dd7070Spatrick /// This is conservatively correct, but may claim that some unexpanded packs are
280e5dd7070Spatrick /// permitted when they are not.
isUnexpandedParameterPackPermitted()281e5dd7070Spatrick bool Sema::isUnexpandedParameterPackPermitted() {
282e5dd7070Spatrick for (auto *SI : FunctionScopes)
283e5dd7070Spatrick if (isa<sema::LambdaScopeInfo>(SI))
284e5dd7070Spatrick return true;
285e5dd7070Spatrick return false;
286e5dd7070Spatrick }
287e5dd7070Spatrick
288e5dd7070Spatrick /// Diagnose all of the unexpanded parameter packs in the given
289e5dd7070Spatrick /// vector.
290e5dd7070Spatrick bool
DiagnoseUnexpandedParameterPacks(SourceLocation Loc,UnexpandedParameterPackContext UPPC,ArrayRef<UnexpandedParameterPack> Unexpanded)291e5dd7070Spatrick Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
292e5dd7070Spatrick UnexpandedParameterPackContext UPPC,
293e5dd7070Spatrick ArrayRef<UnexpandedParameterPack> Unexpanded) {
294e5dd7070Spatrick if (Unexpanded.empty())
295e5dd7070Spatrick return false;
296e5dd7070Spatrick
297e5dd7070Spatrick // If we are within a lambda expression and referencing a pack that is not
298e5dd7070Spatrick // declared within the lambda itself, that lambda contains an unexpanded
299e5dd7070Spatrick // parameter pack, and we are done.
300e5dd7070Spatrick // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
301e5dd7070Spatrick // later.
302e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 4> LambdaParamPackReferences;
303e5dd7070Spatrick if (auto *LSI = getEnclosingLambda()) {
304e5dd7070Spatrick for (auto &Pack : Unexpanded) {
305e5dd7070Spatrick auto DeclaresThisPack = [&](NamedDecl *LocalPack) {
306e5dd7070Spatrick if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) {
307e5dd7070Spatrick auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack);
308e5dd7070Spatrick return TTPD && TTPD->getTypeForDecl() == TTPT;
309e5dd7070Spatrick }
310e5dd7070Spatrick return declaresSameEntity(Pack.first.get<NamedDecl *>(), LocalPack);
311e5dd7070Spatrick };
312*12c85518Srobert if (llvm::any_of(LSI->LocalPacks, DeclaresThisPack))
313e5dd7070Spatrick LambdaParamPackReferences.push_back(Pack);
314e5dd7070Spatrick }
315e5dd7070Spatrick
316e5dd7070Spatrick if (LambdaParamPackReferences.empty()) {
317e5dd7070Spatrick // Construct in lambda only references packs declared outside the lambda.
318e5dd7070Spatrick // That's OK for now, but the lambda itself is considered to contain an
319e5dd7070Spatrick // unexpanded pack in this case, which will require expansion outside the
320e5dd7070Spatrick // lambda.
321e5dd7070Spatrick
322e5dd7070Spatrick // We do not permit pack expansion that would duplicate a statement
323e5dd7070Spatrick // expression, not even within a lambda.
324e5dd7070Spatrick // FIXME: We could probably support this for statement expressions that
325e5dd7070Spatrick // do not contain labels.
326e5dd7070Spatrick // FIXME: This is insufficient to detect this problem; consider
327e5dd7070Spatrick // f( ({ bad: 0; }) + pack ... );
328e5dd7070Spatrick bool EnclosingStmtExpr = false;
329e5dd7070Spatrick for (unsigned N = FunctionScopes.size(); N; --N) {
330e5dd7070Spatrick sema::FunctionScopeInfo *Func = FunctionScopes[N-1];
331*12c85518Srobert if (llvm::any_of(
332*12c85518Srobert Func->CompoundScopes,
333e5dd7070Spatrick [](sema::CompoundScopeInfo &CSI) { return CSI.IsStmtExpr; })) {
334e5dd7070Spatrick EnclosingStmtExpr = true;
335e5dd7070Spatrick break;
336e5dd7070Spatrick }
337e5dd7070Spatrick // Coumpound-statements outside the lambda are OK for now; we'll check
338e5dd7070Spatrick // for those when we finish handling the lambda.
339e5dd7070Spatrick if (Func == LSI)
340e5dd7070Spatrick break;
341e5dd7070Spatrick }
342e5dd7070Spatrick
343e5dd7070Spatrick if (!EnclosingStmtExpr) {
344e5dd7070Spatrick LSI->ContainsUnexpandedParameterPack = true;
345e5dd7070Spatrick return false;
346e5dd7070Spatrick }
347e5dd7070Spatrick } else {
348e5dd7070Spatrick Unexpanded = LambdaParamPackReferences;
349e5dd7070Spatrick }
350e5dd7070Spatrick }
351e5dd7070Spatrick
352e5dd7070Spatrick SmallVector<SourceLocation, 4> Locations;
353e5dd7070Spatrick SmallVector<IdentifierInfo *, 4> Names;
354e5dd7070Spatrick llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
355e5dd7070Spatrick
356e5dd7070Spatrick for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
357e5dd7070Spatrick IdentifierInfo *Name = nullptr;
358e5dd7070Spatrick if (const TemplateTypeParmType *TTP
359e5dd7070Spatrick = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
360e5dd7070Spatrick Name = TTP->getIdentifier();
361e5dd7070Spatrick else
362e5dd7070Spatrick Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
363e5dd7070Spatrick
364e5dd7070Spatrick if (Name && NamesKnown.insert(Name).second)
365e5dd7070Spatrick Names.push_back(Name);
366e5dd7070Spatrick
367e5dd7070Spatrick if (Unexpanded[I].second.isValid())
368e5dd7070Spatrick Locations.push_back(Unexpanded[I].second);
369e5dd7070Spatrick }
370e5dd7070Spatrick
371a9ac8606Spatrick auto DB = Diag(Loc, diag::err_unexpanded_parameter_pack)
372e5dd7070Spatrick << (int)UPPC << (int)Names.size();
373e5dd7070Spatrick for (size_t I = 0, E = std::min(Names.size(), (size_t)2); I != E; ++I)
374e5dd7070Spatrick DB << Names[I];
375e5dd7070Spatrick
376e5dd7070Spatrick for (unsigned I = 0, N = Locations.size(); I != N; ++I)
377e5dd7070Spatrick DB << SourceRange(Locations[I]);
378e5dd7070Spatrick return true;
379e5dd7070Spatrick }
380e5dd7070Spatrick
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TypeSourceInfo * T,UnexpandedParameterPackContext UPPC)381e5dd7070Spatrick bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
382e5dd7070Spatrick TypeSourceInfo *T,
383e5dd7070Spatrick UnexpandedParameterPackContext UPPC) {
384e5dd7070Spatrick // C++0x [temp.variadic]p5:
385e5dd7070Spatrick // An appearance of a name of a parameter pack that is not expanded is
386e5dd7070Spatrick // ill-formed.
387e5dd7070Spatrick if (!T->getType()->containsUnexpandedParameterPack())
388e5dd7070Spatrick return false;
389e5dd7070Spatrick
390e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
391e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
392e5dd7070Spatrick T->getTypeLoc());
393e5dd7070Spatrick assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
394e5dd7070Spatrick return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
395e5dd7070Spatrick }
396e5dd7070Spatrick
DiagnoseUnexpandedParameterPack(Expr * E,UnexpandedParameterPackContext UPPC)397e5dd7070Spatrick bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
398e5dd7070Spatrick UnexpandedParameterPackContext UPPC) {
399e5dd7070Spatrick // C++0x [temp.variadic]p5:
400e5dd7070Spatrick // An appearance of a name of a parameter pack that is not expanded is
401e5dd7070Spatrick // ill-formed.
402e5dd7070Spatrick if (!E->containsUnexpandedParameterPack())
403e5dd7070Spatrick return false;
404e5dd7070Spatrick
405e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
406e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
407e5dd7070Spatrick assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
408e5dd7070Spatrick return DiagnoseUnexpandedParameterPacks(E->getBeginLoc(), UPPC, Unexpanded);
409e5dd7070Spatrick }
410e5dd7070Spatrick
DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr * RE)411a9ac8606Spatrick bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
412a9ac8606Spatrick if (!RE->containsUnexpandedParameterPack())
413a9ac8606Spatrick return false;
414a9ac8606Spatrick
415a9ac8606Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
416a9ac8606Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(RE);
417a9ac8606Spatrick assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
418a9ac8606Spatrick
419a9ac8606Spatrick // We only care about unexpanded references to the RequiresExpr's own
420a9ac8606Spatrick // parameter packs.
421a9ac8606Spatrick auto Parms = RE->getLocalParameters();
422a9ac8606Spatrick llvm::SmallPtrSet<NamedDecl*, 8> ParmSet(Parms.begin(), Parms.end());
423a9ac8606Spatrick SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
424a9ac8606Spatrick for (auto Parm : Unexpanded)
425a9ac8606Spatrick if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl *>()))
426a9ac8606Spatrick UnexpandedParms.push_back(Parm);
427a9ac8606Spatrick if (UnexpandedParms.empty())
428a9ac8606Spatrick return false;
429a9ac8606Spatrick
430a9ac8606Spatrick return DiagnoseUnexpandedParameterPacks(RE->getBeginLoc(), UPPC_Requirement,
431a9ac8606Spatrick UnexpandedParms);
432a9ac8606Spatrick }
433a9ac8606Spatrick
DiagnoseUnexpandedParameterPack(const CXXScopeSpec & SS,UnexpandedParameterPackContext UPPC)434e5dd7070Spatrick bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
435e5dd7070Spatrick UnexpandedParameterPackContext UPPC) {
436e5dd7070Spatrick // C++0x [temp.variadic]p5:
437e5dd7070Spatrick // An appearance of a name of a parameter pack that is not expanded is
438e5dd7070Spatrick // ill-formed.
439e5dd7070Spatrick if (!SS.getScopeRep() ||
440e5dd7070Spatrick !SS.getScopeRep()->containsUnexpandedParameterPack())
441e5dd7070Spatrick return false;
442e5dd7070Spatrick
443e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
444e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded)
445e5dd7070Spatrick .TraverseNestedNameSpecifier(SS.getScopeRep());
446e5dd7070Spatrick assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
447e5dd7070Spatrick return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
448e5dd7070Spatrick UPPC, Unexpanded);
449e5dd7070Spatrick }
450e5dd7070Spatrick
DiagnoseUnexpandedParameterPack(const DeclarationNameInfo & NameInfo,UnexpandedParameterPackContext UPPC)451e5dd7070Spatrick bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
452e5dd7070Spatrick UnexpandedParameterPackContext UPPC) {
453e5dd7070Spatrick // C++0x [temp.variadic]p5:
454e5dd7070Spatrick // An appearance of a name of a parameter pack that is not expanded is
455e5dd7070Spatrick // ill-formed.
456e5dd7070Spatrick switch (NameInfo.getName().getNameKind()) {
457e5dd7070Spatrick case DeclarationName::Identifier:
458e5dd7070Spatrick case DeclarationName::ObjCZeroArgSelector:
459e5dd7070Spatrick case DeclarationName::ObjCOneArgSelector:
460e5dd7070Spatrick case DeclarationName::ObjCMultiArgSelector:
461e5dd7070Spatrick case DeclarationName::CXXOperatorName:
462e5dd7070Spatrick case DeclarationName::CXXLiteralOperatorName:
463e5dd7070Spatrick case DeclarationName::CXXUsingDirective:
464e5dd7070Spatrick case DeclarationName::CXXDeductionGuideName:
465e5dd7070Spatrick return false;
466e5dd7070Spatrick
467e5dd7070Spatrick case DeclarationName::CXXConstructorName:
468e5dd7070Spatrick case DeclarationName::CXXDestructorName:
469e5dd7070Spatrick case DeclarationName::CXXConversionFunctionName:
470e5dd7070Spatrick // FIXME: We shouldn't need this null check!
471e5dd7070Spatrick if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
472e5dd7070Spatrick return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
473e5dd7070Spatrick
474e5dd7070Spatrick if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
475e5dd7070Spatrick return false;
476e5dd7070Spatrick
477e5dd7070Spatrick break;
478e5dd7070Spatrick }
479e5dd7070Spatrick
480e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
481e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded)
482e5dd7070Spatrick .TraverseType(NameInfo.getName().getCXXNameType());
483e5dd7070Spatrick assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
484e5dd7070Spatrick return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
485e5dd7070Spatrick }
486e5dd7070Spatrick
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TemplateName Template,UnexpandedParameterPackContext UPPC)487e5dd7070Spatrick bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
488e5dd7070Spatrick TemplateName Template,
489e5dd7070Spatrick UnexpandedParameterPackContext UPPC) {
490e5dd7070Spatrick
491e5dd7070Spatrick if (Template.isNull() || !Template.containsUnexpandedParameterPack())
492e5dd7070Spatrick return false;
493e5dd7070Spatrick
494e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
495e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded)
496e5dd7070Spatrick .TraverseTemplateName(Template);
497e5dd7070Spatrick assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
498e5dd7070Spatrick return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
499e5dd7070Spatrick }
500e5dd7070Spatrick
DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,UnexpandedParameterPackContext UPPC)501e5dd7070Spatrick bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
502e5dd7070Spatrick UnexpandedParameterPackContext UPPC) {
503e5dd7070Spatrick if (Arg.getArgument().isNull() ||
504e5dd7070Spatrick !Arg.getArgument().containsUnexpandedParameterPack())
505e5dd7070Spatrick return false;
506e5dd7070Spatrick
507e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
508e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded)
509e5dd7070Spatrick .TraverseTemplateArgumentLoc(Arg);
510e5dd7070Spatrick assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
511e5dd7070Spatrick return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
512e5dd7070Spatrick }
513e5dd7070Spatrick
collectUnexpandedParameterPacks(TemplateArgument Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)514e5dd7070Spatrick void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
515e5dd7070Spatrick SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
516e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded)
517e5dd7070Spatrick .TraverseTemplateArgument(Arg);
518e5dd7070Spatrick }
519e5dd7070Spatrick
collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)520e5dd7070Spatrick void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
521e5dd7070Spatrick SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
522e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded)
523e5dd7070Spatrick .TraverseTemplateArgumentLoc(Arg);
524e5dd7070Spatrick }
525e5dd7070Spatrick
collectUnexpandedParameterPacks(QualType T,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)526e5dd7070Spatrick void Sema::collectUnexpandedParameterPacks(QualType T,
527e5dd7070Spatrick SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
528e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
529e5dd7070Spatrick }
530e5dd7070Spatrick
collectUnexpandedParameterPacks(TypeLoc TL,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)531e5dd7070Spatrick void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
532e5dd7070Spatrick SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
533e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
534e5dd7070Spatrick }
535e5dd7070Spatrick
collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)536e5dd7070Spatrick void Sema::collectUnexpandedParameterPacks(
537e5dd7070Spatrick NestedNameSpecifierLoc NNS,
538e5dd7070Spatrick SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
539e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded)
540e5dd7070Spatrick .TraverseNestedNameSpecifierLoc(NNS);
541e5dd7070Spatrick }
542e5dd7070Spatrick
collectUnexpandedParameterPacks(const DeclarationNameInfo & NameInfo,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)543e5dd7070Spatrick void Sema::collectUnexpandedParameterPacks(
544e5dd7070Spatrick const DeclarationNameInfo &NameInfo,
545e5dd7070Spatrick SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
546e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded)
547e5dd7070Spatrick .TraverseDeclarationNameInfo(NameInfo);
548e5dd7070Spatrick }
549e5dd7070Spatrick
550e5dd7070Spatrick
551e5dd7070Spatrick ParsedTemplateArgument
ActOnPackExpansion(const ParsedTemplateArgument & Arg,SourceLocation EllipsisLoc)552e5dd7070Spatrick Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
553e5dd7070Spatrick SourceLocation EllipsisLoc) {
554e5dd7070Spatrick if (Arg.isInvalid())
555e5dd7070Spatrick return Arg;
556e5dd7070Spatrick
557e5dd7070Spatrick switch (Arg.getKind()) {
558e5dd7070Spatrick case ParsedTemplateArgument::Type: {
559e5dd7070Spatrick TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
560e5dd7070Spatrick if (Result.isInvalid())
561e5dd7070Spatrick return ParsedTemplateArgument();
562e5dd7070Spatrick
563e5dd7070Spatrick return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
564e5dd7070Spatrick Arg.getLocation());
565e5dd7070Spatrick }
566e5dd7070Spatrick
567e5dd7070Spatrick case ParsedTemplateArgument::NonType: {
568e5dd7070Spatrick ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
569e5dd7070Spatrick if (Result.isInvalid())
570e5dd7070Spatrick return ParsedTemplateArgument();
571e5dd7070Spatrick
572e5dd7070Spatrick return ParsedTemplateArgument(Arg.getKind(), Result.get(),
573e5dd7070Spatrick Arg.getLocation());
574e5dd7070Spatrick }
575e5dd7070Spatrick
576e5dd7070Spatrick case ParsedTemplateArgument::Template:
577e5dd7070Spatrick if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
578e5dd7070Spatrick SourceRange R(Arg.getLocation());
579e5dd7070Spatrick if (Arg.getScopeSpec().isValid())
580e5dd7070Spatrick R.setBegin(Arg.getScopeSpec().getBeginLoc());
581e5dd7070Spatrick Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
582e5dd7070Spatrick << R;
583e5dd7070Spatrick return ParsedTemplateArgument();
584e5dd7070Spatrick }
585e5dd7070Spatrick
586e5dd7070Spatrick return Arg.getTemplatePackExpansion(EllipsisLoc);
587e5dd7070Spatrick }
588e5dd7070Spatrick llvm_unreachable("Unhandled template argument kind?");
589e5dd7070Spatrick }
590e5dd7070Spatrick
ActOnPackExpansion(ParsedType Type,SourceLocation EllipsisLoc)591e5dd7070Spatrick TypeResult Sema::ActOnPackExpansion(ParsedType Type,
592e5dd7070Spatrick SourceLocation EllipsisLoc) {
593e5dd7070Spatrick TypeSourceInfo *TSInfo;
594e5dd7070Spatrick GetTypeFromParser(Type, &TSInfo);
595e5dd7070Spatrick if (!TSInfo)
596e5dd7070Spatrick return true;
597e5dd7070Spatrick
598*12c85518Srobert TypeSourceInfo *TSResult =
599*12c85518Srobert CheckPackExpansion(TSInfo, EllipsisLoc, std::nullopt);
600e5dd7070Spatrick if (!TSResult)
601e5dd7070Spatrick return true;
602e5dd7070Spatrick
603e5dd7070Spatrick return CreateParsedType(TSResult->getType(), TSResult);
604e5dd7070Spatrick }
605e5dd7070Spatrick
606e5dd7070Spatrick TypeSourceInfo *
CheckPackExpansion(TypeSourceInfo * Pattern,SourceLocation EllipsisLoc,std::optional<unsigned> NumExpansions)607e5dd7070Spatrick Sema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc,
608*12c85518Srobert std::optional<unsigned> NumExpansions) {
609e5dd7070Spatrick // Create the pack expansion type and source-location information.
610e5dd7070Spatrick QualType Result = CheckPackExpansion(Pattern->getType(),
611e5dd7070Spatrick Pattern->getTypeLoc().getSourceRange(),
612e5dd7070Spatrick EllipsisLoc, NumExpansions);
613e5dd7070Spatrick if (Result.isNull())
614e5dd7070Spatrick return nullptr;
615e5dd7070Spatrick
616e5dd7070Spatrick TypeLocBuilder TLB;
617e5dd7070Spatrick TLB.pushFullCopy(Pattern->getTypeLoc());
618e5dd7070Spatrick PackExpansionTypeLoc TL = TLB.push<PackExpansionTypeLoc>(Result);
619e5dd7070Spatrick TL.setEllipsisLoc(EllipsisLoc);
620e5dd7070Spatrick
621e5dd7070Spatrick return TLB.getTypeSourceInfo(Context, Result);
622e5dd7070Spatrick }
623e5dd7070Spatrick
CheckPackExpansion(QualType Pattern,SourceRange PatternRange,SourceLocation EllipsisLoc,std::optional<unsigned> NumExpansions)624e5dd7070Spatrick QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
625e5dd7070Spatrick SourceLocation EllipsisLoc,
626*12c85518Srobert std::optional<unsigned> NumExpansions) {
627e5dd7070Spatrick // C++11 [temp.variadic]p5:
628e5dd7070Spatrick // The pattern of a pack expansion shall name one or more
629e5dd7070Spatrick // parameter packs that are not expanded by a nested pack
630e5dd7070Spatrick // expansion.
631e5dd7070Spatrick //
632e5dd7070Spatrick // A pattern containing a deduced type can't occur "naturally" but arises in
633e5dd7070Spatrick // the desugaring of an init-capture pack.
634e5dd7070Spatrick if (!Pattern->containsUnexpandedParameterPack() &&
635e5dd7070Spatrick !Pattern->getContainedDeducedType()) {
636e5dd7070Spatrick Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
637e5dd7070Spatrick << PatternRange;
638e5dd7070Spatrick return QualType();
639e5dd7070Spatrick }
640e5dd7070Spatrick
641a9ac8606Spatrick return Context.getPackExpansionType(Pattern, NumExpansions,
642a9ac8606Spatrick /*ExpectPackInType=*/false);
643e5dd7070Spatrick }
644e5dd7070Spatrick
ActOnPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc)645e5dd7070Spatrick ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
646*12c85518Srobert return CheckPackExpansion(Pattern, EllipsisLoc, std::nullopt);
647e5dd7070Spatrick }
648e5dd7070Spatrick
CheckPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc,std::optional<unsigned> NumExpansions)649e5dd7070Spatrick ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
650*12c85518Srobert std::optional<unsigned> NumExpansions) {
651e5dd7070Spatrick if (!Pattern)
652e5dd7070Spatrick return ExprError();
653e5dd7070Spatrick
654e5dd7070Spatrick // C++0x [temp.variadic]p5:
655e5dd7070Spatrick // The pattern of a pack expansion shall name one or more
656e5dd7070Spatrick // parameter packs that are not expanded by a nested pack
657e5dd7070Spatrick // expansion.
658e5dd7070Spatrick if (!Pattern->containsUnexpandedParameterPack()) {
659e5dd7070Spatrick Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
660e5dd7070Spatrick << Pattern->getSourceRange();
661e5dd7070Spatrick CorrectDelayedTyposInExpr(Pattern);
662e5dd7070Spatrick return ExprError();
663e5dd7070Spatrick }
664e5dd7070Spatrick
665e5dd7070Spatrick // Create the pack expansion expression and source-location information.
666e5dd7070Spatrick return new (Context)
667e5dd7070Spatrick PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
668e5dd7070Spatrick }
669e5dd7070Spatrick
CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,SourceRange PatternRange,ArrayRef<UnexpandedParameterPack> Unexpanded,const MultiLevelTemplateArgumentList & TemplateArgs,bool & ShouldExpand,bool & RetainExpansion,std::optional<unsigned> & NumExpansions)670e5dd7070Spatrick bool Sema::CheckParameterPacksForExpansion(
671e5dd7070Spatrick SourceLocation EllipsisLoc, SourceRange PatternRange,
672e5dd7070Spatrick ArrayRef<UnexpandedParameterPack> Unexpanded,
673e5dd7070Spatrick const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
674*12c85518Srobert bool &RetainExpansion, std::optional<unsigned> &NumExpansions) {
675e5dd7070Spatrick ShouldExpand = true;
676e5dd7070Spatrick RetainExpansion = false;
677e5dd7070Spatrick std::pair<IdentifierInfo *, SourceLocation> FirstPack;
678e5dd7070Spatrick bool HaveFirstPack = false;
679*12c85518Srobert std::optional<unsigned> NumPartialExpansions;
680e5dd7070Spatrick SourceLocation PartiallySubstitutedPackLoc;
681e5dd7070Spatrick
682*12c85518Srobert for (UnexpandedParameterPack ParmPack : Unexpanded) {
683e5dd7070Spatrick // Compute the depth and index for this parameter pack.
684e5dd7070Spatrick unsigned Depth = 0, Index = 0;
685e5dd7070Spatrick IdentifierInfo *Name;
686e5dd7070Spatrick bool IsVarDeclPack = false;
687e5dd7070Spatrick
688*12c85518Srobert if (const TemplateTypeParmType *TTP =
689*12c85518Srobert ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
690e5dd7070Spatrick Depth = TTP->getDepth();
691e5dd7070Spatrick Index = TTP->getIndex();
692e5dd7070Spatrick Name = TTP->getIdentifier();
693e5dd7070Spatrick } else {
694*12c85518Srobert NamedDecl *ND = ParmPack.first.get<NamedDecl *>();
695e5dd7070Spatrick if (isa<VarDecl>(ND))
696e5dd7070Spatrick IsVarDeclPack = true;
697e5dd7070Spatrick else
698e5dd7070Spatrick std::tie(Depth, Index) = getDepthAndIndex(ND);
699e5dd7070Spatrick
700e5dd7070Spatrick Name = ND->getIdentifier();
701e5dd7070Spatrick }
702e5dd7070Spatrick
703e5dd7070Spatrick // Determine the size of this argument pack.
704e5dd7070Spatrick unsigned NewPackSize;
705e5dd7070Spatrick if (IsVarDeclPack) {
706e5dd7070Spatrick // Figure out whether we're instantiating to an argument pack or not.
707e5dd7070Spatrick typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
708e5dd7070Spatrick
709*12c85518Srobert llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
710*12c85518Srobert CurrentInstantiationScope->findInstantiationOf(
711*12c85518Srobert ParmPack.first.get<NamedDecl *>());
712e5dd7070Spatrick if (Instantiation->is<DeclArgumentPack *>()) {
713e5dd7070Spatrick // We could expand this function parameter pack.
714e5dd7070Spatrick NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
715e5dd7070Spatrick } else {
716e5dd7070Spatrick // We can't expand this function parameter pack, so we can't expand
717e5dd7070Spatrick // the pack expansion.
718e5dd7070Spatrick ShouldExpand = false;
719e5dd7070Spatrick continue;
720e5dd7070Spatrick }
721e5dd7070Spatrick } else {
722e5dd7070Spatrick // If we don't have a template argument at this depth/index, then we
723e5dd7070Spatrick // cannot expand the pack expansion. Make a note of this, but we still
724e5dd7070Spatrick // want to check any parameter packs we *do* have arguments for.
725e5dd7070Spatrick if (Depth >= TemplateArgs.getNumLevels() ||
726e5dd7070Spatrick !TemplateArgs.hasTemplateArgument(Depth, Index)) {
727e5dd7070Spatrick ShouldExpand = false;
728e5dd7070Spatrick continue;
729e5dd7070Spatrick }
730e5dd7070Spatrick
731e5dd7070Spatrick // Determine the size of the argument pack.
732e5dd7070Spatrick NewPackSize = TemplateArgs(Depth, Index).pack_size();
733e5dd7070Spatrick }
734e5dd7070Spatrick
735e5dd7070Spatrick // C++0x [temp.arg.explicit]p9:
736e5dd7070Spatrick // Template argument deduction can extend the sequence of template
737e5dd7070Spatrick // arguments corresponding to a template parameter pack, even when the
738e5dd7070Spatrick // sequence contains explicitly specified template arguments.
739e5dd7070Spatrick if (!IsVarDeclPack && CurrentInstantiationScope) {
740*12c85518Srobert if (NamedDecl *PartialPack =
741*12c85518Srobert CurrentInstantiationScope->getPartiallySubstitutedPack()) {
742e5dd7070Spatrick unsigned PartialDepth, PartialIndex;
743e5dd7070Spatrick std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
744e5dd7070Spatrick if (PartialDepth == Depth && PartialIndex == Index) {
745e5dd7070Spatrick RetainExpansion = true;
746e5dd7070Spatrick // We don't actually know the new pack size yet.
747e5dd7070Spatrick NumPartialExpansions = NewPackSize;
748*12c85518Srobert PartiallySubstitutedPackLoc = ParmPack.second;
749e5dd7070Spatrick continue;
750e5dd7070Spatrick }
751e5dd7070Spatrick }
752e5dd7070Spatrick }
753e5dd7070Spatrick
754e5dd7070Spatrick if (!NumExpansions) {
755e5dd7070Spatrick // The is the first pack we've seen for which we have an argument.
756e5dd7070Spatrick // Record it.
757e5dd7070Spatrick NumExpansions = NewPackSize;
758e5dd7070Spatrick FirstPack.first = Name;
759*12c85518Srobert FirstPack.second = ParmPack.second;
760e5dd7070Spatrick HaveFirstPack = true;
761e5dd7070Spatrick continue;
762e5dd7070Spatrick }
763e5dd7070Spatrick
764e5dd7070Spatrick if (NewPackSize != *NumExpansions) {
765e5dd7070Spatrick // C++0x [temp.variadic]p5:
766e5dd7070Spatrick // All of the parameter packs expanded by a pack expansion shall have
767e5dd7070Spatrick // the same number of arguments specified.
768e5dd7070Spatrick if (HaveFirstPack)
769e5dd7070Spatrick Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
770e5dd7070Spatrick << FirstPack.first << Name << *NumExpansions << NewPackSize
771*12c85518Srobert << SourceRange(FirstPack.second) << SourceRange(ParmPack.second);
772e5dd7070Spatrick else
773e5dd7070Spatrick Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
774e5dd7070Spatrick << Name << *NumExpansions << NewPackSize
775*12c85518Srobert << SourceRange(ParmPack.second);
776e5dd7070Spatrick return true;
777e5dd7070Spatrick }
778e5dd7070Spatrick }
779e5dd7070Spatrick
780e5dd7070Spatrick // If we're performing a partial expansion but we also have a full expansion,
781e5dd7070Spatrick // expand to the number of common arguments. For example, given:
782e5dd7070Spatrick //
783e5dd7070Spatrick // template<typename ...T> struct A {
784e5dd7070Spatrick // template<typename ...U> void f(pair<T, U>...);
785e5dd7070Spatrick // };
786e5dd7070Spatrick //
787e5dd7070Spatrick // ... a call to 'A<int, int>().f<int>' should expand the pack once and
788e5dd7070Spatrick // retain an expansion.
789e5dd7070Spatrick if (NumPartialExpansions) {
790e5dd7070Spatrick if (NumExpansions && *NumExpansions < *NumPartialExpansions) {
791e5dd7070Spatrick NamedDecl *PartialPack =
792e5dd7070Spatrick CurrentInstantiationScope->getPartiallySubstitutedPack();
793e5dd7070Spatrick Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_partial)
794e5dd7070Spatrick << PartialPack << *NumPartialExpansions << *NumExpansions
795e5dd7070Spatrick << SourceRange(PartiallySubstitutedPackLoc);
796e5dd7070Spatrick return true;
797e5dd7070Spatrick }
798e5dd7070Spatrick
799e5dd7070Spatrick NumExpansions = NumPartialExpansions;
800e5dd7070Spatrick }
801e5dd7070Spatrick
802e5dd7070Spatrick return false;
803e5dd7070Spatrick }
804e5dd7070Spatrick
getNumArgumentsInExpansion(QualType T,const MultiLevelTemplateArgumentList & TemplateArgs)805*12c85518Srobert std::optional<unsigned> Sema::getNumArgumentsInExpansion(
806*12c85518Srobert QualType T, const MultiLevelTemplateArgumentList &TemplateArgs) {
807e5dd7070Spatrick QualType Pattern = cast<PackExpansionType>(T)->getPattern();
808e5dd7070Spatrick SmallVector<UnexpandedParameterPack, 2> Unexpanded;
809e5dd7070Spatrick CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
810e5dd7070Spatrick
811*12c85518Srobert std::optional<unsigned> Result;
812e5dd7070Spatrick for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
813e5dd7070Spatrick // Compute the depth and index for this parameter pack.
814e5dd7070Spatrick unsigned Depth;
815e5dd7070Spatrick unsigned Index;
816e5dd7070Spatrick
817*12c85518Srobert if (const TemplateTypeParmType *TTP =
818*12c85518Srobert Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
819e5dd7070Spatrick Depth = TTP->getDepth();
820e5dd7070Spatrick Index = TTP->getIndex();
821e5dd7070Spatrick } else {
822e5dd7070Spatrick NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
823e5dd7070Spatrick if (isa<VarDecl>(ND)) {
824e5dd7070Spatrick // Function parameter pack or init-capture pack.
825e5dd7070Spatrick typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
826e5dd7070Spatrick
827*12c85518Srobert llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation =
828*12c85518Srobert CurrentInstantiationScope->findInstantiationOf(
829e5dd7070Spatrick Unexpanded[I].first.get<NamedDecl *>());
830e5dd7070Spatrick if (Instantiation->is<Decl *>())
831e5dd7070Spatrick // The pattern refers to an unexpanded pack. We're not ready to expand
832e5dd7070Spatrick // this pack yet.
833*12c85518Srobert return std::nullopt;
834e5dd7070Spatrick
835e5dd7070Spatrick unsigned Size = Instantiation->get<DeclArgumentPack *>()->size();
836e5dd7070Spatrick assert((!Result || *Result == Size) && "inconsistent pack sizes");
837e5dd7070Spatrick Result = Size;
838e5dd7070Spatrick continue;
839e5dd7070Spatrick }
840e5dd7070Spatrick
841e5dd7070Spatrick std::tie(Depth, Index) = getDepthAndIndex(ND);
842e5dd7070Spatrick }
843e5dd7070Spatrick if (Depth >= TemplateArgs.getNumLevels() ||
844e5dd7070Spatrick !TemplateArgs.hasTemplateArgument(Depth, Index))
845e5dd7070Spatrick // The pattern refers to an unknown template argument. We're not ready to
846e5dd7070Spatrick // expand this pack yet.
847*12c85518Srobert return std::nullopt;
848e5dd7070Spatrick
849e5dd7070Spatrick // Determine the size of the argument pack.
850e5dd7070Spatrick unsigned Size = TemplateArgs(Depth, Index).pack_size();
851e5dd7070Spatrick assert((!Result || *Result == Size) && "inconsistent pack sizes");
852e5dd7070Spatrick Result = Size;
853e5dd7070Spatrick }
854e5dd7070Spatrick
855e5dd7070Spatrick return Result;
856e5dd7070Spatrick }
857e5dd7070Spatrick
containsUnexpandedParameterPacks(Declarator & D)858e5dd7070Spatrick bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
859e5dd7070Spatrick const DeclSpec &DS = D.getDeclSpec();
860e5dd7070Spatrick switch (DS.getTypeSpecType()) {
861e5dd7070Spatrick case TST_typename:
862*12c85518Srobert case TST_typeof_unqualType:
863e5dd7070Spatrick case TST_typeofType:
864*12c85518Srobert #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:
865*12c85518Srobert #include "clang/Basic/TransformTypeTraits.def"
866e5dd7070Spatrick case TST_atomic: {
867e5dd7070Spatrick QualType T = DS.getRepAsType().get();
868e5dd7070Spatrick if (!T.isNull() && T->containsUnexpandedParameterPack())
869e5dd7070Spatrick return true;
870e5dd7070Spatrick break;
871e5dd7070Spatrick }
872e5dd7070Spatrick
873*12c85518Srobert case TST_typeof_unqualExpr:
874e5dd7070Spatrick case TST_typeofExpr:
875e5dd7070Spatrick case TST_decltype:
876*12c85518Srobert case TST_bitint:
877e5dd7070Spatrick if (DS.getRepAsExpr() &&
878e5dd7070Spatrick DS.getRepAsExpr()->containsUnexpandedParameterPack())
879e5dd7070Spatrick return true;
880e5dd7070Spatrick break;
881e5dd7070Spatrick
882e5dd7070Spatrick case TST_unspecified:
883e5dd7070Spatrick case TST_void:
884e5dd7070Spatrick case TST_char:
885e5dd7070Spatrick case TST_wchar:
886e5dd7070Spatrick case TST_char8:
887e5dd7070Spatrick case TST_char16:
888e5dd7070Spatrick case TST_char32:
889e5dd7070Spatrick case TST_int:
890e5dd7070Spatrick case TST_int128:
891e5dd7070Spatrick case TST_half:
892e5dd7070Spatrick case TST_float:
893e5dd7070Spatrick case TST_double:
894e5dd7070Spatrick case TST_Accum:
895e5dd7070Spatrick case TST_Fract:
896e5dd7070Spatrick case TST_Float16:
897e5dd7070Spatrick case TST_float128:
898*12c85518Srobert case TST_ibm128:
899e5dd7070Spatrick case TST_bool:
900e5dd7070Spatrick case TST_decimal32:
901e5dd7070Spatrick case TST_decimal64:
902e5dd7070Spatrick case TST_decimal128:
903e5dd7070Spatrick case TST_enum:
904e5dd7070Spatrick case TST_union:
905e5dd7070Spatrick case TST_struct:
906e5dd7070Spatrick case TST_interface:
907e5dd7070Spatrick case TST_class:
908e5dd7070Spatrick case TST_auto:
909e5dd7070Spatrick case TST_auto_type:
910e5dd7070Spatrick case TST_decltype_auto:
911ec727ea7Spatrick case TST_BFloat16:
912e5dd7070Spatrick #define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:
913e5dd7070Spatrick #include "clang/Basic/OpenCLImageTypes.def"
914e5dd7070Spatrick case TST_unknown_anytype:
915e5dd7070Spatrick case TST_error:
916e5dd7070Spatrick break;
917e5dd7070Spatrick }
918e5dd7070Spatrick
919e5dd7070Spatrick for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
920e5dd7070Spatrick const DeclaratorChunk &Chunk = D.getTypeObject(I);
921e5dd7070Spatrick switch (Chunk.Kind) {
922e5dd7070Spatrick case DeclaratorChunk::Pointer:
923e5dd7070Spatrick case DeclaratorChunk::Reference:
924e5dd7070Spatrick case DeclaratorChunk::Paren:
925e5dd7070Spatrick case DeclaratorChunk::Pipe:
926e5dd7070Spatrick case DeclaratorChunk::BlockPointer:
927e5dd7070Spatrick // These declarator chunks cannot contain any parameter packs.
928e5dd7070Spatrick break;
929e5dd7070Spatrick
930e5dd7070Spatrick case DeclaratorChunk::Array:
931e5dd7070Spatrick if (Chunk.Arr.NumElts &&
932e5dd7070Spatrick Chunk.Arr.NumElts->containsUnexpandedParameterPack())
933e5dd7070Spatrick return true;
934e5dd7070Spatrick break;
935e5dd7070Spatrick case DeclaratorChunk::Function:
936e5dd7070Spatrick for (unsigned i = 0, e = Chunk.Fun.NumParams; i != e; ++i) {
937e5dd7070Spatrick ParmVarDecl *Param = cast<ParmVarDecl>(Chunk.Fun.Params[i].Param);
938e5dd7070Spatrick QualType ParamTy = Param->getType();
939e5dd7070Spatrick assert(!ParamTy.isNull() && "Couldn't parse type?");
940e5dd7070Spatrick if (ParamTy->containsUnexpandedParameterPack()) return true;
941e5dd7070Spatrick }
942e5dd7070Spatrick
943e5dd7070Spatrick if (Chunk.Fun.getExceptionSpecType() == EST_Dynamic) {
944e5dd7070Spatrick for (unsigned i = 0; i != Chunk.Fun.getNumExceptions(); ++i) {
945e5dd7070Spatrick if (Chunk.Fun.Exceptions[i]
946e5dd7070Spatrick .Ty.get()
947e5dd7070Spatrick ->containsUnexpandedParameterPack())
948e5dd7070Spatrick return true;
949e5dd7070Spatrick }
950e5dd7070Spatrick } else if (isComputedNoexcept(Chunk.Fun.getExceptionSpecType()) &&
951e5dd7070Spatrick Chunk.Fun.NoexceptExpr->containsUnexpandedParameterPack())
952e5dd7070Spatrick return true;
953e5dd7070Spatrick
954e5dd7070Spatrick if (Chunk.Fun.hasTrailingReturnType()) {
955e5dd7070Spatrick QualType T = Chunk.Fun.getTrailingReturnType().get();
956e5dd7070Spatrick if (!T.isNull() && T->containsUnexpandedParameterPack())
957e5dd7070Spatrick return true;
958e5dd7070Spatrick }
959e5dd7070Spatrick break;
960e5dd7070Spatrick
961e5dd7070Spatrick case DeclaratorChunk::MemberPointer:
962e5dd7070Spatrick if (Chunk.Mem.Scope().getScopeRep() &&
963e5dd7070Spatrick Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
964e5dd7070Spatrick return true;
965e5dd7070Spatrick break;
966e5dd7070Spatrick }
967e5dd7070Spatrick }
968e5dd7070Spatrick
969e5dd7070Spatrick if (Expr *TRC = D.getTrailingRequiresClause())
970e5dd7070Spatrick if (TRC->containsUnexpandedParameterPack())
971e5dd7070Spatrick return true;
972e5dd7070Spatrick
973e5dd7070Spatrick return false;
974e5dd7070Spatrick }
975e5dd7070Spatrick
976e5dd7070Spatrick namespace {
977e5dd7070Spatrick
978e5dd7070Spatrick // Callback to only accept typo corrections that refer to parameter packs.
979e5dd7070Spatrick class ParameterPackValidatorCCC final : public CorrectionCandidateCallback {
980e5dd7070Spatrick public:
ValidateCandidate(const TypoCorrection & candidate)981e5dd7070Spatrick bool ValidateCandidate(const TypoCorrection &candidate) override {
982e5dd7070Spatrick NamedDecl *ND = candidate.getCorrectionDecl();
983e5dd7070Spatrick return ND && ND->isParameterPack();
984e5dd7070Spatrick }
985e5dd7070Spatrick
clone()986e5dd7070Spatrick std::unique_ptr<CorrectionCandidateCallback> clone() override {
987e5dd7070Spatrick return std::make_unique<ParameterPackValidatorCCC>(*this);
988e5dd7070Spatrick }
989e5dd7070Spatrick };
990e5dd7070Spatrick
991e5dd7070Spatrick }
992e5dd7070Spatrick
993e5dd7070Spatrick /// Called when an expression computing the size of a parameter pack
994e5dd7070Spatrick /// is parsed.
995e5dd7070Spatrick ///
996e5dd7070Spatrick /// \code
997e5dd7070Spatrick /// template<typename ...Types> struct count {
998e5dd7070Spatrick /// static const unsigned value = sizeof...(Types);
999e5dd7070Spatrick /// };
1000e5dd7070Spatrick /// \endcode
1001e5dd7070Spatrick ///
1002e5dd7070Spatrick //
1003e5dd7070Spatrick /// \param OpLoc The location of the "sizeof" keyword.
1004e5dd7070Spatrick /// \param Name The name of the parameter pack whose size will be determined.
1005e5dd7070Spatrick /// \param NameLoc The source location of the name of the parameter pack.
1006e5dd7070Spatrick /// \param RParenLoc The location of the closing parentheses.
ActOnSizeofParameterPackExpr(Scope * S,SourceLocation OpLoc,IdentifierInfo & Name,SourceLocation NameLoc,SourceLocation RParenLoc)1007e5dd7070Spatrick ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
1008e5dd7070Spatrick SourceLocation OpLoc,
1009e5dd7070Spatrick IdentifierInfo &Name,
1010e5dd7070Spatrick SourceLocation NameLoc,
1011e5dd7070Spatrick SourceLocation RParenLoc) {
1012e5dd7070Spatrick // C++0x [expr.sizeof]p5:
1013e5dd7070Spatrick // The identifier in a sizeof... expression shall name a parameter pack.
1014e5dd7070Spatrick LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
1015e5dd7070Spatrick LookupName(R, S);
1016e5dd7070Spatrick
1017e5dd7070Spatrick NamedDecl *ParameterPack = nullptr;
1018e5dd7070Spatrick switch (R.getResultKind()) {
1019e5dd7070Spatrick case LookupResult::Found:
1020e5dd7070Spatrick ParameterPack = R.getFoundDecl();
1021e5dd7070Spatrick break;
1022e5dd7070Spatrick
1023e5dd7070Spatrick case LookupResult::NotFound:
1024e5dd7070Spatrick case LookupResult::NotFoundInCurrentInstantiation: {
1025e5dd7070Spatrick ParameterPackValidatorCCC CCC{};
1026e5dd7070Spatrick if (TypoCorrection Corrected =
1027e5dd7070Spatrick CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, nullptr,
1028e5dd7070Spatrick CCC, CTK_ErrorRecovery)) {
1029e5dd7070Spatrick diagnoseTypo(Corrected,
1030e5dd7070Spatrick PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,
1031e5dd7070Spatrick PDiag(diag::note_parameter_pack_here));
1032e5dd7070Spatrick ParameterPack = Corrected.getCorrectionDecl();
1033e5dd7070Spatrick }
1034e5dd7070Spatrick break;
1035e5dd7070Spatrick }
1036e5dd7070Spatrick case LookupResult::FoundOverloaded:
1037e5dd7070Spatrick case LookupResult::FoundUnresolvedValue:
1038e5dd7070Spatrick break;
1039e5dd7070Spatrick
1040e5dd7070Spatrick case LookupResult::Ambiguous:
1041e5dd7070Spatrick DiagnoseAmbiguousLookup(R);
1042e5dd7070Spatrick return ExprError();
1043e5dd7070Spatrick }
1044e5dd7070Spatrick
1045e5dd7070Spatrick if (!ParameterPack || !ParameterPack->isParameterPack()) {
1046e5dd7070Spatrick Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
1047e5dd7070Spatrick << &Name;
1048e5dd7070Spatrick return ExprError();
1049e5dd7070Spatrick }
1050e5dd7070Spatrick
1051e5dd7070Spatrick MarkAnyDeclReferenced(OpLoc, ParameterPack, true);
1052e5dd7070Spatrick
1053e5dd7070Spatrick return SizeOfPackExpr::Create(Context, OpLoc, ParameterPack, NameLoc,
1054e5dd7070Spatrick RParenLoc);
1055e5dd7070Spatrick }
1056e5dd7070Spatrick
getTemplateArgumentPackExpansionPattern(TemplateArgumentLoc OrigLoc,SourceLocation & Ellipsis,std::optional<unsigned> & NumExpansions) const1057*12c85518Srobert TemplateArgumentLoc Sema::getTemplateArgumentPackExpansionPattern(
1058*12c85518Srobert TemplateArgumentLoc OrigLoc, SourceLocation &Ellipsis,
1059*12c85518Srobert std::optional<unsigned> &NumExpansions) const {
1060e5dd7070Spatrick const TemplateArgument &Argument = OrigLoc.getArgument();
1061e5dd7070Spatrick assert(Argument.isPackExpansion());
1062e5dd7070Spatrick switch (Argument.getKind()) {
1063e5dd7070Spatrick case TemplateArgument::Type: {
1064e5dd7070Spatrick // FIXME: We shouldn't ever have to worry about missing
1065e5dd7070Spatrick // type-source info!
1066e5dd7070Spatrick TypeSourceInfo *ExpansionTSInfo = OrigLoc.getTypeSourceInfo();
1067e5dd7070Spatrick if (!ExpansionTSInfo)
1068e5dd7070Spatrick ExpansionTSInfo = Context.getTrivialTypeSourceInfo(Argument.getAsType(),
1069e5dd7070Spatrick Ellipsis);
1070e5dd7070Spatrick PackExpansionTypeLoc Expansion =
1071e5dd7070Spatrick ExpansionTSInfo->getTypeLoc().castAs<PackExpansionTypeLoc>();
1072e5dd7070Spatrick Ellipsis = Expansion.getEllipsisLoc();
1073e5dd7070Spatrick
1074e5dd7070Spatrick TypeLoc Pattern = Expansion.getPatternLoc();
1075e5dd7070Spatrick NumExpansions = Expansion.getTypePtr()->getNumExpansions();
1076e5dd7070Spatrick
1077e5dd7070Spatrick // We need to copy the TypeLoc because TemplateArgumentLocs store a
1078e5dd7070Spatrick // TypeSourceInfo.
1079e5dd7070Spatrick // FIXME: Find some way to avoid the copy?
1080e5dd7070Spatrick TypeLocBuilder TLB;
1081e5dd7070Spatrick TLB.pushFullCopy(Pattern);
1082e5dd7070Spatrick TypeSourceInfo *PatternTSInfo =
1083e5dd7070Spatrick TLB.getTypeSourceInfo(Context, Pattern.getType());
1084e5dd7070Spatrick return TemplateArgumentLoc(TemplateArgument(Pattern.getType()),
1085e5dd7070Spatrick PatternTSInfo);
1086e5dd7070Spatrick }
1087e5dd7070Spatrick
1088e5dd7070Spatrick case TemplateArgument::Expression: {
1089e5dd7070Spatrick PackExpansionExpr *Expansion
1090e5dd7070Spatrick = cast<PackExpansionExpr>(Argument.getAsExpr());
1091e5dd7070Spatrick Expr *Pattern = Expansion->getPattern();
1092e5dd7070Spatrick Ellipsis = Expansion->getEllipsisLoc();
1093e5dd7070Spatrick NumExpansions = Expansion->getNumExpansions();
1094e5dd7070Spatrick return TemplateArgumentLoc(Pattern, Pattern);
1095e5dd7070Spatrick }
1096e5dd7070Spatrick
1097e5dd7070Spatrick case TemplateArgument::TemplateExpansion:
1098e5dd7070Spatrick Ellipsis = OrigLoc.getTemplateEllipsisLoc();
1099e5dd7070Spatrick NumExpansions = Argument.getNumTemplateExpansions();
1100a9ac8606Spatrick return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(),
1101e5dd7070Spatrick OrigLoc.getTemplateQualifierLoc(),
1102e5dd7070Spatrick OrigLoc.getTemplateNameLoc());
1103e5dd7070Spatrick
1104e5dd7070Spatrick case TemplateArgument::Declaration:
1105e5dd7070Spatrick case TemplateArgument::NullPtr:
1106e5dd7070Spatrick case TemplateArgument::Template:
1107e5dd7070Spatrick case TemplateArgument::Integral:
1108e5dd7070Spatrick case TemplateArgument::Pack:
1109e5dd7070Spatrick case TemplateArgument::Null:
1110e5dd7070Spatrick return TemplateArgumentLoc();
1111e5dd7070Spatrick }
1112e5dd7070Spatrick
1113e5dd7070Spatrick llvm_unreachable("Invalid TemplateArgument Kind!");
1114e5dd7070Spatrick }
1115e5dd7070Spatrick
getFullyPackExpandedSize(TemplateArgument Arg)1116*12c85518Srobert std::optional<unsigned> Sema::getFullyPackExpandedSize(TemplateArgument Arg) {
1117e5dd7070Spatrick assert(Arg.containsUnexpandedParameterPack());
1118e5dd7070Spatrick
1119e5dd7070Spatrick // If this is a substituted pack, grab that pack. If not, we don't know
1120e5dd7070Spatrick // the size yet.
1121e5dd7070Spatrick // FIXME: We could find a size in more cases by looking for a substituted
1122e5dd7070Spatrick // pack anywhere within this argument, but that's not necessary in the common
1123e5dd7070Spatrick // case for 'sizeof...(A)' handling.
1124e5dd7070Spatrick TemplateArgument Pack;
1125e5dd7070Spatrick switch (Arg.getKind()) {
1126e5dd7070Spatrick case TemplateArgument::Type:
1127e5dd7070Spatrick if (auto *Subst = Arg.getAsType()->getAs<SubstTemplateTypeParmPackType>())
1128e5dd7070Spatrick Pack = Subst->getArgumentPack();
1129e5dd7070Spatrick else
1130*12c85518Srobert return std::nullopt;
1131e5dd7070Spatrick break;
1132e5dd7070Spatrick
1133e5dd7070Spatrick case TemplateArgument::Expression:
1134e5dd7070Spatrick if (auto *Subst =
1135e5dd7070Spatrick dyn_cast<SubstNonTypeTemplateParmPackExpr>(Arg.getAsExpr()))
1136e5dd7070Spatrick Pack = Subst->getArgumentPack();
1137e5dd7070Spatrick else if (auto *Subst = dyn_cast<FunctionParmPackExpr>(Arg.getAsExpr())) {
1138e5dd7070Spatrick for (VarDecl *PD : *Subst)
1139e5dd7070Spatrick if (PD->isParameterPack())
1140*12c85518Srobert return std::nullopt;
1141e5dd7070Spatrick return Subst->getNumExpansions();
1142e5dd7070Spatrick } else
1143*12c85518Srobert return std::nullopt;
1144e5dd7070Spatrick break;
1145e5dd7070Spatrick
1146e5dd7070Spatrick case TemplateArgument::Template:
1147e5dd7070Spatrick if (SubstTemplateTemplateParmPackStorage *Subst =
1148e5dd7070Spatrick Arg.getAsTemplate().getAsSubstTemplateTemplateParmPack())
1149e5dd7070Spatrick Pack = Subst->getArgumentPack();
1150e5dd7070Spatrick else
1151*12c85518Srobert return std::nullopt;
1152e5dd7070Spatrick break;
1153e5dd7070Spatrick
1154e5dd7070Spatrick case TemplateArgument::Declaration:
1155e5dd7070Spatrick case TemplateArgument::NullPtr:
1156e5dd7070Spatrick case TemplateArgument::TemplateExpansion:
1157e5dd7070Spatrick case TemplateArgument::Integral:
1158e5dd7070Spatrick case TemplateArgument::Pack:
1159e5dd7070Spatrick case TemplateArgument::Null:
1160*12c85518Srobert return std::nullopt;
1161e5dd7070Spatrick }
1162e5dd7070Spatrick
1163e5dd7070Spatrick // Check that no argument in the pack is itself a pack expansion.
1164e5dd7070Spatrick for (TemplateArgument Elem : Pack.pack_elements()) {
1165e5dd7070Spatrick // There's no point recursing in this case; we would have already
1166e5dd7070Spatrick // expanded this pack expansion into the enclosing pack if we could.
1167e5dd7070Spatrick if (Elem.isPackExpansion())
1168*12c85518Srobert return std::nullopt;
1169e5dd7070Spatrick }
1170e5dd7070Spatrick return Pack.pack_size();
1171e5dd7070Spatrick }
1172e5dd7070Spatrick
CheckFoldOperand(Sema & S,Expr * E)1173e5dd7070Spatrick static void CheckFoldOperand(Sema &S, Expr *E) {
1174e5dd7070Spatrick if (!E)
1175e5dd7070Spatrick return;
1176e5dd7070Spatrick
1177e5dd7070Spatrick E = E->IgnoreImpCasts();
1178e5dd7070Spatrick auto *OCE = dyn_cast<CXXOperatorCallExpr>(E);
1179e5dd7070Spatrick if ((OCE && OCE->isInfixBinaryOp()) || isa<BinaryOperator>(E) ||
1180e5dd7070Spatrick isa<AbstractConditionalOperator>(E)) {
1181e5dd7070Spatrick S.Diag(E->getExprLoc(), diag::err_fold_expression_bad_operand)
1182e5dd7070Spatrick << E->getSourceRange()
1183e5dd7070Spatrick << FixItHint::CreateInsertion(E->getBeginLoc(), "(")
1184e5dd7070Spatrick << FixItHint::CreateInsertion(E->getEndLoc(), ")");
1185e5dd7070Spatrick }
1186e5dd7070Spatrick }
1187e5dd7070Spatrick
ActOnCXXFoldExpr(Scope * S,SourceLocation LParenLoc,Expr * LHS,tok::TokenKind Operator,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc)1188a9ac8606Spatrick ExprResult Sema::ActOnCXXFoldExpr(Scope *S, SourceLocation LParenLoc, Expr *LHS,
1189e5dd7070Spatrick tok::TokenKind Operator,
1190e5dd7070Spatrick SourceLocation EllipsisLoc, Expr *RHS,
1191e5dd7070Spatrick SourceLocation RParenLoc) {
1192e5dd7070Spatrick // LHS and RHS must be cast-expressions. We allow an arbitrary expression
1193e5dd7070Spatrick // in the parser and reduce down to just cast-expressions here.
1194e5dd7070Spatrick CheckFoldOperand(*this, LHS);
1195e5dd7070Spatrick CheckFoldOperand(*this, RHS);
1196e5dd7070Spatrick
1197e5dd7070Spatrick auto DiscardOperands = [&] {
1198e5dd7070Spatrick CorrectDelayedTyposInExpr(LHS);
1199e5dd7070Spatrick CorrectDelayedTyposInExpr(RHS);
1200e5dd7070Spatrick };
1201e5dd7070Spatrick
1202e5dd7070Spatrick // [expr.prim.fold]p3:
1203e5dd7070Spatrick // In a binary fold, op1 and op2 shall be the same fold-operator, and
1204e5dd7070Spatrick // either e1 shall contain an unexpanded parameter pack or e2 shall contain
1205e5dd7070Spatrick // an unexpanded parameter pack, but not both.
1206e5dd7070Spatrick if (LHS && RHS &&
1207e5dd7070Spatrick LHS->containsUnexpandedParameterPack() ==
1208e5dd7070Spatrick RHS->containsUnexpandedParameterPack()) {
1209e5dd7070Spatrick DiscardOperands();
1210e5dd7070Spatrick return Diag(EllipsisLoc,
1211e5dd7070Spatrick LHS->containsUnexpandedParameterPack()
1212e5dd7070Spatrick ? diag::err_fold_expression_packs_both_sides
1213e5dd7070Spatrick : diag::err_pack_expansion_without_parameter_packs)
1214e5dd7070Spatrick << LHS->getSourceRange() << RHS->getSourceRange();
1215e5dd7070Spatrick }
1216e5dd7070Spatrick
1217e5dd7070Spatrick // [expr.prim.fold]p2:
1218e5dd7070Spatrick // In a unary fold, the cast-expression shall contain an unexpanded
1219e5dd7070Spatrick // parameter pack.
1220e5dd7070Spatrick if (!LHS || !RHS) {
1221e5dd7070Spatrick Expr *Pack = LHS ? LHS : RHS;
1222e5dd7070Spatrick assert(Pack && "fold expression with neither LHS nor RHS");
1223e5dd7070Spatrick DiscardOperands();
1224e5dd7070Spatrick if (!Pack->containsUnexpandedParameterPack())
1225e5dd7070Spatrick return Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
1226e5dd7070Spatrick << Pack->getSourceRange();
1227e5dd7070Spatrick }
1228e5dd7070Spatrick
1229e5dd7070Spatrick BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Operator);
1230a9ac8606Spatrick
1231a9ac8606Spatrick // Perform first-phase name lookup now.
1232a9ac8606Spatrick UnresolvedLookupExpr *ULE = nullptr;
1233a9ac8606Spatrick {
1234a9ac8606Spatrick UnresolvedSet<16> Functions;
1235a9ac8606Spatrick LookupBinOp(S, EllipsisLoc, Opc, Functions);
1236a9ac8606Spatrick if (!Functions.empty()) {
1237a9ac8606Spatrick DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(
1238a9ac8606Spatrick BinaryOperator::getOverloadedOperator(Opc));
1239a9ac8606Spatrick ExprResult Callee = CreateUnresolvedLookupExpr(
1240a9ac8606Spatrick /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
1241a9ac8606Spatrick DeclarationNameInfo(OpName, EllipsisLoc), Functions);
1242a9ac8606Spatrick if (Callee.isInvalid())
1243a9ac8606Spatrick return ExprError();
1244a9ac8606Spatrick ULE = cast<UnresolvedLookupExpr>(Callee.get());
1245a9ac8606Spatrick }
1246a9ac8606Spatrick }
1247a9ac8606Spatrick
1248a9ac8606Spatrick return BuildCXXFoldExpr(ULE, LParenLoc, LHS, Opc, EllipsisLoc, RHS, RParenLoc,
1249*12c85518Srobert std::nullopt);
1250e5dd7070Spatrick }
1251e5dd7070Spatrick
BuildCXXFoldExpr(UnresolvedLookupExpr * Callee,SourceLocation LParenLoc,Expr * LHS,BinaryOperatorKind Operator,SourceLocation EllipsisLoc,Expr * RHS,SourceLocation RParenLoc,std::optional<unsigned> NumExpansions)1252a9ac8606Spatrick ExprResult Sema::BuildCXXFoldExpr(UnresolvedLookupExpr *Callee,
1253a9ac8606Spatrick SourceLocation LParenLoc, Expr *LHS,
1254e5dd7070Spatrick BinaryOperatorKind Operator,
1255e5dd7070Spatrick SourceLocation EllipsisLoc, Expr *RHS,
1256e5dd7070Spatrick SourceLocation RParenLoc,
1257*12c85518Srobert std::optional<unsigned> NumExpansions) {
1258a9ac8606Spatrick return new (Context)
1259a9ac8606Spatrick CXXFoldExpr(Context.DependentTy, Callee, LParenLoc, LHS, Operator,
1260a9ac8606Spatrick EllipsisLoc, RHS, RParenLoc, NumExpansions);
1261e5dd7070Spatrick }
1262e5dd7070Spatrick
BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,BinaryOperatorKind Operator)1263e5dd7070Spatrick ExprResult Sema::BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
1264e5dd7070Spatrick BinaryOperatorKind Operator) {
1265e5dd7070Spatrick // [temp.variadic]p9:
1266e5dd7070Spatrick // If N is zero for a unary fold-expression, the value of the expression is
1267e5dd7070Spatrick // && -> true
1268e5dd7070Spatrick // || -> false
1269e5dd7070Spatrick // , -> void()
1270e5dd7070Spatrick // if the operator is not listed [above], the instantiation is ill-formed.
1271e5dd7070Spatrick //
1272e5dd7070Spatrick // Note that we need to use something like int() here, not merely 0, to
1273e5dd7070Spatrick // prevent the result from being a null pointer constant.
1274e5dd7070Spatrick QualType ScalarType;
1275e5dd7070Spatrick switch (Operator) {
1276e5dd7070Spatrick case BO_LOr:
1277e5dd7070Spatrick return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_false);
1278e5dd7070Spatrick case BO_LAnd:
1279e5dd7070Spatrick return ActOnCXXBoolLiteral(EllipsisLoc, tok::kw_true);
1280e5dd7070Spatrick case BO_Comma:
1281e5dd7070Spatrick ScalarType = Context.VoidTy;
1282e5dd7070Spatrick break;
1283e5dd7070Spatrick
1284e5dd7070Spatrick default:
1285e5dd7070Spatrick return Diag(EllipsisLoc, diag::err_fold_expression_empty)
1286e5dd7070Spatrick << BinaryOperator::getOpcodeStr(Operator);
1287e5dd7070Spatrick }
1288e5dd7070Spatrick
1289e5dd7070Spatrick return new (Context) CXXScalarValueInitExpr(
1290e5dd7070Spatrick ScalarType, Context.getTrivialTypeSourceInfo(ScalarType, EllipsisLoc),
1291e5dd7070Spatrick EllipsisLoc);
1292e5dd7070Spatrick }
1293