blob: fb88bd114b4f65735fccdf155ee1bb7d9169b6d2 [file] [log] [blame]
Douglas Gregorb55fdf82010-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 Gregor820ba7b2011-01-04 17:33:58 +000013#include "clang/Sema/Lookup.h"
Douglas Gregord2fa7662010-12-20 02:24:11 +000014#include "clang/Sema/ParsedTemplate.h"
Douglas Gregorb55fdf82010-12-15 17:38:57 +000015#include "clang/Sema/SemaInternal.h"
Douglas Gregor840bd6c2010-12-20 22:05:00 +000016#include "clang/Sema/Template.h"
Douglas Gregorb55fdf82010-12-15 17:38:57 +000017#include "clang/AST/Expr.h"
Douglas Gregor1da294a2010-12-15 19:43:21 +000018#include "clang/AST/RecursiveASTVisitor.h"
Douglas Gregorb55fdf82010-12-15 17:38:57 +000019#include "clang/AST/TypeLoc.h"
20
21using namespace clang;
22
Douglas Gregor1da294a2010-12-15 19:43:21 +000023//----------------------------------------------------------------------------
24// Visitor that collects unexpanded parameter packs
25//----------------------------------------------------------------------------
26
Douglas Gregor1da294a2010-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
35 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
36
37 public:
38 explicit CollectUnexpandedParameterPacksVisitor(
39 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
40 : Unexpanded(Unexpanded) { }
41
Douglas Gregor15b4ec22010-12-20 23:07:20 +000042 bool shouldWalkTypesOfTypeLocs() const { return false; }
43
Douglas Gregor1da294a2010-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 Gregorda3cc0d2010-12-23 23:51:58 +000067 /// \brief Record occurrences of (FIXME: function and) non-type template
68 /// parameter packs in an expression.
69 bool VisitDeclRefExpr(DeclRefExpr *E) {
70 if (NonTypeTemplateParmDecl *NTTP
71 = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) {
72 if (NTTP->isParameterPack())
73 Unexpanded.push_back(std::make_pair(NTTP, E->getLocation()));
74 }
75
76 // FIXME: Function parameter packs.
77
78 return true;
79 }
80
Douglas Gregorf5500772011-01-05 15:48:55 +000081 /// \brief Record occurrences of template template parameter packs.
82 bool TraverseTemplateName(TemplateName Template) {
83 if (TemplateTemplateParmDecl *TTP
84 = dyn_cast_or_null<TemplateTemplateParmDecl>(
85 Template.getAsTemplateDecl()))
86 if (TTP->isParameterPack())
87 Unexpanded.push_back(std::make_pair(TTP, SourceLocation()));
88
89 return inherited::TraverseTemplateName(Template);
90 }
Douglas Gregor1da294a2010-12-15 19:43:21 +000091
Douglas Gregor1da294a2010-12-15 19:43:21 +000092 //------------------------------------------------------------------------
93 // Pruning the search for unexpanded parameter packs.
94 //------------------------------------------------------------------------
95
96 /// \brief Suppress traversal into statements and expressions that
97 /// do not contain unexpanded parameter packs.
98 bool TraverseStmt(Stmt *S) {
99 if (Expr *E = dyn_cast_or_null<Expr>(S))
100 if (E->containsUnexpandedParameterPack())
101 return inherited::TraverseStmt(E);
102
103 return true;
104 }
105
106 /// \brief Suppress traversal into types that do not contain
107 /// unexpanded parameter packs.
108 bool TraverseType(QualType T) {
109 if (!T.isNull() && T->containsUnexpandedParameterPack())
110 return inherited::TraverseType(T);
111
112 return true;
113 }
114
115 /// \brief Suppress traversel into types with location information
116 /// that do not contain unexpanded parameter packs.
117 bool TraverseTypeLoc(TypeLoc TL) {
Douglas Gregorda3cc0d2010-12-23 23:51:58 +0000118 if (!TL.getType().isNull() &&
119 TL.getType()->containsUnexpandedParameterPack())
Douglas Gregor1da294a2010-12-15 19:43:21 +0000120 return inherited::TraverseTypeLoc(TL);
121
122 return true;
123 }
124
Douglas Gregora8461bb2010-12-15 21:57:59 +0000125 /// \brief Suppress traversal of non-parameter declarations, since
126 /// they cannot contain unexpanded parameter packs.
127 bool TraverseDecl(Decl *D) {
128 if (D && isa<ParmVarDecl>(D))
129 return inherited::TraverseDecl(D);
130
131 return true;
132 }
Douglas Gregoreb29d182011-01-05 17:40:24 +0000133
134 /// \brief Suppress traversal of template argument pack expansions.
135 bool TraverseTemplateArgument(const TemplateArgument &Arg) {
136 if (Arg.isPackExpansion())
137 return true;
138
139 return inherited::TraverseTemplateArgument(Arg);
140 }
141
142 /// \brief Suppress traversal of template argument pack expansions.
143 bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
144 if (ArgLoc.getArgument().isPackExpansion())
145 return true;
146
147 return inherited::TraverseTemplateArgumentLoc(ArgLoc);
148 }
Douglas Gregor1da294a2010-12-15 19:43:21 +0000149 };
150}
151
152/// \brief Diagnose all of the unexpanded parameter packs in the given
153/// vector.
154static void
155DiagnoseUnexpandedParameterPacks(Sema &S, SourceLocation Loc,
156 Sema::UnexpandedParameterPackContext UPPC,
157 const llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
158 llvm::SmallVector<SourceLocation, 4> Locations;
159 llvm::SmallVector<IdentifierInfo *, 4> Names;
160 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
161
162 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
163 IdentifierInfo *Name = 0;
164 if (const TemplateTypeParmType *TTP
165 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
166 Name = TTP->getName();
167 else
168 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
169
170 if (Name && NamesKnown.insert(Name))
171 Names.push_back(Name);
172
173 if (Unexpanded[I].second.isValid())
174 Locations.push_back(Unexpanded[I].second);
175 }
176
177 DiagnosticBuilder DB
178 = Names.size() == 0? S.Diag(Loc, diag::err_unexpanded_parameter_pack_0)
179 << (int)UPPC
180 : Names.size() == 1? S.Diag(Loc, diag::err_unexpanded_parameter_pack_1)
181 << (int)UPPC << Names[0]
182 : Names.size() == 2? S.Diag(Loc, diag::err_unexpanded_parameter_pack_2)
183 << (int)UPPC << Names[0] << Names[1]
184 : S.Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
185 << (int)UPPC << Names[0] << Names[1];
186
187 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
188 DB << SourceRange(Locations[I]);
189}
190
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000191bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
192 TypeSourceInfo *T,
193 UnexpandedParameterPackContext UPPC) {
194 // C++0x [temp.variadic]p5:
195 // An appearance of a name of a parameter pack that is not expanded is
196 // ill-formed.
197 if (!T->getType()->containsUnexpandedParameterPack())
198 return false;
199
Douglas Gregor1da294a2010-12-15 19:43:21 +0000200 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
201 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
202 T->getTypeLoc());
203 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
204 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000205 return true;
206}
207
208bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
Douglas Gregorc4356532010-12-16 00:46:58 +0000209 UnexpandedParameterPackContext UPPC) {
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000210 // C++0x [temp.variadic]p5:
211 // An appearance of a name of a parameter pack that is not expanded is
212 // ill-formed.
213 if (!E->containsUnexpandedParameterPack())
214 return false;
215
Douglas Gregor1da294a2010-12-15 19:43:21 +0000216 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
217 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
218 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
219 DiagnoseUnexpandedParameterPacks(*this, E->getLocStart(), UPPC, Unexpanded);
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000220 return true;
221}
Douglas Gregorc4356532010-12-16 00:46:58 +0000222
223bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
224 UnexpandedParameterPackContext UPPC) {
225 // C++0x [temp.variadic]p5:
226 // An appearance of a name of a parameter pack that is not expanded is
227 // ill-formed.
228 if (!SS.getScopeRep() ||
229 !SS.getScopeRep()->containsUnexpandedParameterPack())
230 return false;
231
232 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
233 CollectUnexpandedParameterPacksVisitor(Unexpanded)
234 .TraverseNestedNameSpecifier(SS.getScopeRep());
235 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
236 DiagnoseUnexpandedParameterPacks(*this, SS.getRange().getBegin(),
237 UPPC, Unexpanded);
238 return true;
239}
240
241bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
242 UnexpandedParameterPackContext UPPC) {
243 // C++0x [temp.variadic]p5:
244 // An appearance of a name of a parameter pack that is not expanded is
245 // ill-formed.
246 switch (NameInfo.getName().getNameKind()) {
247 case DeclarationName::Identifier:
248 case DeclarationName::ObjCZeroArgSelector:
249 case DeclarationName::ObjCOneArgSelector:
250 case DeclarationName::ObjCMultiArgSelector:
251 case DeclarationName::CXXOperatorName:
252 case DeclarationName::CXXLiteralOperatorName:
253 case DeclarationName::CXXUsingDirective:
254 return false;
255
256 case DeclarationName::CXXConstructorName:
257 case DeclarationName::CXXDestructorName:
258 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor062ecac2010-12-16 17:19:19 +0000259 // FIXME: We shouldn't need this null check!
Douglas Gregor6ab34af2010-12-16 01:40:04 +0000260 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
261 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
262
263 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
Douglas Gregorc4356532010-12-16 00:46:58 +0000264 return false;
Douglas Gregor6ab34af2010-12-16 01:40:04 +0000265
Douglas Gregorc4356532010-12-16 00:46:58 +0000266 break;
267 }
268
269 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
270 CollectUnexpandedParameterPacksVisitor(Unexpanded)
Douglas Gregor6ab34af2010-12-16 01:40:04 +0000271 .TraverseType(NameInfo.getName().getCXXNameType());
Douglas Gregorc4356532010-12-16 00:46:58 +0000272 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
273 DiagnoseUnexpandedParameterPacks(*this, NameInfo.getLoc(), UPPC, Unexpanded);
274 return true;
275}
Douglas Gregor6ff1fbf2010-12-16 08:48:57 +0000276
277bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
278 TemplateName Template,
279 UnexpandedParameterPackContext UPPC) {
280
281 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
282 return false;
283
284 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
285 CollectUnexpandedParameterPacksVisitor(Unexpanded)
286 .TraverseTemplateName(Template);
287 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
288 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
289 return true;
290}
291
Douglas Gregor14406932011-01-03 20:35:03 +0000292bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
293 UnexpandedParameterPackContext UPPC) {
294 if (Arg.getArgument().isNull() ||
295 !Arg.getArgument().containsUnexpandedParameterPack())
296 return false;
297
298 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
299 CollectUnexpandedParameterPacksVisitor(Unexpanded)
300 .TraverseTemplateArgumentLoc(Arg);
301 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
302 DiagnoseUnexpandedParameterPacks(*this, Arg.getLocation(), UPPC, Unexpanded);
303 return true;
304}
305
Douglas Gregor0f3feb42010-12-22 21:19:48 +0000306void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
307 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
308 CollectUnexpandedParameterPacksVisitor(Unexpanded)
309 .TraverseTemplateArgument(Arg);
310}
311
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000312void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
313 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
314 CollectUnexpandedParameterPacksVisitor(Unexpanded)
315 .TraverseTemplateArgumentLoc(Arg);
316}
317
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000318void Sema::collectUnexpandedParameterPacks(QualType T,
319 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
320 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
321}
322
Douglas Gregor752a5952011-01-03 22:36:02 +0000323void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
324 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
325 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
326}
327
Douglas Gregord2fa7662010-12-20 02:24:11 +0000328ParsedTemplateArgument
329Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
330 SourceLocation EllipsisLoc) {
331 if (Arg.isInvalid())
332 return Arg;
333
334 switch (Arg.getKind()) {
335 case ParsedTemplateArgument::Type: {
336 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
337 if (Result.isInvalid())
338 return ParsedTemplateArgument();
339
340 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
341 Arg.getLocation());
342 }
343
Douglas Gregore8e9dd62011-01-03 17:17:50 +0000344 case ParsedTemplateArgument::NonType: {
345 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
346 if (Result.isInvalid())
347 return ParsedTemplateArgument();
348
349 return ParsedTemplateArgument(Arg.getKind(), Result.get(),
350 Arg.getLocation());
351 }
352
Douglas Gregord2fa7662010-12-20 02:24:11 +0000353 case ParsedTemplateArgument::Template:
Douglas Gregoreb29d182011-01-05 17:40:24 +0000354 if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
355 SourceRange R(Arg.getLocation());
356 if (Arg.getScopeSpec().isValid())
357 R.setBegin(Arg.getScopeSpec().getBeginLoc());
358 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
359 << R;
360 return ParsedTemplateArgument();
361 }
362
363 return Arg.getTemplatePackExpansion(EllipsisLoc);
Douglas Gregord2fa7662010-12-20 02:24:11 +0000364 }
365 llvm_unreachable("Unhandled template argument kind?");
366 return ParsedTemplateArgument();
367}
368
369TypeResult Sema::ActOnPackExpansion(ParsedType Type,
370 SourceLocation EllipsisLoc) {
371 TypeSourceInfo *TSInfo;
372 GetTypeFromParser(Type, &TSInfo);
373 if (!TSInfo)
374 return true;
375
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000376 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc);
377 if (!TSResult)
378 return true;
379
380 return CreateParsedType(TSResult->getType(), TSResult);
381}
382
383TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
384 SourceLocation EllipsisLoc) {
Douglas Gregord2fa7662010-12-20 02:24:11 +0000385 // C++0x [temp.variadic]p5:
386 // The pattern of a pack expansion shall name one or more
387 // parameter packs that are not expanded by a nested pack
388 // expansion.
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000389 if (!Pattern->getType()->containsUnexpandedParameterPack()) {
Douglas Gregord2fa7662010-12-20 02:24:11 +0000390 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000391 << Pattern->getTypeLoc().getSourceRange();
392 return 0;
Douglas Gregord2fa7662010-12-20 02:24:11 +0000393 }
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000394
Douglas Gregord2fa7662010-12-20 02:24:11 +0000395 // Create the pack expansion type and source-location information.
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000396 QualType Result = Context.getPackExpansionType(Pattern->getType());
Douglas Gregord2fa7662010-12-20 02:24:11 +0000397 TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
398 PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc());
399 TL.setEllipsisLoc(EllipsisLoc);
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000400
Douglas Gregord2fa7662010-12-20 02:24:11 +0000401 // Copy over the source-location information from the type.
402 memcpy(TL.getNextTypeLoc().getOpaqueData(),
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000403 Pattern->getTypeLoc().getOpaqueData(),
404 Pattern->getTypeLoc().getFullDataSize());
405 return TSResult;
Douglas Gregord2fa7662010-12-20 02:24:11 +0000406}
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000407
Douglas Gregore8e9dd62011-01-03 17:17:50 +0000408ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
409 if (!Pattern)
410 return ExprError();
411
412 // C++0x [temp.variadic]p5:
413 // The pattern of a pack expansion shall name one or more
414 // parameter packs that are not expanded by a nested pack
415 // expansion.
416 if (!Pattern->containsUnexpandedParameterPack()) {
417 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
418 << Pattern->getSourceRange();
419 return ExprError();
420 }
421
422 // Create the pack expansion expression and source-location information.
423 return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
424 EllipsisLoc));
425}
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000426
427bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
428 SourceRange PatternRange,
429 const UnexpandedParameterPack *Unexpanded,
430 unsigned NumUnexpanded,
431 const MultiLevelTemplateArgumentList &TemplateArgs,
432 bool &ShouldExpand,
433 unsigned &NumExpansions) {
434 ShouldExpand = true;
435 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
436 bool HaveFirstPack = false;
437
438 for (unsigned I = 0; I != NumUnexpanded; ++I) {
439 // Compute the depth and index for this parameter pack.
440 unsigned Depth;
441 unsigned Index;
442 IdentifierInfo *Name;
443
444 if (const TemplateTypeParmType *TTP
445 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
446 Depth = TTP->getDepth();
447 Index = TTP->getIndex();
448 Name = TTP->getName();
449 } else {
450 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
451 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) {
452 Depth = TTP->getDepth();
453 Index = TTP->getIndex();
454 } else if (NonTypeTemplateParmDecl *NTTP
455 = dyn_cast<NonTypeTemplateParmDecl>(ND)) {
456 Depth = NTTP->getDepth();
457 Index = NTTP->getIndex();
458 } else {
459 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
460 Depth = TTP->getDepth();
461 Index = TTP->getIndex();
462 }
463 // FIXME: Variadic templates function parameter packs?
464 Name = ND->getIdentifier();
465 }
466
467 // If we don't have a template argument at this depth/index, then we
468 // cannot expand the pack expansion. Make a note of this, but we still
Douglas Gregoreb5a39d2010-12-24 00:15:10 +0000469 // want to check any parameter packs we *do* have arguments for.
Douglas Gregor98318c22011-01-03 21:37:45 +0000470 if (Depth >= TemplateArgs.getNumLevels() ||
471 !TemplateArgs.hasTemplateArgument(Depth, Index)) {
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000472 ShouldExpand = false;
473 continue;
474 }
475
476 // Determine the size of the argument pack.
477 unsigned NewPackSize = TemplateArgs(Depth, Index).pack_size();
478 if (!HaveFirstPack) {
479 // The is the first pack we've seen for which we have an argument.
480 // Record it.
481 NumExpansions = NewPackSize;
482 FirstPack.first = Name;
483 FirstPack.second = Unexpanded[I].second;
484 HaveFirstPack = true;
485 continue;
486 }
487
488 if (NewPackSize != NumExpansions) {
489 // C++0x [temp.variadic]p5:
490 // All of the parameter packs expanded by a pack expansion shall have
491 // the same number of arguments specified.
492 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
493 << FirstPack.first << Name << NumExpansions << NewPackSize
494 << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
495 return true;
496 }
497 }
498
499 return false;
500}
Douglas Gregor27b4c162010-12-23 22:44:42 +0000501
502bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
503 const DeclSpec &DS = D.getDeclSpec();
504 switch (DS.getTypeSpecType()) {
505 case TST_typename:
506 case TST_typeofType: {
507 QualType T = DS.getRepAsType().get();
508 if (!T.isNull() && T->containsUnexpandedParameterPack())
509 return true;
510 break;
511 }
512
513 case TST_typeofExpr:
514 case TST_decltype:
515 if (DS.getRepAsExpr() &&
516 DS.getRepAsExpr()->containsUnexpandedParameterPack())
517 return true;
518 break;
519
520 case TST_unspecified:
521 case TST_void:
522 case TST_char:
523 case TST_wchar:
524 case TST_char16:
525 case TST_char32:
526 case TST_int:
527 case TST_float:
528 case TST_double:
529 case TST_bool:
530 case TST_decimal32:
531 case TST_decimal64:
532 case TST_decimal128:
533 case TST_enum:
534 case TST_union:
535 case TST_struct:
536 case TST_class:
537 case TST_auto:
538 case TST_error:
539 break;
540 }
541
542 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
543 const DeclaratorChunk &Chunk = D.getTypeObject(I);
544 switch (Chunk.Kind) {
545 case DeclaratorChunk::Pointer:
546 case DeclaratorChunk::Reference:
547 case DeclaratorChunk::Paren:
548 // These declarator chunks cannot contain any parameter packs.
549 break;
550
551 case DeclaratorChunk::Array:
552 case DeclaratorChunk::Function:
553 case DeclaratorChunk::BlockPointer:
554 // Syntactically, these kinds of declarator chunks all come after the
555 // declarator-id (conceptually), so the parser should not invoke this
556 // routine at this time.
557 llvm_unreachable("Could not have seen this kind of declarator chunk");
558 break;
559
560 case DeclaratorChunk::MemberPointer:
561 if (Chunk.Mem.Scope().getScopeRep() &&
562 Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
563 return true;
564 break;
565 }
566 }
567
568 return false;
569}
Douglas Gregor820ba7b2011-01-04 17:33:58 +0000570
571/// \brief Called when an expression computing the size of a parameter pack
572/// is parsed.
573///
574/// \code
575/// template<typename ...Types> struct count {
576/// static const unsigned value = sizeof...(Types);
577/// };
578/// \endcode
579///
580//
581/// \param OpLoc The location of the "sizeof" keyword.
582/// \param Name The name of the parameter pack whose size will be determined.
583/// \param NameLoc The source location of the name of the parameter pack.
584/// \param RParenLoc The location of the closing parentheses.
585ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
586 SourceLocation OpLoc,
587 IdentifierInfo &Name,
588 SourceLocation NameLoc,
589 SourceLocation RParenLoc) {
590 // C++0x [expr.sizeof]p5:
591 // The identifier in a sizeof... expression shall name a parameter pack.
Douglas Gregor820ba7b2011-01-04 17:33:58 +0000592 LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
593 LookupName(R, S);
594
595 NamedDecl *ParameterPack = 0;
596 switch (R.getResultKind()) {
597 case LookupResult::Found:
598 ParameterPack = R.getFoundDecl();
599 break;
600
601 case LookupResult::NotFound:
602 case LookupResult::NotFoundInCurrentInstantiation:
603 if (DeclarationName CorrectedName = CorrectTypo(R, S, 0, 0, false,
604 CTC_NoKeywords)) {
605 // FIXME: Variadic templates function parameter packs.
606 if (NamedDecl *CorrectedResult = R.getAsSingle<NamedDecl>())
607 if (CorrectedResult->isTemplateParameterPack()) {
608 ParameterPack = CorrectedResult;
609 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
610 << &Name << CorrectedName
611 << FixItHint::CreateReplacement(NameLoc,
612 CorrectedName.getAsString());
613 Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
614 << CorrectedName;
615 }
616 }
617
618 case LookupResult::FoundOverloaded:
619 case LookupResult::FoundUnresolvedValue:
620 break;
621
622 case LookupResult::Ambiguous:
623 DiagnoseAmbiguousLookup(R);
624 return ExprError();
625 }
626
627 // FIXME: Variadic templates function parameter packs.
628 if (!ParameterPack || !ParameterPack->isTemplateParameterPack()) {
629 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
630 << &Name;
631 return ExprError();
632 }
633
634 return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc,
635 ParameterPack, NameLoc, RParenLoc);
636}