blob: acb73144d9217b5f856c43059d68ebc6e6c3e96b [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
35 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
36
37 public:
38 explicit CollectUnexpandedParameterPacksVisitor(
39 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
40 : 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 Gregor10738d32010-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 Gregor61c4d282011-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 Gregor9ef75892010-12-15 19:43:21 +000091
Douglas Gregor9ef75892010-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 Gregor10738d32010-12-23 23:51:58 +0000118 if (!TL.getType().isNull() &&
119 TL.getType()->containsUnexpandedParameterPack())
Douglas Gregor9ef75892010-12-15 19:43:21 +0000120 return inherited::TraverseTypeLoc(TL);
121
122 return true;
123 }
124
Douglas Gregorcff163e2010-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 Gregor9ef75892010-12-15 19:43:21 +0000133 };
134}
135
136/// \brief Diagnose all of the unexpanded parameter packs in the given
137/// vector.
138static void
139DiagnoseUnexpandedParameterPacks(Sema &S, SourceLocation Loc,
140 Sema::UnexpandedParameterPackContext UPPC,
141 const llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
142 llvm::SmallVector<SourceLocation, 4> Locations;
143 llvm::SmallVector<IdentifierInfo *, 4> Names;
144 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
145
146 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
147 IdentifierInfo *Name = 0;
148 if (const TemplateTypeParmType *TTP
149 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
150 Name = TTP->getName();
151 else
152 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
153
154 if (Name && NamesKnown.insert(Name))
155 Names.push_back(Name);
156
157 if (Unexpanded[I].second.isValid())
158 Locations.push_back(Unexpanded[I].second);
159 }
160
161 DiagnosticBuilder DB
162 = Names.size() == 0? S.Diag(Loc, diag::err_unexpanded_parameter_pack_0)
163 << (int)UPPC
164 : Names.size() == 1? S.Diag(Loc, diag::err_unexpanded_parameter_pack_1)
165 << (int)UPPC << Names[0]
166 : Names.size() == 2? S.Diag(Loc, diag::err_unexpanded_parameter_pack_2)
167 << (int)UPPC << Names[0] << Names[1]
168 : S.Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
169 << (int)UPPC << Names[0] << Names[1];
170
171 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
172 DB << SourceRange(Locations[I]);
173}
174
Douglas Gregorc4633352010-12-15 17:38:57 +0000175bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
176 TypeSourceInfo *T,
177 UnexpandedParameterPackContext UPPC) {
178 // C++0x [temp.variadic]p5:
179 // An appearance of a name of a parameter pack that is not expanded is
180 // ill-formed.
181 if (!T->getType()->containsUnexpandedParameterPack())
182 return false;
183
Douglas Gregor9ef75892010-12-15 19:43:21 +0000184 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
185 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
186 T->getTypeLoc());
187 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
188 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
Douglas Gregorc4633352010-12-15 17:38:57 +0000189 return true;
190}
191
192bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
Douglas Gregor56c04582010-12-16 00:46:58 +0000193 UnexpandedParameterPackContext UPPC) {
Douglas Gregorc4633352010-12-15 17:38:57 +0000194 // 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 (!E->containsUnexpandedParameterPack())
198 return false;
199
Douglas Gregor9ef75892010-12-15 19:43:21 +0000200 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
201 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
202 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
203 DiagnoseUnexpandedParameterPacks(*this, E->getLocStart(), UPPC, Unexpanded);
Douglas Gregorc4633352010-12-15 17:38:57 +0000204 return true;
205}
Douglas Gregor56c04582010-12-16 00:46:58 +0000206
207bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
208 UnexpandedParameterPackContext UPPC) {
209 // C++0x [temp.variadic]p5:
210 // An appearance of a name of a parameter pack that is not expanded is
211 // ill-formed.
212 if (!SS.getScopeRep() ||
213 !SS.getScopeRep()->containsUnexpandedParameterPack())
214 return false;
215
216 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
217 CollectUnexpandedParameterPacksVisitor(Unexpanded)
218 .TraverseNestedNameSpecifier(SS.getScopeRep());
219 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
220 DiagnoseUnexpandedParameterPacks(*this, SS.getRange().getBegin(),
221 UPPC, Unexpanded);
222 return true;
223}
224
225bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
226 UnexpandedParameterPackContext UPPC) {
227 // C++0x [temp.variadic]p5:
228 // An appearance of a name of a parameter pack that is not expanded is
229 // ill-formed.
230 switch (NameInfo.getName().getNameKind()) {
231 case DeclarationName::Identifier:
232 case DeclarationName::ObjCZeroArgSelector:
233 case DeclarationName::ObjCOneArgSelector:
234 case DeclarationName::ObjCMultiArgSelector:
235 case DeclarationName::CXXOperatorName:
236 case DeclarationName::CXXLiteralOperatorName:
237 case DeclarationName::CXXUsingDirective:
238 return false;
239
240 case DeclarationName::CXXConstructorName:
241 case DeclarationName::CXXDestructorName:
242 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor099ffe82010-12-16 17:19:19 +0000243 // FIXME: We shouldn't need this null check!
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000244 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
245 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
246
247 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
Douglas Gregor56c04582010-12-16 00:46:58 +0000248 return false;
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000249
Douglas Gregor56c04582010-12-16 00:46:58 +0000250 break;
251 }
252
253 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
254 CollectUnexpandedParameterPacksVisitor(Unexpanded)
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000255 .TraverseType(NameInfo.getName().getCXXNameType());
Douglas Gregor56c04582010-12-16 00:46:58 +0000256 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
257 DiagnoseUnexpandedParameterPacks(*this, NameInfo.getLoc(), UPPC, Unexpanded);
258 return true;
259}
Douglas Gregor6f526752010-12-16 08:48:57 +0000260
261bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
262 TemplateName Template,
263 UnexpandedParameterPackContext UPPC) {
264
265 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
266 return false;
267
268 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
269 CollectUnexpandedParameterPacksVisitor(Unexpanded)
270 .TraverseTemplateName(Template);
271 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
272 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
273 return true;
274}
275
Douglas Gregor925910d2011-01-03 20:35:03 +0000276bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
277 UnexpandedParameterPackContext UPPC) {
278 if (Arg.getArgument().isNull() ||
279 !Arg.getArgument().containsUnexpandedParameterPack())
280 return false;
281
282 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
283 CollectUnexpandedParameterPacksVisitor(Unexpanded)
284 .TraverseTemplateArgumentLoc(Arg);
285 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
286 DiagnoseUnexpandedParameterPacks(*this, Arg.getLocation(), UPPC, Unexpanded);
287 return true;
288}
289
Douglas Gregore02e2622010-12-22 21:19:48 +0000290void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
291 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
292 CollectUnexpandedParameterPacksVisitor(Unexpanded)
293 .TraverseTemplateArgument(Arg);
294}
295
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000296void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
297 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
298 CollectUnexpandedParameterPacksVisitor(Unexpanded)
299 .TraverseTemplateArgumentLoc(Arg);
300}
301
Douglas Gregorb99268b2010-12-21 00:52:54 +0000302void Sema::collectUnexpandedParameterPacks(QualType T,
303 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
304 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
305}
306
Douglas Gregorf90b27a2011-01-03 22:36:02 +0000307void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
308 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
309 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
310}
311
Douglas Gregor7536dd52010-12-20 02:24:11 +0000312ParsedTemplateArgument
313Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
314 SourceLocation EllipsisLoc) {
315 if (Arg.isInvalid())
316 return Arg;
317
318 switch (Arg.getKind()) {
319 case ParsedTemplateArgument::Type: {
320 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
321 if (Result.isInvalid())
322 return ParsedTemplateArgument();
323
324 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
325 Arg.getLocation());
326 }
327
Douglas Gregorbe230c32011-01-03 17:17:50 +0000328 case ParsedTemplateArgument::NonType: {
329 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
330 if (Result.isInvalid())
331 return ParsedTemplateArgument();
332
333 return ParsedTemplateArgument(Arg.getKind(), Result.get(),
334 Arg.getLocation());
335 }
336
Douglas Gregor7536dd52010-12-20 02:24:11 +0000337 case ParsedTemplateArgument::Template:
Douglas Gregorbe230c32011-01-03 17:17:50 +0000338 Diag(EllipsisLoc, diag::err_pack_expansion_unsupported);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000339 return ParsedTemplateArgument();
340 }
341 llvm_unreachable("Unhandled template argument kind?");
342 return ParsedTemplateArgument();
343}
344
345TypeResult Sema::ActOnPackExpansion(ParsedType Type,
346 SourceLocation EllipsisLoc) {
347 TypeSourceInfo *TSInfo;
348 GetTypeFromParser(Type, &TSInfo);
349 if (!TSInfo)
350 return true;
351
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000352 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc);
353 if (!TSResult)
354 return true;
355
356 return CreateParsedType(TSResult->getType(), TSResult);
357}
358
359TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
360 SourceLocation EllipsisLoc) {
Douglas Gregor7536dd52010-12-20 02:24:11 +0000361 // C++0x [temp.variadic]p5:
362 // The pattern of a pack expansion shall name one or more
363 // parameter packs that are not expanded by a nested pack
364 // expansion.
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000365 if (!Pattern->getType()->containsUnexpandedParameterPack()) {
Douglas Gregor7536dd52010-12-20 02:24:11 +0000366 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000367 << Pattern->getTypeLoc().getSourceRange();
368 return 0;
Douglas Gregor7536dd52010-12-20 02:24:11 +0000369 }
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000370
Douglas Gregor7536dd52010-12-20 02:24:11 +0000371 // Create the pack expansion type and source-location information.
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000372 QualType Result = Context.getPackExpansionType(Pattern->getType());
Douglas Gregor7536dd52010-12-20 02:24:11 +0000373 TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
374 PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc());
375 TL.setEllipsisLoc(EllipsisLoc);
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000376
Douglas Gregor7536dd52010-12-20 02:24:11 +0000377 // Copy over the source-location information from the type.
378 memcpy(TL.getNextTypeLoc().getOpaqueData(),
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000379 Pattern->getTypeLoc().getOpaqueData(),
380 Pattern->getTypeLoc().getFullDataSize());
381 return TSResult;
Douglas Gregor7536dd52010-12-20 02:24:11 +0000382}
Douglas Gregorb99268b2010-12-21 00:52:54 +0000383
Douglas Gregorbe230c32011-01-03 17:17:50 +0000384ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
385 if (!Pattern)
386 return ExprError();
387
388 // C++0x [temp.variadic]p5:
389 // The pattern of a pack expansion shall name one or more
390 // parameter packs that are not expanded by a nested pack
391 // expansion.
392 if (!Pattern->containsUnexpandedParameterPack()) {
393 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
394 << Pattern->getSourceRange();
395 return ExprError();
396 }
397
398 // Create the pack expansion expression and source-location information.
399 return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
400 EllipsisLoc));
401}
Douglas Gregorb99268b2010-12-21 00:52:54 +0000402
403bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
404 SourceRange PatternRange,
405 const UnexpandedParameterPack *Unexpanded,
406 unsigned NumUnexpanded,
407 const MultiLevelTemplateArgumentList &TemplateArgs,
408 bool &ShouldExpand,
409 unsigned &NumExpansions) {
410 ShouldExpand = true;
411 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
412 bool HaveFirstPack = false;
413
414 for (unsigned I = 0; I != NumUnexpanded; ++I) {
415 // Compute the depth and index for this parameter pack.
416 unsigned Depth;
417 unsigned Index;
418 IdentifierInfo *Name;
419
420 if (const TemplateTypeParmType *TTP
421 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
422 Depth = TTP->getDepth();
423 Index = TTP->getIndex();
424 Name = TTP->getName();
425 } else {
426 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
427 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) {
428 Depth = TTP->getDepth();
429 Index = TTP->getIndex();
430 } else if (NonTypeTemplateParmDecl *NTTP
431 = dyn_cast<NonTypeTemplateParmDecl>(ND)) {
432 Depth = NTTP->getDepth();
433 Index = NTTP->getIndex();
434 } else {
435 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
436 Depth = TTP->getDepth();
437 Index = TTP->getIndex();
438 }
439 // FIXME: Variadic templates function parameter packs?
440 Name = ND->getIdentifier();
441 }
442
443 // If we don't have a template argument at this depth/index, then we
444 // cannot expand the pack expansion. Make a note of this, but we still
Douglas Gregor56bc9832010-12-24 00:15:10 +0000445 // want to check any parameter packs we *do* have arguments for.
Douglas Gregor7a21fd42011-01-03 21:37:45 +0000446 if (Depth >= TemplateArgs.getNumLevels() ||
447 !TemplateArgs.hasTemplateArgument(Depth, Index)) {
Douglas Gregorb99268b2010-12-21 00:52:54 +0000448 ShouldExpand = false;
449 continue;
450 }
451
452 // Determine the size of the argument pack.
453 unsigned NewPackSize = TemplateArgs(Depth, Index).pack_size();
454 if (!HaveFirstPack) {
455 // The is the first pack we've seen for which we have an argument.
456 // Record it.
457 NumExpansions = NewPackSize;
458 FirstPack.first = Name;
459 FirstPack.second = Unexpanded[I].second;
460 HaveFirstPack = true;
461 continue;
462 }
463
464 if (NewPackSize != NumExpansions) {
465 // C++0x [temp.variadic]p5:
466 // All of the parameter packs expanded by a pack expansion shall have
467 // the same number of arguments specified.
468 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
469 << FirstPack.first << Name << NumExpansions << NewPackSize
470 << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
471 return true;
472 }
473 }
474
475 return false;
476}
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000477
478bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
479 const DeclSpec &DS = D.getDeclSpec();
480 switch (DS.getTypeSpecType()) {
481 case TST_typename:
482 case TST_typeofType: {
483 QualType T = DS.getRepAsType().get();
484 if (!T.isNull() && T->containsUnexpandedParameterPack())
485 return true;
486 break;
487 }
488
489 case TST_typeofExpr:
490 case TST_decltype:
491 if (DS.getRepAsExpr() &&
492 DS.getRepAsExpr()->containsUnexpandedParameterPack())
493 return true;
494 break;
495
496 case TST_unspecified:
497 case TST_void:
498 case TST_char:
499 case TST_wchar:
500 case TST_char16:
501 case TST_char32:
502 case TST_int:
503 case TST_float:
504 case TST_double:
505 case TST_bool:
506 case TST_decimal32:
507 case TST_decimal64:
508 case TST_decimal128:
509 case TST_enum:
510 case TST_union:
511 case TST_struct:
512 case TST_class:
513 case TST_auto:
514 case TST_error:
515 break;
516 }
517
518 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
519 const DeclaratorChunk &Chunk = D.getTypeObject(I);
520 switch (Chunk.Kind) {
521 case DeclaratorChunk::Pointer:
522 case DeclaratorChunk::Reference:
523 case DeclaratorChunk::Paren:
524 // These declarator chunks cannot contain any parameter packs.
525 break;
526
527 case DeclaratorChunk::Array:
528 case DeclaratorChunk::Function:
529 case DeclaratorChunk::BlockPointer:
530 // Syntactically, these kinds of declarator chunks all come after the
531 // declarator-id (conceptually), so the parser should not invoke this
532 // routine at this time.
533 llvm_unreachable("Could not have seen this kind of declarator chunk");
534 break;
535
536 case DeclaratorChunk::MemberPointer:
537 if (Chunk.Mem.Scope().getScopeRep() &&
538 Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
539 return true;
540 break;
541 }
542 }
543
544 return false;
545}
Douglas Gregoree8aff02011-01-04 17:33:58 +0000546
547/// \brief Called when an expression computing the size of a parameter pack
548/// is parsed.
549///
550/// \code
551/// template<typename ...Types> struct count {
552/// static const unsigned value = sizeof...(Types);
553/// };
554/// \endcode
555///
556//
557/// \param OpLoc The location of the "sizeof" keyword.
558/// \param Name The name of the parameter pack whose size will be determined.
559/// \param NameLoc The source location of the name of the parameter pack.
560/// \param RParenLoc The location of the closing parentheses.
561ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
562 SourceLocation OpLoc,
563 IdentifierInfo &Name,
564 SourceLocation NameLoc,
565 SourceLocation RParenLoc) {
566 // C++0x [expr.sizeof]p5:
567 // The identifier in a sizeof... expression shall name a parameter pack.
Douglas Gregoree8aff02011-01-04 17:33:58 +0000568 LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
569 LookupName(R, S);
570
571 NamedDecl *ParameterPack = 0;
572 switch (R.getResultKind()) {
573 case LookupResult::Found:
574 ParameterPack = R.getFoundDecl();
575 break;
576
577 case LookupResult::NotFound:
578 case LookupResult::NotFoundInCurrentInstantiation:
579 if (DeclarationName CorrectedName = CorrectTypo(R, S, 0, 0, false,
580 CTC_NoKeywords)) {
581 // FIXME: Variadic templates function parameter packs.
582 if (NamedDecl *CorrectedResult = R.getAsSingle<NamedDecl>())
583 if (CorrectedResult->isTemplateParameterPack()) {
584 ParameterPack = CorrectedResult;
585 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
586 << &Name << CorrectedName
587 << FixItHint::CreateReplacement(NameLoc,
588 CorrectedName.getAsString());
589 Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
590 << CorrectedName;
591 }
592 }
593
594 case LookupResult::FoundOverloaded:
595 case LookupResult::FoundUnresolvedValue:
596 break;
597
598 case LookupResult::Ambiguous:
599 DiagnoseAmbiguousLookup(R);
600 return ExprError();
601 }
602
603 // FIXME: Variadic templates function parameter packs.
604 if (!ParameterPack || !ParameterPack->isTemplateParameterPack()) {
605 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
606 << &Name;
607 return ExprError();
608 }
609
610 return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc,
611 ParameterPack, NameLoc, RParenLoc);
612}