blob: 828d2a3539e447799f41969e72cedb7a79e2e20b [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 Gregor7536dd52010-12-20 02:24:11 +000013#include "clang/Sema/ParsedTemplate.h"
Douglas Gregorc4633352010-12-15 17:38:57 +000014#include "clang/Sema/SemaInternal.h"
Douglas Gregor8491ffe2010-12-20 22:05:00 +000015#include "clang/Sema/Template.h"
Douglas Gregorc4633352010-12-15 17:38:57 +000016#include "clang/AST/Expr.h"
Douglas Gregor9ef75892010-12-15 19:43:21 +000017#include "clang/AST/RecursiveASTVisitor.h"
Douglas Gregorc4633352010-12-15 17:38:57 +000018#include "clang/AST/TypeLoc.h"
19
20using namespace clang;
21
Douglas Gregor9ef75892010-12-15 19:43:21 +000022//----------------------------------------------------------------------------
23// Visitor that collects unexpanded parameter packs
24//----------------------------------------------------------------------------
25
Douglas Gregor9ef75892010-12-15 19:43:21 +000026namespace {
27 /// \brief A class that collects unexpanded parameter packs.
28 class CollectUnexpandedParameterPacksVisitor :
29 public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
30 {
31 typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
32 inherited;
33
34 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
35
36 public:
37 explicit CollectUnexpandedParameterPacksVisitor(
38 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
39 : Unexpanded(Unexpanded) { }
40
Douglas Gregora40bc722010-12-20 23:07:20 +000041 bool shouldWalkTypesOfTypeLocs() const { return false; }
42
Douglas Gregor9ef75892010-12-15 19:43:21 +000043 //------------------------------------------------------------------------
44 // Recording occurrences of (unexpanded) parameter packs.
45 //------------------------------------------------------------------------
46
47 /// \brief Record occurrences of template type parameter packs.
48 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
49 if (TL.getTypePtr()->isParameterPack())
50 Unexpanded.push_back(std::make_pair(TL.getTypePtr(), TL.getNameLoc()));
51 return true;
52 }
53
54 /// \brief Record occurrences of template type parameter packs
55 /// when we don't have proper source-location information for
56 /// them.
57 ///
58 /// Ideally, this routine would never be used.
59 bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
60 if (T->isParameterPack())
61 Unexpanded.push_back(std::make_pair(T, SourceLocation()));
62
63 return true;
64 }
65
Douglas Gregor10738d32010-12-23 23:51:58 +000066 /// \brief Record occurrences of (FIXME: function and) non-type template
67 /// parameter packs in an expression.
68 bool VisitDeclRefExpr(DeclRefExpr *E) {
69 if (NonTypeTemplateParmDecl *NTTP
70 = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) {
71 if (NTTP->isParameterPack())
72 Unexpanded.push_back(std::make_pair(NTTP, E->getLocation()));
73 }
74
75 // FIXME: Function parameter packs.
76
77 return true;
78 }
79
80 // FIXME: Record occurrences of template template parameter packs.
Douglas Gregor9ef75892010-12-15 19:43:21 +000081
Douglas Gregor9ef75892010-12-15 19:43:21 +000082 //------------------------------------------------------------------------
83 // Pruning the search for unexpanded parameter packs.
84 //------------------------------------------------------------------------
85
86 /// \brief Suppress traversal into statements and expressions that
87 /// do not contain unexpanded parameter packs.
88 bool TraverseStmt(Stmt *S) {
89 if (Expr *E = dyn_cast_or_null<Expr>(S))
90 if (E->containsUnexpandedParameterPack())
91 return inherited::TraverseStmt(E);
92
93 return true;
94 }
95
96 /// \brief Suppress traversal into types that do not contain
97 /// unexpanded parameter packs.
98 bool TraverseType(QualType T) {
99 if (!T.isNull() && T->containsUnexpandedParameterPack())
100 return inherited::TraverseType(T);
101
102 return true;
103 }
104
105 /// \brief Suppress traversel into types with location information
106 /// that do not contain unexpanded parameter packs.
107 bool TraverseTypeLoc(TypeLoc TL) {
Douglas Gregor10738d32010-12-23 23:51:58 +0000108 if (!TL.getType().isNull() &&
109 TL.getType()->containsUnexpandedParameterPack())
Douglas Gregor9ef75892010-12-15 19:43:21 +0000110 return inherited::TraverseTypeLoc(TL);
111
112 return true;
113 }
114
Douglas Gregorcff163e2010-12-15 21:57:59 +0000115 /// \brief Suppress traversal of non-parameter declarations, since
116 /// they cannot contain unexpanded parameter packs.
117 bool TraverseDecl(Decl *D) {
118 if (D && isa<ParmVarDecl>(D))
119 return inherited::TraverseDecl(D);
120
121 return true;
122 }
Douglas Gregor9ef75892010-12-15 19:43:21 +0000123 };
124}
125
126/// \brief Diagnose all of the unexpanded parameter packs in the given
127/// vector.
128static void
129DiagnoseUnexpandedParameterPacks(Sema &S, SourceLocation Loc,
130 Sema::UnexpandedParameterPackContext UPPC,
131 const llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
132 llvm::SmallVector<SourceLocation, 4> Locations;
133 llvm::SmallVector<IdentifierInfo *, 4> Names;
134 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
135
136 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
137 IdentifierInfo *Name = 0;
138 if (const TemplateTypeParmType *TTP
139 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
140 Name = TTP->getName();
141 else
142 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
143
144 if (Name && NamesKnown.insert(Name))
145 Names.push_back(Name);
146
147 if (Unexpanded[I].second.isValid())
148 Locations.push_back(Unexpanded[I].second);
149 }
150
151 DiagnosticBuilder DB
152 = Names.size() == 0? S.Diag(Loc, diag::err_unexpanded_parameter_pack_0)
153 << (int)UPPC
154 : Names.size() == 1? S.Diag(Loc, diag::err_unexpanded_parameter_pack_1)
155 << (int)UPPC << Names[0]
156 : Names.size() == 2? S.Diag(Loc, diag::err_unexpanded_parameter_pack_2)
157 << (int)UPPC << Names[0] << Names[1]
158 : S.Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
159 << (int)UPPC << Names[0] << Names[1];
160
161 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
162 DB << SourceRange(Locations[I]);
163}
164
Douglas Gregorc4633352010-12-15 17:38:57 +0000165bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
166 TypeSourceInfo *T,
167 UnexpandedParameterPackContext UPPC) {
168 // C++0x [temp.variadic]p5:
169 // An appearance of a name of a parameter pack that is not expanded is
170 // ill-formed.
171 if (!T->getType()->containsUnexpandedParameterPack())
172 return false;
173
Douglas Gregor9ef75892010-12-15 19:43:21 +0000174 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
175 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
176 T->getTypeLoc());
177 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
178 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
Douglas Gregorc4633352010-12-15 17:38:57 +0000179 return true;
180}
181
182bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
Douglas Gregor56c04582010-12-16 00:46:58 +0000183 UnexpandedParameterPackContext UPPC) {
Douglas Gregorc4633352010-12-15 17:38:57 +0000184 // C++0x [temp.variadic]p5:
185 // An appearance of a name of a parameter pack that is not expanded is
186 // ill-formed.
187 if (!E->containsUnexpandedParameterPack())
188 return false;
189
Douglas Gregor9ef75892010-12-15 19:43:21 +0000190 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
191 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
192 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
193 DiagnoseUnexpandedParameterPacks(*this, E->getLocStart(), UPPC, Unexpanded);
Douglas Gregorc4633352010-12-15 17:38:57 +0000194 return true;
195}
Douglas Gregor56c04582010-12-16 00:46:58 +0000196
197bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
198 UnexpandedParameterPackContext UPPC) {
199 // C++0x [temp.variadic]p5:
200 // An appearance of a name of a parameter pack that is not expanded is
201 // ill-formed.
202 if (!SS.getScopeRep() ||
203 !SS.getScopeRep()->containsUnexpandedParameterPack())
204 return false;
205
206 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
207 CollectUnexpandedParameterPacksVisitor(Unexpanded)
208 .TraverseNestedNameSpecifier(SS.getScopeRep());
209 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
210 DiagnoseUnexpandedParameterPacks(*this, SS.getRange().getBegin(),
211 UPPC, Unexpanded);
212 return true;
213}
214
215bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
216 UnexpandedParameterPackContext UPPC) {
217 // C++0x [temp.variadic]p5:
218 // An appearance of a name of a parameter pack that is not expanded is
219 // ill-formed.
220 switch (NameInfo.getName().getNameKind()) {
221 case DeclarationName::Identifier:
222 case DeclarationName::ObjCZeroArgSelector:
223 case DeclarationName::ObjCOneArgSelector:
224 case DeclarationName::ObjCMultiArgSelector:
225 case DeclarationName::CXXOperatorName:
226 case DeclarationName::CXXLiteralOperatorName:
227 case DeclarationName::CXXUsingDirective:
228 return false;
229
230 case DeclarationName::CXXConstructorName:
231 case DeclarationName::CXXDestructorName:
232 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor099ffe82010-12-16 17:19:19 +0000233 // FIXME: We shouldn't need this null check!
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000234 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
235 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
236
237 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
Douglas Gregor56c04582010-12-16 00:46:58 +0000238 return false;
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000239
Douglas Gregor56c04582010-12-16 00:46:58 +0000240 break;
241 }
242
243 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
244 CollectUnexpandedParameterPacksVisitor(Unexpanded)
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000245 .TraverseType(NameInfo.getName().getCXXNameType());
Douglas Gregor56c04582010-12-16 00:46:58 +0000246 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
247 DiagnoseUnexpandedParameterPacks(*this, NameInfo.getLoc(), UPPC, Unexpanded);
248 return true;
249}
Douglas Gregor6f526752010-12-16 08:48:57 +0000250
251bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
252 TemplateName Template,
253 UnexpandedParameterPackContext UPPC) {
254
255 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
256 return false;
257
258 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
259 CollectUnexpandedParameterPacksVisitor(Unexpanded)
260 .TraverseTemplateName(Template);
261 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
262 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
263 return true;
264}
265
Douglas Gregor925910d2011-01-03 20:35:03 +0000266bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
267 UnexpandedParameterPackContext UPPC) {
268 if (Arg.getArgument().isNull() ||
269 !Arg.getArgument().containsUnexpandedParameterPack())
270 return false;
271
272 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
273 CollectUnexpandedParameterPacksVisitor(Unexpanded)
274 .TraverseTemplateArgumentLoc(Arg);
275 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
276 DiagnoseUnexpandedParameterPacks(*this, Arg.getLocation(), UPPC, Unexpanded);
277 return true;
278}
279
Douglas Gregore02e2622010-12-22 21:19:48 +0000280void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
281 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
282 CollectUnexpandedParameterPacksVisitor(Unexpanded)
283 .TraverseTemplateArgument(Arg);
284}
285
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000286void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
287 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
288 CollectUnexpandedParameterPacksVisitor(Unexpanded)
289 .TraverseTemplateArgumentLoc(Arg);
290}
291
Douglas Gregorb99268b2010-12-21 00:52:54 +0000292void Sema::collectUnexpandedParameterPacks(QualType T,
293 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
294 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
295}
296
Douglas Gregor7536dd52010-12-20 02:24:11 +0000297ParsedTemplateArgument
298Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
299 SourceLocation EllipsisLoc) {
300 if (Arg.isInvalid())
301 return Arg;
302
303 switch (Arg.getKind()) {
304 case ParsedTemplateArgument::Type: {
305 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
306 if (Result.isInvalid())
307 return ParsedTemplateArgument();
308
309 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
310 Arg.getLocation());
311 }
312
Douglas Gregorbe230c32011-01-03 17:17:50 +0000313 case ParsedTemplateArgument::NonType: {
314 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
315 if (Result.isInvalid())
316 return ParsedTemplateArgument();
317
318 return ParsedTemplateArgument(Arg.getKind(), Result.get(),
319 Arg.getLocation());
320 }
321
Douglas Gregor7536dd52010-12-20 02:24:11 +0000322 case ParsedTemplateArgument::Template:
Douglas Gregorbe230c32011-01-03 17:17:50 +0000323 Diag(EllipsisLoc, diag::err_pack_expansion_unsupported);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000324 return ParsedTemplateArgument();
325 }
326 llvm_unreachable("Unhandled template argument kind?");
327 return ParsedTemplateArgument();
328}
329
330TypeResult Sema::ActOnPackExpansion(ParsedType Type,
331 SourceLocation EllipsisLoc) {
332 TypeSourceInfo *TSInfo;
333 GetTypeFromParser(Type, &TSInfo);
334 if (!TSInfo)
335 return true;
336
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000337 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc);
338 if (!TSResult)
339 return true;
340
341 return CreateParsedType(TSResult->getType(), TSResult);
342}
343
344TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
345 SourceLocation EllipsisLoc) {
Douglas Gregor7536dd52010-12-20 02:24:11 +0000346 // C++0x [temp.variadic]p5:
347 // The pattern of a pack expansion shall name one or more
348 // parameter packs that are not expanded by a nested pack
349 // expansion.
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000350 if (!Pattern->getType()->containsUnexpandedParameterPack()) {
Douglas Gregor7536dd52010-12-20 02:24:11 +0000351 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000352 << Pattern->getTypeLoc().getSourceRange();
353 return 0;
Douglas Gregor7536dd52010-12-20 02:24:11 +0000354 }
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000355
Douglas Gregor7536dd52010-12-20 02:24:11 +0000356 // Create the pack expansion type and source-location information.
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000357 QualType Result = Context.getPackExpansionType(Pattern->getType());
Douglas Gregor7536dd52010-12-20 02:24:11 +0000358 TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
359 PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc());
360 TL.setEllipsisLoc(EllipsisLoc);
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000361
Douglas Gregor7536dd52010-12-20 02:24:11 +0000362 // Copy over the source-location information from the type.
363 memcpy(TL.getNextTypeLoc().getOpaqueData(),
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000364 Pattern->getTypeLoc().getOpaqueData(),
365 Pattern->getTypeLoc().getFullDataSize());
366 return TSResult;
Douglas Gregor7536dd52010-12-20 02:24:11 +0000367}
Douglas Gregorb99268b2010-12-21 00:52:54 +0000368
Douglas Gregorbe230c32011-01-03 17:17:50 +0000369ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
370 if (!Pattern)
371 return ExprError();
372
373 // C++0x [temp.variadic]p5:
374 // The pattern of a pack expansion shall name one or more
375 // parameter packs that are not expanded by a nested pack
376 // expansion.
377 if (!Pattern->containsUnexpandedParameterPack()) {
378 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
379 << Pattern->getSourceRange();
380 return ExprError();
381 }
382
383 // Create the pack expansion expression and source-location information.
384 return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
385 EllipsisLoc));
386}
Douglas Gregorb99268b2010-12-21 00:52:54 +0000387
388bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
389 SourceRange PatternRange,
390 const UnexpandedParameterPack *Unexpanded,
391 unsigned NumUnexpanded,
392 const MultiLevelTemplateArgumentList &TemplateArgs,
393 bool &ShouldExpand,
394 unsigned &NumExpansions) {
395 ShouldExpand = true;
396 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
397 bool HaveFirstPack = false;
398
399 for (unsigned I = 0; I != NumUnexpanded; ++I) {
400 // Compute the depth and index for this parameter pack.
401 unsigned Depth;
402 unsigned Index;
403 IdentifierInfo *Name;
404
405 if (const TemplateTypeParmType *TTP
406 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
407 Depth = TTP->getDepth();
408 Index = TTP->getIndex();
409 Name = TTP->getName();
410 } else {
411 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
412 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) {
413 Depth = TTP->getDepth();
414 Index = TTP->getIndex();
415 } else if (NonTypeTemplateParmDecl *NTTP
416 = dyn_cast<NonTypeTemplateParmDecl>(ND)) {
417 Depth = NTTP->getDepth();
418 Index = NTTP->getIndex();
419 } else {
420 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
421 Depth = TTP->getDepth();
422 Index = TTP->getIndex();
423 }
424 // FIXME: Variadic templates function parameter packs?
425 Name = ND->getIdentifier();
426 }
427
428 // If we don't have a template argument at this depth/index, then we
429 // cannot expand the pack expansion. Make a note of this, but we still
Douglas Gregor56bc9832010-12-24 00:15:10 +0000430 // want to check any parameter packs we *do* have arguments for.
Douglas Gregorb99268b2010-12-21 00:52:54 +0000431 if (!TemplateArgs.hasTemplateArgument(Depth, Index)) {
432 ShouldExpand = false;
433 continue;
434 }
435
436 // Determine the size of the argument pack.
437 unsigned NewPackSize = TemplateArgs(Depth, Index).pack_size();
438 if (!HaveFirstPack) {
439 // The is the first pack we've seen for which we have an argument.
440 // Record it.
441 NumExpansions = NewPackSize;
442 FirstPack.first = Name;
443 FirstPack.second = Unexpanded[I].second;
444 HaveFirstPack = true;
445 continue;
446 }
447
448 if (NewPackSize != NumExpansions) {
449 // C++0x [temp.variadic]p5:
450 // All of the parameter packs expanded by a pack expansion shall have
451 // the same number of arguments specified.
452 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
453 << FirstPack.first << Name << NumExpansions << NewPackSize
454 << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
455 return true;
456 }
457 }
458
459 return false;
460}
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000461
462bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
463 const DeclSpec &DS = D.getDeclSpec();
464 switch (DS.getTypeSpecType()) {
465 case TST_typename:
466 case TST_typeofType: {
467 QualType T = DS.getRepAsType().get();
468 if (!T.isNull() && T->containsUnexpandedParameterPack())
469 return true;
470 break;
471 }
472
473 case TST_typeofExpr:
474 case TST_decltype:
475 if (DS.getRepAsExpr() &&
476 DS.getRepAsExpr()->containsUnexpandedParameterPack())
477 return true;
478 break;
479
480 case TST_unspecified:
481 case TST_void:
482 case TST_char:
483 case TST_wchar:
484 case TST_char16:
485 case TST_char32:
486 case TST_int:
487 case TST_float:
488 case TST_double:
489 case TST_bool:
490 case TST_decimal32:
491 case TST_decimal64:
492 case TST_decimal128:
493 case TST_enum:
494 case TST_union:
495 case TST_struct:
496 case TST_class:
497 case TST_auto:
498 case TST_error:
499 break;
500 }
501
502 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
503 const DeclaratorChunk &Chunk = D.getTypeObject(I);
504 switch (Chunk.Kind) {
505 case DeclaratorChunk::Pointer:
506 case DeclaratorChunk::Reference:
507 case DeclaratorChunk::Paren:
508 // These declarator chunks cannot contain any parameter packs.
509 break;
510
511 case DeclaratorChunk::Array:
512 case DeclaratorChunk::Function:
513 case DeclaratorChunk::BlockPointer:
514 // Syntactically, these kinds of declarator chunks all come after the
515 // declarator-id (conceptually), so the parser should not invoke this
516 // routine at this time.
517 llvm_unreachable("Could not have seen this kind of declarator chunk");
518 break;
519
520 case DeclaratorChunk::MemberPointer:
521 if (Chunk.Mem.Scope().getScopeRep() &&
522 Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
523 return true;
524 break;
525 }
526 }
527
528 return false;
529}