blob: 4e01ec2407dc576fcf4650c3941e1729d1761e5c [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
81 // FIXME: Record occurrences of template template parameter packs.
Douglas Gregor1da294a2010-12-15 19:43:21 +000082
Douglas Gregor1da294a2010-12-15 19:43:21 +000083 //------------------------------------------------------------------------
84 // Pruning the search for unexpanded parameter packs.
85 //------------------------------------------------------------------------
86
87 /// \brief Suppress traversal into statements and expressions that
88 /// do not contain unexpanded parameter packs.
89 bool TraverseStmt(Stmt *S) {
90 if (Expr *E = dyn_cast_or_null<Expr>(S))
91 if (E->containsUnexpandedParameterPack())
92 return inherited::TraverseStmt(E);
93
94 return true;
95 }
96
97 /// \brief Suppress traversal into types that do not contain
98 /// unexpanded parameter packs.
99 bool TraverseType(QualType T) {
100 if (!T.isNull() && T->containsUnexpandedParameterPack())
101 return inherited::TraverseType(T);
102
103 return true;
104 }
105
106 /// \brief Suppress traversel into types with location information
107 /// that do not contain unexpanded parameter packs.
108 bool TraverseTypeLoc(TypeLoc TL) {
Douglas Gregorda3cc0d2010-12-23 23:51:58 +0000109 if (!TL.getType().isNull() &&
110 TL.getType()->containsUnexpandedParameterPack())
Douglas Gregor1da294a2010-12-15 19:43:21 +0000111 return inherited::TraverseTypeLoc(TL);
112
113 return true;
114 }
115
Douglas Gregora8461bb2010-12-15 21:57:59 +0000116 /// \brief Suppress traversal of non-parameter declarations, since
117 /// they cannot contain unexpanded parameter packs.
118 bool TraverseDecl(Decl *D) {
119 if (D && isa<ParmVarDecl>(D))
120 return inherited::TraverseDecl(D);
121
122 return true;
123 }
Douglas Gregor1da294a2010-12-15 19:43:21 +0000124 };
125}
126
127/// \brief Diagnose all of the unexpanded parameter packs in the given
128/// vector.
129static void
130DiagnoseUnexpandedParameterPacks(Sema &S, SourceLocation Loc,
131 Sema::UnexpandedParameterPackContext UPPC,
132 const llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
133 llvm::SmallVector<SourceLocation, 4> Locations;
134 llvm::SmallVector<IdentifierInfo *, 4> Names;
135 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
136
137 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
138 IdentifierInfo *Name = 0;
139 if (const TemplateTypeParmType *TTP
140 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
141 Name = TTP->getName();
142 else
143 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
144
145 if (Name && NamesKnown.insert(Name))
146 Names.push_back(Name);
147
148 if (Unexpanded[I].second.isValid())
149 Locations.push_back(Unexpanded[I].second);
150 }
151
152 DiagnosticBuilder DB
153 = Names.size() == 0? S.Diag(Loc, diag::err_unexpanded_parameter_pack_0)
154 << (int)UPPC
155 : Names.size() == 1? S.Diag(Loc, diag::err_unexpanded_parameter_pack_1)
156 << (int)UPPC << Names[0]
157 : Names.size() == 2? S.Diag(Loc, diag::err_unexpanded_parameter_pack_2)
158 << (int)UPPC << Names[0] << Names[1]
159 : S.Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
160 << (int)UPPC << Names[0] << Names[1];
161
162 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
163 DB << SourceRange(Locations[I]);
164}
165
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000166bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
167 TypeSourceInfo *T,
168 UnexpandedParameterPackContext UPPC) {
169 // C++0x [temp.variadic]p5:
170 // An appearance of a name of a parameter pack that is not expanded is
171 // ill-formed.
172 if (!T->getType()->containsUnexpandedParameterPack())
173 return false;
174
Douglas Gregor1da294a2010-12-15 19:43:21 +0000175 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
176 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
177 T->getTypeLoc());
178 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
179 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000180 return true;
181}
182
183bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
Douglas Gregorc4356532010-12-16 00:46:58 +0000184 UnexpandedParameterPackContext UPPC) {
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000185 // C++0x [temp.variadic]p5:
186 // An appearance of a name of a parameter pack that is not expanded is
187 // ill-formed.
188 if (!E->containsUnexpandedParameterPack())
189 return false;
190
Douglas Gregor1da294a2010-12-15 19:43:21 +0000191 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
192 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
193 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
194 DiagnoseUnexpandedParameterPacks(*this, E->getLocStart(), UPPC, Unexpanded);
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000195 return true;
196}
Douglas Gregorc4356532010-12-16 00:46:58 +0000197
198bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
199 UnexpandedParameterPackContext UPPC) {
200 // C++0x [temp.variadic]p5:
201 // An appearance of a name of a parameter pack that is not expanded is
202 // ill-formed.
203 if (!SS.getScopeRep() ||
204 !SS.getScopeRep()->containsUnexpandedParameterPack())
205 return false;
206
207 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
208 CollectUnexpandedParameterPacksVisitor(Unexpanded)
209 .TraverseNestedNameSpecifier(SS.getScopeRep());
210 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
211 DiagnoseUnexpandedParameterPacks(*this, SS.getRange().getBegin(),
212 UPPC, Unexpanded);
213 return true;
214}
215
216bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
217 UnexpandedParameterPackContext UPPC) {
218 // C++0x [temp.variadic]p5:
219 // An appearance of a name of a parameter pack that is not expanded is
220 // ill-formed.
221 switch (NameInfo.getName().getNameKind()) {
222 case DeclarationName::Identifier:
223 case DeclarationName::ObjCZeroArgSelector:
224 case DeclarationName::ObjCOneArgSelector:
225 case DeclarationName::ObjCMultiArgSelector:
226 case DeclarationName::CXXOperatorName:
227 case DeclarationName::CXXLiteralOperatorName:
228 case DeclarationName::CXXUsingDirective:
229 return false;
230
231 case DeclarationName::CXXConstructorName:
232 case DeclarationName::CXXDestructorName:
233 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor062ecac2010-12-16 17:19:19 +0000234 // FIXME: We shouldn't need this null check!
Douglas Gregor6ab34af2010-12-16 01:40:04 +0000235 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
236 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
237
238 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
Douglas Gregorc4356532010-12-16 00:46:58 +0000239 return false;
Douglas Gregor6ab34af2010-12-16 01:40:04 +0000240
Douglas Gregorc4356532010-12-16 00:46:58 +0000241 break;
242 }
243
244 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
245 CollectUnexpandedParameterPacksVisitor(Unexpanded)
Douglas Gregor6ab34af2010-12-16 01:40:04 +0000246 .TraverseType(NameInfo.getName().getCXXNameType());
Douglas Gregorc4356532010-12-16 00:46:58 +0000247 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
248 DiagnoseUnexpandedParameterPacks(*this, NameInfo.getLoc(), UPPC, Unexpanded);
249 return true;
250}
Douglas Gregor6ff1fbf2010-12-16 08:48:57 +0000251
252bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
253 TemplateName Template,
254 UnexpandedParameterPackContext UPPC) {
255
256 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
257 return false;
258
259 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
260 CollectUnexpandedParameterPacksVisitor(Unexpanded)
261 .TraverseTemplateName(Template);
262 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
263 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
264 return true;
265}
266
Douglas Gregor14406932011-01-03 20:35:03 +0000267bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
268 UnexpandedParameterPackContext UPPC) {
269 if (Arg.getArgument().isNull() ||
270 !Arg.getArgument().containsUnexpandedParameterPack())
271 return false;
272
273 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
274 CollectUnexpandedParameterPacksVisitor(Unexpanded)
275 .TraverseTemplateArgumentLoc(Arg);
276 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
277 DiagnoseUnexpandedParameterPacks(*this, Arg.getLocation(), UPPC, Unexpanded);
278 return true;
279}
280
Douglas Gregor0f3feb42010-12-22 21:19:48 +0000281void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
282 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
283 CollectUnexpandedParameterPacksVisitor(Unexpanded)
284 .TraverseTemplateArgument(Arg);
285}
286
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000287void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
288 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
289 CollectUnexpandedParameterPacksVisitor(Unexpanded)
290 .TraverseTemplateArgumentLoc(Arg);
291}
292
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000293void Sema::collectUnexpandedParameterPacks(QualType T,
294 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
295 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
296}
297
Douglas Gregor752a5952011-01-03 22:36:02 +0000298void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
299 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
300 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
301}
302
Douglas Gregord2fa7662010-12-20 02:24:11 +0000303ParsedTemplateArgument
304Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
305 SourceLocation EllipsisLoc) {
306 if (Arg.isInvalid())
307 return Arg;
308
309 switch (Arg.getKind()) {
310 case ParsedTemplateArgument::Type: {
311 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
312 if (Result.isInvalid())
313 return ParsedTemplateArgument();
314
315 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
316 Arg.getLocation());
317 }
318
Douglas Gregore8e9dd62011-01-03 17:17:50 +0000319 case ParsedTemplateArgument::NonType: {
320 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
321 if (Result.isInvalid())
322 return ParsedTemplateArgument();
323
324 return ParsedTemplateArgument(Arg.getKind(), Result.get(),
325 Arg.getLocation());
326 }
327
Douglas Gregord2fa7662010-12-20 02:24:11 +0000328 case ParsedTemplateArgument::Template:
Douglas Gregore8e9dd62011-01-03 17:17:50 +0000329 Diag(EllipsisLoc, diag::err_pack_expansion_unsupported);
Douglas Gregord2fa7662010-12-20 02:24:11 +0000330 return ParsedTemplateArgument();
331 }
332 llvm_unreachable("Unhandled template argument kind?");
333 return ParsedTemplateArgument();
334}
335
336TypeResult Sema::ActOnPackExpansion(ParsedType Type,
337 SourceLocation EllipsisLoc) {
338 TypeSourceInfo *TSInfo;
339 GetTypeFromParser(Type, &TSInfo);
340 if (!TSInfo)
341 return true;
342
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000343 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc);
344 if (!TSResult)
345 return true;
346
347 return CreateParsedType(TSResult->getType(), TSResult);
348}
349
350TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
351 SourceLocation EllipsisLoc) {
Douglas Gregord2fa7662010-12-20 02:24:11 +0000352 // C++0x [temp.variadic]p5:
353 // The pattern of a pack expansion shall name one or more
354 // parameter packs that are not expanded by a nested pack
355 // expansion.
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000356 if (!Pattern->getType()->containsUnexpandedParameterPack()) {
Douglas Gregord2fa7662010-12-20 02:24:11 +0000357 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000358 << Pattern->getTypeLoc().getSourceRange();
359 return 0;
Douglas Gregord2fa7662010-12-20 02:24:11 +0000360 }
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000361
Douglas Gregord2fa7662010-12-20 02:24:11 +0000362 // Create the pack expansion type and source-location information.
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000363 QualType Result = Context.getPackExpansionType(Pattern->getType());
Douglas Gregord2fa7662010-12-20 02:24:11 +0000364 TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
365 PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc());
366 TL.setEllipsisLoc(EllipsisLoc);
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000367
Douglas Gregord2fa7662010-12-20 02:24:11 +0000368 // Copy over the source-location information from the type.
369 memcpy(TL.getNextTypeLoc().getOpaqueData(),
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000370 Pattern->getTypeLoc().getOpaqueData(),
371 Pattern->getTypeLoc().getFullDataSize());
372 return TSResult;
Douglas Gregord2fa7662010-12-20 02:24:11 +0000373}
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000374
Douglas Gregore8e9dd62011-01-03 17:17:50 +0000375ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
376 if (!Pattern)
377 return ExprError();
378
379 // C++0x [temp.variadic]p5:
380 // The pattern of a pack expansion shall name one or more
381 // parameter packs that are not expanded by a nested pack
382 // expansion.
383 if (!Pattern->containsUnexpandedParameterPack()) {
384 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
385 << Pattern->getSourceRange();
386 return ExprError();
387 }
388
389 // Create the pack expansion expression and source-location information.
390 return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
391 EllipsisLoc));
392}
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000393
394bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
395 SourceRange PatternRange,
396 const UnexpandedParameterPack *Unexpanded,
397 unsigned NumUnexpanded,
398 const MultiLevelTemplateArgumentList &TemplateArgs,
399 bool &ShouldExpand,
400 unsigned &NumExpansions) {
401 ShouldExpand = true;
402 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
403 bool HaveFirstPack = false;
404
405 for (unsigned I = 0; I != NumUnexpanded; ++I) {
406 // Compute the depth and index for this parameter pack.
407 unsigned Depth;
408 unsigned Index;
409 IdentifierInfo *Name;
410
411 if (const TemplateTypeParmType *TTP
412 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
413 Depth = TTP->getDepth();
414 Index = TTP->getIndex();
415 Name = TTP->getName();
416 } else {
417 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
418 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) {
419 Depth = TTP->getDepth();
420 Index = TTP->getIndex();
421 } else if (NonTypeTemplateParmDecl *NTTP
422 = dyn_cast<NonTypeTemplateParmDecl>(ND)) {
423 Depth = NTTP->getDepth();
424 Index = NTTP->getIndex();
425 } else {
426 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
427 Depth = TTP->getDepth();
428 Index = TTP->getIndex();
429 }
430 // FIXME: Variadic templates function parameter packs?
431 Name = ND->getIdentifier();
432 }
433
434 // If we don't have a template argument at this depth/index, then we
435 // cannot expand the pack expansion. Make a note of this, but we still
Douglas Gregoreb5a39d2010-12-24 00:15:10 +0000436 // want to check any parameter packs we *do* have arguments for.
Douglas Gregor98318c22011-01-03 21:37:45 +0000437 if (Depth >= TemplateArgs.getNumLevels() ||
438 !TemplateArgs.hasTemplateArgument(Depth, Index)) {
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000439 ShouldExpand = false;
440 continue;
441 }
442
443 // Determine the size of the argument pack.
444 unsigned NewPackSize = TemplateArgs(Depth, Index).pack_size();
445 if (!HaveFirstPack) {
446 // The is the first pack we've seen for which we have an argument.
447 // Record it.
448 NumExpansions = NewPackSize;
449 FirstPack.first = Name;
450 FirstPack.second = Unexpanded[I].second;
451 HaveFirstPack = true;
452 continue;
453 }
454
455 if (NewPackSize != NumExpansions) {
456 // C++0x [temp.variadic]p5:
457 // All of the parameter packs expanded by a pack expansion shall have
458 // the same number of arguments specified.
459 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
460 << FirstPack.first << Name << NumExpansions << NewPackSize
461 << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
462 return true;
463 }
464 }
465
466 return false;
467}
Douglas Gregor27b4c162010-12-23 22:44:42 +0000468
469bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
470 const DeclSpec &DS = D.getDeclSpec();
471 switch (DS.getTypeSpecType()) {
472 case TST_typename:
473 case TST_typeofType: {
474 QualType T = DS.getRepAsType().get();
475 if (!T.isNull() && T->containsUnexpandedParameterPack())
476 return true;
477 break;
478 }
479
480 case TST_typeofExpr:
481 case TST_decltype:
482 if (DS.getRepAsExpr() &&
483 DS.getRepAsExpr()->containsUnexpandedParameterPack())
484 return true;
485 break;
486
487 case TST_unspecified:
488 case TST_void:
489 case TST_char:
490 case TST_wchar:
491 case TST_char16:
492 case TST_char32:
493 case TST_int:
494 case TST_float:
495 case TST_double:
496 case TST_bool:
497 case TST_decimal32:
498 case TST_decimal64:
499 case TST_decimal128:
500 case TST_enum:
501 case TST_union:
502 case TST_struct:
503 case TST_class:
504 case TST_auto:
505 case TST_error:
506 break;
507 }
508
509 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
510 const DeclaratorChunk &Chunk = D.getTypeObject(I);
511 switch (Chunk.Kind) {
512 case DeclaratorChunk::Pointer:
513 case DeclaratorChunk::Reference:
514 case DeclaratorChunk::Paren:
515 // These declarator chunks cannot contain any parameter packs.
516 break;
517
518 case DeclaratorChunk::Array:
519 case DeclaratorChunk::Function:
520 case DeclaratorChunk::BlockPointer:
521 // Syntactically, these kinds of declarator chunks all come after the
522 // declarator-id (conceptually), so the parser should not invoke this
523 // routine at this time.
524 llvm_unreachable("Could not have seen this kind of declarator chunk");
525 break;
526
527 case DeclaratorChunk::MemberPointer:
528 if (Chunk.Mem.Scope().getScopeRep() &&
529 Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
530 return true;
531 break;
532 }
533 }
534
535 return false;
536}
Douglas Gregor820ba7b2011-01-04 17:33:58 +0000537
538/// \brief Called when an expression computing the size of a parameter pack
539/// is parsed.
540///
541/// \code
542/// template<typename ...Types> struct count {
543/// static const unsigned value = sizeof...(Types);
544/// };
545/// \endcode
546///
547//
548/// \param OpLoc The location of the "sizeof" keyword.
549/// \param Name The name of the parameter pack whose size will be determined.
550/// \param NameLoc The source location of the name of the parameter pack.
551/// \param RParenLoc The location of the closing parentheses.
552ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
553 SourceLocation OpLoc,
554 IdentifierInfo &Name,
555 SourceLocation NameLoc,
556 SourceLocation RParenLoc) {
557 // C++0x [expr.sizeof]p5:
558 // The identifier in a sizeof... expression shall name a parameter pack.
559
560 LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
561 LookupName(R, S);
562
563 NamedDecl *ParameterPack = 0;
564 switch (R.getResultKind()) {
565 case LookupResult::Found:
566 ParameterPack = R.getFoundDecl();
567 break;
568
569 case LookupResult::NotFound:
570 case LookupResult::NotFoundInCurrentInstantiation:
571 if (DeclarationName CorrectedName = CorrectTypo(R, S, 0, 0, false,
572 CTC_NoKeywords)) {
573 // FIXME: Variadic templates function parameter packs.
574 if (NamedDecl *CorrectedResult = R.getAsSingle<NamedDecl>())
575 if (CorrectedResult->isTemplateParameterPack()) {
576 ParameterPack = CorrectedResult;
577 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
578 << &Name << CorrectedName
579 << FixItHint::CreateReplacement(NameLoc,
580 CorrectedName.getAsString());
581 Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
582 << CorrectedName;
583 }
584 }
585
586 case LookupResult::FoundOverloaded:
587 case LookupResult::FoundUnresolvedValue:
588 break;
589
590 case LookupResult::Ambiguous:
591 DiagnoseAmbiguousLookup(R);
592 return ExprError();
593 }
594
595 // FIXME: Variadic templates function parameter packs.
596 if (!ParameterPack || !ParameterPack->isTemplateParameterPack()) {
597 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
598 << &Name;
599 return ExprError();
600 }
601
602 return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc,
603 ParameterPack, NameLoc, RParenLoc);
604}