blob: a40100c7a726279254606bd038740ca9328478ff [file] [log] [blame]
Douglas Gregorc4633352010-12-15 17:38:57 +00001//===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//===----------------------------------------------------------------------===/
8//
9// This file implements semantic analysis for C++0x variadic templates.
10//===----------------------------------------------------------------------===/
11
12#include "clang/Sema/Sema.h"
Douglas Gregoree8aff02011-01-04 17:33:58 +000013#include "clang/Sema/Lookup.h"
Douglas Gregor7536dd52010-12-20 02:24:11 +000014#include "clang/Sema/ParsedTemplate.h"
Douglas Gregorc4633352010-12-15 17:38:57 +000015#include "clang/Sema/SemaInternal.h"
Douglas Gregor8491ffe2010-12-20 22:05:00 +000016#include "clang/Sema/Template.h"
Douglas Gregorc4633352010-12-15 17:38:57 +000017#include "clang/AST/Expr.h"
Douglas Gregor9ef75892010-12-15 19:43:21 +000018#include "clang/AST/RecursiveASTVisitor.h"
Douglas Gregorc4633352010-12-15 17:38:57 +000019#include "clang/AST/TypeLoc.h"
20
21using namespace clang;
22
Douglas Gregor9ef75892010-12-15 19:43:21 +000023//----------------------------------------------------------------------------
24// Visitor that collects unexpanded parameter packs
25//----------------------------------------------------------------------------
26
Douglas Gregor9ef75892010-12-15 19:43:21 +000027namespace {
28 /// \brief A class that collects unexpanded parameter packs.
29 class CollectUnexpandedParameterPacksVisitor :
30 public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
31 {
32 typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
33 inherited;
34
Chris Lattner5f9e2722011-07-23 10:55:15 +000035 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
Douglas Gregor9ef75892010-12-15 19:43:21 +000036
37 public:
38 explicit CollectUnexpandedParameterPacksVisitor(
Chris Lattner5f9e2722011-07-23 10:55:15 +000039 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
Douglas Gregor9ef75892010-12-15 19:43:21 +000040 : Unexpanded(Unexpanded) { }
41
Douglas Gregora40bc722010-12-20 23:07:20 +000042 bool shouldWalkTypesOfTypeLocs() const { return false; }
43
Douglas Gregor9ef75892010-12-15 19:43:21 +000044 //------------------------------------------------------------------------
45 // Recording occurrences of (unexpanded) parameter packs.
46 //------------------------------------------------------------------------
47
48 /// \brief Record occurrences of template type parameter packs.
49 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
50 if (TL.getTypePtr()->isParameterPack())
51 Unexpanded.push_back(std::make_pair(TL.getTypePtr(), TL.getNameLoc()));
52 return true;
53 }
54
55 /// \brief Record occurrences of template type parameter packs
56 /// when we don't have proper source-location information for
57 /// them.
58 ///
59 /// Ideally, this routine would never be used.
60 bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
61 if (T->isParameterPack())
62 Unexpanded.push_back(std::make_pair(T, SourceLocation()));
63
64 return true;
65 }
66
Douglas Gregora779d9c2011-01-19 21:32:01 +000067 /// \brief Record occurrences of function and non-type template
Douglas Gregor10738d32010-12-23 23:51:58 +000068 /// parameter packs in an expression.
69 bool VisitDeclRefExpr(DeclRefExpr *E) {
Douglas Gregor12c9c002011-01-07 16:43:16 +000070 if (E->getDecl()->isParameterPack())
71 Unexpanded.push_back(std::make_pair(E->getDecl(), E->getLocation()));
Douglas Gregor10738d32010-12-23 23:51:58 +000072
73 return true;
74 }
75
Douglas Gregor61c4d282011-01-05 15:48:55 +000076 /// \brief Record occurrences of template template parameter packs.
77 bool TraverseTemplateName(TemplateName Template) {
78 if (TemplateTemplateParmDecl *TTP
79 = dyn_cast_or_null<TemplateTemplateParmDecl>(
80 Template.getAsTemplateDecl()))
81 if (TTP->isParameterPack())
82 Unexpanded.push_back(std::make_pair(TTP, SourceLocation()));
83
84 return inherited::TraverseTemplateName(Template);
85 }
Douglas Gregor9ef75892010-12-15 19:43:21 +000086
Ted Kremenekebcb57a2012-03-06 20:05:56 +000087 /// \brief Suppress traversal into Objective-C container literal
88 /// elements that are pack expansions.
89 bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
90 if (!E->containsUnexpandedParameterPack())
91 return true;
92
93 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
94 ObjCDictionaryElement Element = E->getKeyValueElement(I);
95 if (Element.isPackExpansion())
96 continue;
97
98 TraverseStmt(Element.Key);
99 TraverseStmt(Element.Value);
100 }
101 return true;
102 }
Douglas Gregor9ef75892010-12-15 19:43:21 +0000103 //------------------------------------------------------------------------
104 // Pruning the search for unexpanded parameter packs.
105 //------------------------------------------------------------------------
106
107 /// \brief Suppress traversal into statements and expressions that
108 /// do not contain unexpanded parameter packs.
109 bool TraverseStmt(Stmt *S) {
110 if (Expr *E = dyn_cast_or_null<Expr>(S))
111 if (E->containsUnexpandedParameterPack())
112 return inherited::TraverseStmt(E);
113
114 return true;
115 }
116
117 /// \brief Suppress traversal into types that do not contain
118 /// unexpanded parameter packs.
119 bool TraverseType(QualType T) {
120 if (!T.isNull() && T->containsUnexpandedParameterPack())
121 return inherited::TraverseType(T);
122
123 return true;
124 }
125
126 /// \brief Suppress traversel into types with location information
127 /// that do not contain unexpanded parameter packs.
128 bool TraverseTypeLoc(TypeLoc TL) {
Douglas Gregor10738d32010-12-23 23:51:58 +0000129 if (!TL.getType().isNull() &&
130 TL.getType()->containsUnexpandedParameterPack())
Douglas Gregor9ef75892010-12-15 19:43:21 +0000131 return inherited::TraverseTypeLoc(TL);
132
133 return true;
134 }
135
Douglas Gregorcff163e2010-12-15 21:57:59 +0000136 /// \brief Suppress traversal of non-parameter declarations, since
137 /// they cannot contain unexpanded parameter packs.
138 bool TraverseDecl(Decl *D) {
139 if (D && isa<ParmVarDecl>(D))
140 return inherited::TraverseDecl(D);
141
142 return true;
143 }
Douglas Gregorba68eca2011-01-05 17:40:24 +0000144
145 /// \brief Suppress traversal of template argument pack expansions.
146 bool TraverseTemplateArgument(const TemplateArgument &Arg) {
147 if (Arg.isPackExpansion())
148 return true;
149
150 return inherited::TraverseTemplateArgument(Arg);
151 }
152
153 /// \brief Suppress traversal of template argument pack expansions.
154 bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
155 if (ArgLoc.getArgument().isPackExpansion())
156 return true;
157
158 return inherited::TraverseTemplateArgumentLoc(ArgLoc);
159 }
Douglas Gregor9ef75892010-12-15 19:43:21 +0000160 };
161}
162
163/// \brief Diagnose all of the unexpanded parameter packs in the given
164/// vector.
Douglas Gregor65019ac2011-10-25 03:44:56 +0000165void
166Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
167 UnexpandedParameterPackContext UPPC,
Bill Wendling4fe5be02012-02-22 09:38:11 +0000168 ArrayRef<UnexpandedParameterPack> Unexpanded) {
Douglas Gregor65019ac2011-10-25 03:44:56 +0000169 if (Unexpanded.empty())
170 return;
171
Chris Lattner5f9e2722011-07-23 10:55:15 +0000172 SmallVector<SourceLocation, 4> Locations;
173 SmallVector<IdentifierInfo *, 4> Names;
Douglas Gregor9ef75892010-12-15 19:43:21 +0000174 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
175
176 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
177 IdentifierInfo *Name = 0;
178 if (const TemplateTypeParmType *TTP
179 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
Chandler Carruthb7efff42011-05-01 01:05:51 +0000180 Name = TTP->getIdentifier();
Douglas Gregor9ef75892010-12-15 19:43:21 +0000181 else
182 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
183
184 if (Name && NamesKnown.insert(Name))
185 Names.push_back(Name);
186
187 if (Unexpanded[I].second.isValid())
188 Locations.push_back(Unexpanded[I].second);
189 }
190
191 DiagnosticBuilder DB
Douglas Gregor65019ac2011-10-25 03:44:56 +0000192 = Names.size() == 0? Diag(Loc, diag::err_unexpanded_parameter_pack_0)
Douglas Gregor9ef75892010-12-15 19:43:21 +0000193 << (int)UPPC
Douglas Gregor65019ac2011-10-25 03:44:56 +0000194 : Names.size() == 1? Diag(Loc, diag::err_unexpanded_parameter_pack_1)
Douglas Gregor9ef75892010-12-15 19:43:21 +0000195 << (int)UPPC << Names[0]
Douglas Gregor65019ac2011-10-25 03:44:56 +0000196 : Names.size() == 2? Diag(Loc, diag::err_unexpanded_parameter_pack_2)
Douglas Gregor9ef75892010-12-15 19:43:21 +0000197 << (int)UPPC << Names[0] << Names[1]
Douglas Gregor65019ac2011-10-25 03:44:56 +0000198 : Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
Douglas Gregor9ef75892010-12-15 19:43:21 +0000199 << (int)UPPC << Names[0] << Names[1];
200
201 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
202 DB << SourceRange(Locations[I]);
203}
204
Douglas Gregorc4633352010-12-15 17:38:57 +0000205bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
206 TypeSourceInfo *T,
207 UnexpandedParameterPackContext UPPC) {
208 // C++0x [temp.variadic]p5:
209 // An appearance of a name of a parameter pack that is not expanded is
210 // ill-formed.
211 if (!T->getType()->containsUnexpandedParameterPack())
212 return false;
213
Chris Lattner5f9e2722011-07-23 10:55:15 +0000214 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
Douglas Gregor9ef75892010-12-15 19:43:21 +0000215 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
216 T->getTypeLoc());
217 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
Douglas Gregor65019ac2011-10-25 03:44:56 +0000218 DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
Douglas Gregorc4633352010-12-15 17:38:57 +0000219 return true;
220}
221
222bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
Douglas Gregor56c04582010-12-16 00:46:58 +0000223 UnexpandedParameterPackContext UPPC) {
Douglas Gregorc4633352010-12-15 17:38:57 +0000224 // C++0x [temp.variadic]p5:
225 // An appearance of a name of a parameter pack that is not expanded is
226 // ill-formed.
227 if (!E->containsUnexpandedParameterPack())
228 return false;
229
Chris Lattner5f9e2722011-07-23 10:55:15 +0000230 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
Douglas Gregor9ef75892010-12-15 19:43:21 +0000231 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
232 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
Douglas Gregor65019ac2011-10-25 03:44:56 +0000233 DiagnoseUnexpandedParameterPacks(E->getLocStart(), UPPC, Unexpanded);
Douglas Gregorc4633352010-12-15 17:38:57 +0000234 return true;
235}
Douglas Gregor56c04582010-12-16 00:46:58 +0000236
237bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
238 UnexpandedParameterPackContext UPPC) {
239 // C++0x [temp.variadic]p5:
240 // An appearance of a name of a parameter pack that is not expanded is
241 // ill-formed.
242 if (!SS.getScopeRep() ||
243 !SS.getScopeRep()->containsUnexpandedParameterPack())
244 return false;
245
Chris Lattner5f9e2722011-07-23 10:55:15 +0000246 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
Douglas Gregor56c04582010-12-16 00:46:58 +0000247 CollectUnexpandedParameterPacksVisitor(Unexpanded)
248 .TraverseNestedNameSpecifier(SS.getScopeRep());
249 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
Douglas Gregor65019ac2011-10-25 03:44:56 +0000250 DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
Douglas Gregor56c04582010-12-16 00:46:58 +0000251 UPPC, Unexpanded);
252 return true;
253}
254
255bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
256 UnexpandedParameterPackContext UPPC) {
257 // C++0x [temp.variadic]p5:
258 // An appearance of a name of a parameter pack that is not expanded is
259 // ill-formed.
260 switch (NameInfo.getName().getNameKind()) {
261 case DeclarationName::Identifier:
262 case DeclarationName::ObjCZeroArgSelector:
263 case DeclarationName::ObjCOneArgSelector:
264 case DeclarationName::ObjCMultiArgSelector:
265 case DeclarationName::CXXOperatorName:
266 case DeclarationName::CXXLiteralOperatorName:
267 case DeclarationName::CXXUsingDirective:
268 return false;
269
270 case DeclarationName::CXXConstructorName:
271 case DeclarationName::CXXDestructorName:
272 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor099ffe82010-12-16 17:19:19 +0000273 // FIXME: We shouldn't need this null check!
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000274 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
275 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
276
277 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
Douglas Gregor56c04582010-12-16 00:46:58 +0000278 return false;
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000279
Douglas Gregor56c04582010-12-16 00:46:58 +0000280 break;
281 }
282
Chris Lattner5f9e2722011-07-23 10:55:15 +0000283 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
Douglas Gregor56c04582010-12-16 00:46:58 +0000284 CollectUnexpandedParameterPacksVisitor(Unexpanded)
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000285 .TraverseType(NameInfo.getName().getCXXNameType());
Douglas Gregor56c04582010-12-16 00:46:58 +0000286 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
Douglas Gregor65019ac2011-10-25 03:44:56 +0000287 DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
Douglas Gregor56c04582010-12-16 00:46:58 +0000288 return true;
289}
Douglas Gregor6f526752010-12-16 08:48:57 +0000290
291bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
292 TemplateName Template,
293 UnexpandedParameterPackContext UPPC) {
294
295 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
296 return false;
297
Chris Lattner5f9e2722011-07-23 10:55:15 +0000298 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
Douglas Gregor6f526752010-12-16 08:48:57 +0000299 CollectUnexpandedParameterPacksVisitor(Unexpanded)
300 .TraverseTemplateName(Template);
301 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
Douglas Gregor65019ac2011-10-25 03:44:56 +0000302 DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
Douglas Gregor6f526752010-12-16 08:48:57 +0000303 return true;
304}
305
Douglas Gregor925910d2011-01-03 20:35:03 +0000306bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
307 UnexpandedParameterPackContext UPPC) {
308 if (Arg.getArgument().isNull() ||
309 !Arg.getArgument().containsUnexpandedParameterPack())
310 return false;
311
Chris Lattner5f9e2722011-07-23 10:55:15 +0000312 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
Douglas Gregor925910d2011-01-03 20:35:03 +0000313 CollectUnexpandedParameterPacksVisitor(Unexpanded)
314 .TraverseTemplateArgumentLoc(Arg);
315 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
Douglas Gregor65019ac2011-10-25 03:44:56 +0000316 DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
Douglas Gregor925910d2011-01-03 20:35:03 +0000317 return true;
318}
319
Douglas Gregore02e2622010-12-22 21:19:48 +0000320void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000321 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
Douglas Gregore02e2622010-12-22 21:19:48 +0000322 CollectUnexpandedParameterPacksVisitor(Unexpanded)
323 .TraverseTemplateArgument(Arg);
324}
325
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000326void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000327 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000328 CollectUnexpandedParameterPacksVisitor(Unexpanded)
329 .TraverseTemplateArgumentLoc(Arg);
330}
331
Douglas Gregorb99268b2010-12-21 00:52:54 +0000332void Sema::collectUnexpandedParameterPacks(QualType T,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000333 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
Douglas Gregorb99268b2010-12-21 00:52:54 +0000334 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
335}
336
Douglas Gregorf90b27a2011-01-03 22:36:02 +0000337void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
Chris Lattner5f9e2722011-07-23 10:55:15 +0000338 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
Douglas Gregorf90b27a2011-01-03 22:36:02 +0000339 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
340}
341
Douglas Gregor65019ac2011-10-25 03:44:56 +0000342void Sema::collectUnexpandedParameterPacks(CXXScopeSpec &SS,
343 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
344 NestedNameSpecifier *Qualifier = SS.getScopeRep();
345 if (!Qualifier)
346 return;
347
348 NestedNameSpecifierLoc QualifierLoc(Qualifier, SS.location_data());
349 CollectUnexpandedParameterPacksVisitor(Unexpanded)
350 .TraverseNestedNameSpecifierLoc(QualifierLoc);
351}
352
353void Sema::collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
354 SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
355 CollectUnexpandedParameterPacksVisitor(Unexpanded)
356 .TraverseDeclarationNameInfo(NameInfo);
357}
358
359
Douglas Gregor7536dd52010-12-20 02:24:11 +0000360ParsedTemplateArgument
361Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
362 SourceLocation EllipsisLoc) {
363 if (Arg.isInvalid())
364 return Arg;
365
366 switch (Arg.getKind()) {
367 case ParsedTemplateArgument::Type: {
368 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
369 if (Result.isInvalid())
370 return ParsedTemplateArgument();
371
372 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
373 Arg.getLocation());
374 }
375
Douglas Gregorbe230c32011-01-03 17:17:50 +0000376 case ParsedTemplateArgument::NonType: {
377 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
378 if (Result.isInvalid())
379 return ParsedTemplateArgument();
380
381 return ParsedTemplateArgument(Arg.getKind(), Result.get(),
382 Arg.getLocation());
383 }
384
Douglas Gregor7536dd52010-12-20 02:24:11 +0000385 case ParsedTemplateArgument::Template:
Douglas Gregorba68eca2011-01-05 17:40:24 +0000386 if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
387 SourceRange R(Arg.getLocation());
388 if (Arg.getScopeSpec().isValid())
389 R.setBegin(Arg.getScopeSpec().getBeginLoc());
390 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
391 << R;
392 return ParsedTemplateArgument();
393 }
394
395 return Arg.getTemplatePackExpansion(EllipsisLoc);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000396 }
397 llvm_unreachable("Unhandled template argument kind?");
Douglas Gregor7536dd52010-12-20 02:24:11 +0000398}
399
400TypeResult Sema::ActOnPackExpansion(ParsedType Type,
401 SourceLocation EllipsisLoc) {
402 TypeSourceInfo *TSInfo;
403 GetTypeFromParser(Type, &TSInfo);
404 if (!TSInfo)
405 return true;
406
Douglas Gregorcded4f62011-01-14 17:04:44 +0000407 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc,
408 llvm::Optional<unsigned>());
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000409 if (!TSResult)
410 return true;
411
412 return CreateParsedType(TSResult->getType(), TSResult);
413}
414
415TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
Douglas Gregorcded4f62011-01-14 17:04:44 +0000416 SourceLocation EllipsisLoc,
417 llvm::Optional<unsigned> NumExpansions) {
Douglas Gregor7536dd52010-12-20 02:24:11 +0000418 // Create the pack expansion type and source-location information.
Douglas Gregor2fc1bb72011-01-12 17:07:58 +0000419 QualType Result = CheckPackExpansion(Pattern->getType(),
420 Pattern->getTypeLoc().getSourceRange(),
Douglas Gregorcded4f62011-01-14 17:04:44 +0000421 EllipsisLoc, NumExpansions);
Douglas Gregor2fc1bb72011-01-12 17:07:58 +0000422 if (Result.isNull())
423 return 0;
424
Douglas Gregor7536dd52010-12-20 02:24:11 +0000425 TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
426 PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc());
427 TL.setEllipsisLoc(EllipsisLoc);
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000428
Douglas Gregor7536dd52010-12-20 02:24:11 +0000429 // Copy over the source-location information from the type.
430 memcpy(TL.getNextTypeLoc().getOpaqueData(),
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000431 Pattern->getTypeLoc().getOpaqueData(),
432 Pattern->getTypeLoc().getFullDataSize());
433 return TSResult;
Douglas Gregor7536dd52010-12-20 02:24:11 +0000434}
Douglas Gregorb99268b2010-12-21 00:52:54 +0000435
Douglas Gregor2fc1bb72011-01-12 17:07:58 +0000436QualType Sema::CheckPackExpansion(QualType Pattern,
437 SourceRange PatternRange,
Douglas Gregorcded4f62011-01-14 17:04:44 +0000438 SourceLocation EllipsisLoc,
439 llvm::Optional<unsigned> NumExpansions) {
Douglas Gregor2fc1bb72011-01-12 17:07:58 +0000440 // C++0x [temp.variadic]p5:
441 // The pattern of a pack expansion shall name one or more
442 // parameter packs that are not expanded by a nested pack
443 // expansion.
444 if (!Pattern->containsUnexpandedParameterPack()) {
445 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
446 << PatternRange;
447 return QualType();
448 }
449
Douglas Gregorcded4f62011-01-14 17:04:44 +0000450 return Context.getPackExpansionType(Pattern, NumExpansions);
Douglas Gregor2fc1bb72011-01-12 17:07:58 +0000451}
452
Douglas Gregorbe230c32011-01-03 17:17:50 +0000453ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
Douglas Gregor67fd1252011-01-14 21:20:45 +0000454 return CheckPackExpansion(Pattern, EllipsisLoc, llvm::Optional<unsigned>());
455}
456
457ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
458 llvm::Optional<unsigned> NumExpansions) {
Douglas Gregorbe230c32011-01-03 17:17:50 +0000459 if (!Pattern)
460 return ExprError();
461
462 // C++0x [temp.variadic]p5:
463 // The pattern of a pack expansion shall name one or more
464 // parameter packs that are not expanded by a nested pack
465 // expansion.
466 if (!Pattern->containsUnexpandedParameterPack()) {
467 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
468 << Pattern->getSourceRange();
469 return ExprError();
470 }
471
472 // Create the pack expansion expression and source-location information.
473 return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
Douglas Gregor67fd1252011-01-14 21:20:45 +0000474 EllipsisLoc, NumExpansions));
Douglas Gregorbe230c32011-01-03 17:17:50 +0000475}
Douglas Gregorb99268b2010-12-21 00:52:54 +0000476
Douglas Gregord3731192011-01-10 07:32:04 +0000477/// \brief Retrieve the depth and index of a parameter pack.
478static std::pair<unsigned, unsigned>
479getDepthAndIndex(NamedDecl *ND) {
480 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
481 return std::make_pair(TTP->getDepth(), TTP->getIndex());
482
483 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
484 return std::make_pair(NTTP->getDepth(), NTTP->getIndex());
485
486 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
487 return std::make_pair(TTP->getDepth(), TTP->getIndex());
488}
489
Douglas Gregorb99268b2010-12-21 00:52:54 +0000490bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
491 SourceRange PatternRange,
David Blaikiea71f9d02011-09-22 02:34:54 +0000492 ArrayRef<UnexpandedParameterPack> Unexpanded,
Douglas Gregorb99268b2010-12-21 00:52:54 +0000493 const MultiLevelTemplateArgumentList &TemplateArgs,
494 bool &ShouldExpand,
Douglas Gregord3731192011-01-10 07:32:04 +0000495 bool &RetainExpansion,
Douglas Gregorcded4f62011-01-14 17:04:44 +0000496 llvm::Optional<unsigned> &NumExpansions) {
Douglas Gregorb99268b2010-12-21 00:52:54 +0000497 ShouldExpand = true;
Douglas Gregord3731192011-01-10 07:32:04 +0000498 RetainExpansion = false;
Douglas Gregorb99268b2010-12-21 00:52:54 +0000499 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
500 bool HaveFirstPack = false;
501
David Blaikiea71f9d02011-09-22 02:34:54 +0000502 for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(),
503 end = Unexpanded.end();
504 i != end; ++i) {
Douglas Gregorb99268b2010-12-21 00:52:54 +0000505 // Compute the depth and index for this parameter pack.
Ted Kremenek9577abc2011-01-23 17:04:59 +0000506 unsigned Depth = 0, Index = 0;
Douglas Gregorb99268b2010-12-21 00:52:54 +0000507 IdentifierInfo *Name;
Douglas Gregor12c9c002011-01-07 16:43:16 +0000508 bool IsFunctionParameterPack = false;
Douglas Gregorb99268b2010-12-21 00:52:54 +0000509
510 if (const TemplateTypeParmType *TTP
David Blaikiea71f9d02011-09-22 02:34:54 +0000511 = i->first.dyn_cast<const TemplateTypeParmType *>()) {
Douglas Gregorb99268b2010-12-21 00:52:54 +0000512 Depth = TTP->getDepth();
513 Index = TTP->getIndex();
Chandler Carruthb7efff42011-05-01 01:05:51 +0000514 Name = TTP->getIdentifier();
Douglas Gregorb99268b2010-12-21 00:52:54 +0000515 } else {
David Blaikiea71f9d02011-09-22 02:34:54 +0000516 NamedDecl *ND = i->first.get<NamedDecl *>();
Douglas Gregord3731192011-01-10 07:32:04 +0000517 if (isa<ParmVarDecl>(ND))
Douglas Gregor12c9c002011-01-07 16:43:16 +0000518 IsFunctionParameterPack = true;
Douglas Gregord3731192011-01-10 07:32:04 +0000519 else
520 llvm::tie(Depth, Index) = getDepthAndIndex(ND);
521
Douglas Gregorb99268b2010-12-21 00:52:54 +0000522 Name = ND->getIdentifier();
523 }
524
Douglas Gregor12c9c002011-01-07 16:43:16 +0000525 // Determine the size of this argument pack.
526 unsigned NewPackSize;
527 if (IsFunctionParameterPack) {
528 // Figure out whether we're instantiating to an argument pack or not.
529 typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
530
531 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
532 = CurrentInstantiationScope->findInstantiationOf(
David Blaikiea71f9d02011-09-22 02:34:54 +0000533 i->first.get<NamedDecl *>());
Chris Lattnera70062f2011-02-17 19:38:27 +0000534 if (Instantiation->is<DeclArgumentPack *>()) {
Douglas Gregor12c9c002011-01-07 16:43:16 +0000535 // We could expand this function parameter pack.
536 NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
537 } else {
538 // We can't expand this function parameter pack, so we can't expand
539 // the pack expansion.
540 ShouldExpand = false;
541 continue;
542 }
543 } else {
544 // If we don't have a template argument at this depth/index, then we
545 // cannot expand the pack expansion. Make a note of this, but we still
546 // want to check any parameter packs we *do* have arguments for.
547 if (Depth >= TemplateArgs.getNumLevels() ||
548 !TemplateArgs.hasTemplateArgument(Depth, Index)) {
549 ShouldExpand = false;
550 continue;
551 }
552
553 // Determine the size of the argument pack.
554 NewPackSize = TemplateArgs(Depth, Index).pack_size();
Douglas Gregorb99268b2010-12-21 00:52:54 +0000555 }
556
Douglas Gregord3731192011-01-10 07:32:04 +0000557 // C++0x [temp.arg.explicit]p9:
558 // Template argument deduction can extend the sequence of template
559 // arguments corresponding to a template parameter pack, even when the
560 // sequence contains explicitly specified template arguments.
Douglas Gregor8619edd2011-01-20 23:15:49 +0000561 if (!IsFunctionParameterPack) {
562 if (NamedDecl *PartialPack
563 = CurrentInstantiationScope->getPartiallySubstitutedPack()){
564 unsigned PartialDepth, PartialIndex;
565 llvm::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
566 if (PartialDepth == Depth && PartialIndex == Index)
567 RetainExpansion = true;
568 }
Douglas Gregord3731192011-01-10 07:32:04 +0000569 }
Douglas Gregor8619edd2011-01-20 23:15:49 +0000570
Douglas Gregorcded4f62011-01-14 17:04:44 +0000571 if (!NumExpansions) {
Douglas Gregorb99268b2010-12-21 00:52:54 +0000572 // The is the first pack we've seen for which we have an argument.
573 // Record it.
574 NumExpansions = NewPackSize;
575 FirstPack.first = Name;
David Blaikiea71f9d02011-09-22 02:34:54 +0000576 FirstPack.second = i->second;
Douglas Gregorb99268b2010-12-21 00:52:54 +0000577 HaveFirstPack = true;
578 continue;
579 }
580
Douglas Gregorcded4f62011-01-14 17:04:44 +0000581 if (NewPackSize != *NumExpansions) {
Douglas Gregorb99268b2010-12-21 00:52:54 +0000582 // C++0x [temp.variadic]p5:
583 // All of the parameter packs expanded by a pack expansion shall have
584 // the same number of arguments specified.
Douglas Gregorcded4f62011-01-14 17:04:44 +0000585 if (HaveFirstPack)
586 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
587 << FirstPack.first << Name << *NumExpansions << NewPackSize
David Blaikiea71f9d02011-09-22 02:34:54 +0000588 << SourceRange(FirstPack.second) << SourceRange(i->second);
Douglas Gregorcded4f62011-01-14 17:04:44 +0000589 else
590 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
591 << Name << *NumExpansions << NewPackSize
David Blaikiea71f9d02011-09-22 02:34:54 +0000592 << SourceRange(i->second);
Douglas Gregorb99268b2010-12-21 00:52:54 +0000593 return true;
594 }
595 }
596
597 return false;
598}
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000599
Douglas Gregor21371ea2011-01-11 03:14:20 +0000600unsigned Sema::getNumArgumentsInExpansion(QualType T,
601 const MultiLevelTemplateArgumentList &TemplateArgs) {
602 QualType Pattern = cast<PackExpansionType>(T)->getPattern();
Chris Lattner5f9e2722011-07-23 10:55:15 +0000603 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
Douglas Gregor21371ea2011-01-11 03:14:20 +0000604 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
605
606 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
607 // Compute the depth and index for this parameter pack.
608 unsigned Depth;
609 unsigned Index;
610
611 if (const TemplateTypeParmType *TTP
612 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
613 Depth = TTP->getDepth();
614 Index = TTP->getIndex();
615 } else {
616 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
617 if (isa<ParmVarDecl>(ND)) {
618 // Function parameter pack.
619 typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
620
621 llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
622 = CurrentInstantiationScope->findInstantiationOf(
623 Unexpanded[I].first.get<NamedDecl *>());
Chris Lattnera70062f2011-02-17 19:38:27 +0000624 if (Instantiation->is<DeclArgumentPack *>())
Douglas Gregor21371ea2011-01-11 03:14:20 +0000625 return Instantiation->get<DeclArgumentPack *>()->size();
626
627 continue;
628 }
629
630 llvm::tie(Depth, Index) = getDepthAndIndex(ND);
631 }
632 if (Depth >= TemplateArgs.getNumLevels() ||
633 !TemplateArgs.hasTemplateArgument(Depth, Index))
634 continue;
635
636 // Determine the size of the argument pack.
637 return TemplateArgs(Depth, Index).pack_size();
638 }
639
640 llvm_unreachable("No unexpanded parameter packs in type expansion.");
Douglas Gregor21371ea2011-01-11 03:14:20 +0000641}
642
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000643bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
644 const DeclSpec &DS = D.getDeclSpec();
645 switch (DS.getTypeSpecType()) {
646 case TST_typename:
Sean Huntdb5d44b2011-05-19 05:37:45 +0000647 case TST_typeofType:
Eli Friedmanb001de72011-10-06 23:00:33 +0000648 case TST_underlyingType:
649 case TST_atomic: {
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000650 QualType T = DS.getRepAsType().get();
651 if (!T.isNull() && T->containsUnexpandedParameterPack())
652 return true;
653 break;
654 }
655
656 case TST_typeofExpr:
657 case TST_decltype:
658 if (DS.getRepAsExpr() &&
659 DS.getRepAsExpr()->containsUnexpandedParameterPack())
660 return true;
661 break;
662
663 case TST_unspecified:
664 case TST_void:
665 case TST_char:
666 case TST_wchar:
667 case TST_char16:
668 case TST_char32:
669 case TST_int:
Richard Smith5a5a9712012-04-04 06:24:32 +0000670 case TST_int128:
Anton Korobeynikovaa4a99b2011-10-14 23:23:15 +0000671 case TST_half:
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000672 case TST_float:
673 case TST_double:
674 case TST_bool:
675 case TST_decimal32:
676 case TST_decimal64:
677 case TST_decimal128:
678 case TST_enum:
679 case TST_union:
680 case TST_struct:
681 case TST_class:
682 case TST_auto:
John McCalla5fc4722011-04-09 22:50:59 +0000683 case TST_unknown_anytype:
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000684 case TST_error:
685 break;
686 }
687
688 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
689 const DeclaratorChunk &Chunk = D.getTypeObject(I);
690 switch (Chunk.Kind) {
691 case DeclaratorChunk::Pointer:
692 case DeclaratorChunk::Reference:
693 case DeclaratorChunk::Paren:
694 // These declarator chunks cannot contain any parameter packs.
695 break;
696
697 case DeclaratorChunk::Array:
698 case DeclaratorChunk::Function:
699 case DeclaratorChunk::BlockPointer:
700 // Syntactically, these kinds of declarator chunks all come after the
701 // declarator-id (conceptually), so the parser should not invoke this
702 // routine at this time.
703 llvm_unreachable("Could not have seen this kind of declarator chunk");
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000704
705 case DeclaratorChunk::MemberPointer:
706 if (Chunk.Mem.Scope().getScopeRep() &&
707 Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
708 return true;
709 break;
710 }
711 }
712
713 return false;
714}
Douglas Gregoree8aff02011-01-04 17:33:58 +0000715
Kaelyn Uhrainf8ec8c92012-01-13 23:10:36 +0000716namespace {
717
718// Callback to only accept typo corrections that refer to parameter packs.
719class ParameterPackValidatorCCC : public CorrectionCandidateCallback {
720 public:
721 virtual bool ValidateCandidate(const TypoCorrection &candidate) {
722 NamedDecl *ND = candidate.getCorrectionDecl();
723 return ND && ND->isParameterPack();
724 }
725};
726
727}
728
Douglas Gregoree8aff02011-01-04 17:33:58 +0000729/// \brief Called when an expression computing the size of a parameter pack
730/// is parsed.
731///
732/// \code
733/// template<typename ...Types> struct count {
734/// static const unsigned value = sizeof...(Types);
735/// };
736/// \endcode
737///
738//
739/// \param OpLoc The location of the "sizeof" keyword.
740/// \param Name The name of the parameter pack whose size will be determined.
741/// \param NameLoc The source location of the name of the parameter pack.
742/// \param RParenLoc The location of the closing parentheses.
743ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
744 SourceLocation OpLoc,
745 IdentifierInfo &Name,
746 SourceLocation NameLoc,
747 SourceLocation RParenLoc) {
748 // C++0x [expr.sizeof]p5:
749 // The identifier in a sizeof... expression shall name a parameter pack.
Douglas Gregoree8aff02011-01-04 17:33:58 +0000750 LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
751 LookupName(R, S);
752
753 NamedDecl *ParameterPack = 0;
Kaelyn Uhrainf8ec8c92012-01-13 23:10:36 +0000754 ParameterPackValidatorCCC Validator;
Douglas Gregoree8aff02011-01-04 17:33:58 +0000755 switch (R.getResultKind()) {
756 case LookupResult::Found:
757 ParameterPack = R.getFoundDecl();
758 break;
759
760 case LookupResult::NotFound:
761 case LookupResult::NotFoundInCurrentInstantiation:
Douglas Gregord8bba9c2011-06-28 16:20:02 +0000762 if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
Kaelyn Uhrainf8ec8c92012-01-13 23:10:36 +0000763 R.getLookupKind(), S, 0,
Kaelyn Uhrain16e46dd2012-01-31 23:49:25 +0000764 Validator)) {
David Blaikie4e4d0842012-03-11 07:00:24 +0000765 std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts()));
Kaelyn Uhrainf8ec8c92012-01-13 23:10:36 +0000766 ParameterPack = Corrected.getCorrectionDecl();
767 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
768 << &Name << CorrectedQuotedStr
769 << FixItHint::CreateReplacement(
David Blaikie4e4d0842012-03-11 07:00:24 +0000770 NameLoc, Corrected.getAsString(getLangOpts()));
Kaelyn Uhrainf8ec8c92012-01-13 23:10:36 +0000771 Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
772 << CorrectedQuotedStr;
Douglas Gregoree8aff02011-01-04 17:33:58 +0000773 }
774
775 case LookupResult::FoundOverloaded:
776 case LookupResult::FoundUnresolvedValue:
777 break;
778
779 case LookupResult::Ambiguous:
780 DiagnoseAmbiguousLookup(R);
781 return ExprError();
782 }
783
Douglas Gregor1fe85ea2011-01-05 21:11:38 +0000784 if (!ParameterPack || !ParameterPack->isParameterPack()) {
Douglas Gregoree8aff02011-01-04 17:33:58 +0000785 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
786 << &Name;
787 return ExprError();
788 }
789
Eli Friedman88530d52012-03-01 21:32:56 +0000790 MarkAnyDeclReferenced(OpLoc, ParameterPack);
791
Douglas Gregoree8aff02011-01-04 17:33:58 +0000792 return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc,
793 ParameterPack, NameLoc, RParenLoc);
794}