blob: 92df1fd86368ec076acd7cf838944fcc9a8ca6f4 [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 Gregorf90b27a2011-01-03 22:36:02 +0000297void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
298 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
299 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
300}
301
Douglas Gregor7536dd52010-12-20 02:24:11 +0000302ParsedTemplateArgument
303Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
304 SourceLocation EllipsisLoc) {
305 if (Arg.isInvalid())
306 return Arg;
307
308 switch (Arg.getKind()) {
309 case ParsedTemplateArgument::Type: {
310 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
311 if (Result.isInvalid())
312 return ParsedTemplateArgument();
313
314 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
315 Arg.getLocation());
316 }
317
Douglas Gregorbe230c32011-01-03 17:17:50 +0000318 case ParsedTemplateArgument::NonType: {
319 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
320 if (Result.isInvalid())
321 return ParsedTemplateArgument();
322
323 return ParsedTemplateArgument(Arg.getKind(), Result.get(),
324 Arg.getLocation());
325 }
326
Douglas Gregor7536dd52010-12-20 02:24:11 +0000327 case ParsedTemplateArgument::Template:
Douglas Gregorbe230c32011-01-03 17:17:50 +0000328 Diag(EllipsisLoc, diag::err_pack_expansion_unsupported);
Douglas Gregor7536dd52010-12-20 02:24:11 +0000329 return ParsedTemplateArgument();
330 }
331 llvm_unreachable("Unhandled template argument kind?");
332 return ParsedTemplateArgument();
333}
334
335TypeResult Sema::ActOnPackExpansion(ParsedType Type,
336 SourceLocation EllipsisLoc) {
337 TypeSourceInfo *TSInfo;
338 GetTypeFromParser(Type, &TSInfo);
339 if (!TSInfo)
340 return true;
341
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000342 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc);
343 if (!TSResult)
344 return true;
345
346 return CreateParsedType(TSResult->getType(), TSResult);
347}
348
349TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
350 SourceLocation EllipsisLoc) {
Douglas Gregor7536dd52010-12-20 02:24:11 +0000351 // C++0x [temp.variadic]p5:
352 // The pattern of a pack expansion shall name one or more
353 // parameter packs that are not expanded by a nested pack
354 // expansion.
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000355 if (!Pattern->getType()->containsUnexpandedParameterPack()) {
Douglas Gregor7536dd52010-12-20 02:24:11 +0000356 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000357 << Pattern->getTypeLoc().getSourceRange();
358 return 0;
Douglas Gregor7536dd52010-12-20 02:24:11 +0000359 }
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000360
Douglas Gregor7536dd52010-12-20 02:24:11 +0000361 // Create the pack expansion type and source-location information.
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000362 QualType Result = Context.getPackExpansionType(Pattern->getType());
Douglas Gregor7536dd52010-12-20 02:24:11 +0000363 TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
364 PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc());
365 TL.setEllipsisLoc(EllipsisLoc);
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000366
Douglas Gregor7536dd52010-12-20 02:24:11 +0000367 // Copy over the source-location information from the type.
368 memcpy(TL.getNextTypeLoc().getOpaqueData(),
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000369 Pattern->getTypeLoc().getOpaqueData(),
370 Pattern->getTypeLoc().getFullDataSize());
371 return TSResult;
Douglas Gregor7536dd52010-12-20 02:24:11 +0000372}
Douglas Gregorb99268b2010-12-21 00:52:54 +0000373
Douglas Gregorbe230c32011-01-03 17:17:50 +0000374ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
375 if (!Pattern)
376 return ExprError();
377
378 // C++0x [temp.variadic]p5:
379 // The pattern of a pack expansion shall name one or more
380 // parameter packs that are not expanded by a nested pack
381 // expansion.
382 if (!Pattern->containsUnexpandedParameterPack()) {
383 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
384 << Pattern->getSourceRange();
385 return ExprError();
386 }
387
388 // Create the pack expansion expression and source-location information.
389 return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
390 EllipsisLoc));
391}
Douglas Gregorb99268b2010-12-21 00:52:54 +0000392
393bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
394 SourceRange PatternRange,
395 const UnexpandedParameterPack *Unexpanded,
396 unsigned NumUnexpanded,
397 const MultiLevelTemplateArgumentList &TemplateArgs,
398 bool &ShouldExpand,
399 unsigned &NumExpansions) {
400 ShouldExpand = true;
401 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
402 bool HaveFirstPack = false;
403
404 for (unsigned I = 0; I != NumUnexpanded; ++I) {
405 // Compute the depth and index for this parameter pack.
406 unsigned Depth;
407 unsigned Index;
408 IdentifierInfo *Name;
409
410 if (const TemplateTypeParmType *TTP
411 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
412 Depth = TTP->getDepth();
413 Index = TTP->getIndex();
414 Name = TTP->getName();
415 } else {
416 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
417 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) {
418 Depth = TTP->getDepth();
419 Index = TTP->getIndex();
420 } else if (NonTypeTemplateParmDecl *NTTP
421 = dyn_cast<NonTypeTemplateParmDecl>(ND)) {
422 Depth = NTTP->getDepth();
423 Index = NTTP->getIndex();
424 } else {
425 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
426 Depth = TTP->getDepth();
427 Index = TTP->getIndex();
428 }
429 // FIXME: Variadic templates function parameter packs?
430 Name = ND->getIdentifier();
431 }
432
433 // If we don't have a template argument at this depth/index, then we
434 // cannot expand the pack expansion. Make a note of this, but we still
Douglas Gregor56bc9832010-12-24 00:15:10 +0000435 // want to check any parameter packs we *do* have arguments for.
Douglas Gregor7a21fd42011-01-03 21:37:45 +0000436 if (Depth >= TemplateArgs.getNumLevels() ||
437 !TemplateArgs.hasTemplateArgument(Depth, Index)) {
Douglas Gregorb99268b2010-12-21 00:52:54 +0000438 ShouldExpand = false;
439 continue;
440 }
441
442 // Determine the size of the argument pack.
443 unsigned NewPackSize = TemplateArgs(Depth, Index).pack_size();
444 if (!HaveFirstPack) {
445 // The is the first pack we've seen for which we have an argument.
446 // Record it.
447 NumExpansions = NewPackSize;
448 FirstPack.first = Name;
449 FirstPack.second = Unexpanded[I].second;
450 HaveFirstPack = true;
451 continue;
452 }
453
454 if (NewPackSize != NumExpansions) {
455 // C++0x [temp.variadic]p5:
456 // All of the parameter packs expanded by a pack expansion shall have
457 // the same number of arguments specified.
458 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
459 << FirstPack.first << Name << NumExpansions << NewPackSize
460 << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
461 return true;
462 }
463 }
464
465 return false;
466}
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000467
468bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
469 const DeclSpec &DS = D.getDeclSpec();
470 switch (DS.getTypeSpecType()) {
471 case TST_typename:
472 case TST_typeofType: {
473 QualType T = DS.getRepAsType().get();
474 if (!T.isNull() && T->containsUnexpandedParameterPack())
475 return true;
476 break;
477 }
478
479 case TST_typeofExpr:
480 case TST_decltype:
481 if (DS.getRepAsExpr() &&
482 DS.getRepAsExpr()->containsUnexpandedParameterPack())
483 return true;
484 break;
485
486 case TST_unspecified:
487 case TST_void:
488 case TST_char:
489 case TST_wchar:
490 case TST_char16:
491 case TST_char32:
492 case TST_int:
493 case TST_float:
494 case TST_double:
495 case TST_bool:
496 case TST_decimal32:
497 case TST_decimal64:
498 case TST_decimal128:
499 case TST_enum:
500 case TST_union:
501 case TST_struct:
502 case TST_class:
503 case TST_auto:
504 case TST_error:
505 break;
506 }
507
508 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
509 const DeclaratorChunk &Chunk = D.getTypeObject(I);
510 switch (Chunk.Kind) {
511 case DeclaratorChunk::Pointer:
512 case DeclaratorChunk::Reference:
513 case DeclaratorChunk::Paren:
514 // These declarator chunks cannot contain any parameter packs.
515 break;
516
517 case DeclaratorChunk::Array:
518 case DeclaratorChunk::Function:
519 case DeclaratorChunk::BlockPointer:
520 // Syntactically, these kinds of declarator chunks all come after the
521 // declarator-id (conceptually), so the parser should not invoke this
522 // routine at this time.
523 llvm_unreachable("Could not have seen this kind of declarator chunk");
524 break;
525
526 case DeclaratorChunk::MemberPointer:
527 if (Chunk.Mem.Scope().getScopeRep() &&
528 Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
529 return true;
530 break;
531 }
532 }
533
534 return false;
535}