• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===------- 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"
13 #include "clang/Sema/Lookup.h"
14 #include "clang/Sema/ParsedTemplate.h"
15 #include "clang/Sema/SemaInternal.h"
16 #include "clang/Sema/Template.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/AST/RecursiveASTVisitor.h"
19 #include "clang/AST/TypeLoc.h"
20 
21 using namespace clang;
22 
23 //----------------------------------------------------------------------------
24 // Visitor that collects unexpanded parameter packs
25 //----------------------------------------------------------------------------
26 
27 namespace {
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     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
36 
37   public:
CollectUnexpandedParameterPacksVisitor(SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)38     explicit CollectUnexpandedParameterPacksVisitor(
39                   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
40       : Unexpanded(Unexpanded) { }
41 
shouldWalkTypesOfTypeLocs() const42     bool shouldWalkTypesOfTypeLocs() const { return false; }
43 
44     //------------------------------------------------------------------------
45     // Recording occurrences of (unexpanded) parameter packs.
46     //------------------------------------------------------------------------
47 
48     /// \brief Record occurrences of template type parameter packs.
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)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.
VisitTemplateTypeParmType(TemplateTypeParmType * T)60     bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
61       if (T->isParameterPack())
62         Unexpanded.push_back(std::make_pair(T, SourceLocation()));
63 
64       return true;
65     }
66 
67     /// \brief Record occurrences of function and non-type template
68     /// parameter packs in an expression.
VisitDeclRefExpr(DeclRefExpr * E)69     bool VisitDeclRefExpr(DeclRefExpr *E) {
70       if (E->getDecl()->isParameterPack())
71         Unexpanded.push_back(std::make_pair(E->getDecl(), E->getLocation()));
72 
73       return true;
74     }
75 
76     /// \brief Record occurrences of template template parameter packs.
TraverseTemplateName(TemplateName Template)77     bool TraverseTemplateName(TemplateName Template) {
78       if (TemplateTemplateParmDecl *TTP
79             = dyn_cast_or_null<TemplateTemplateParmDecl>(
80                                                   Template.getAsTemplateDecl()))
81         if (TTP->isParameterPack())
82           Unexpanded.push_back(std::make_pair(TTP, SourceLocation()));
83 
84       return inherited::TraverseTemplateName(Template);
85     }
86 
87     /// \brief Suppress traversal into Objective-C container literal
88     /// elements that are pack expansions.
TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral * E)89     bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
90       if (!E->containsUnexpandedParameterPack())
91         return true;
92 
93       for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
94         ObjCDictionaryElement Element = E->getKeyValueElement(I);
95         if (Element.isPackExpansion())
96           continue;
97 
98         TraverseStmt(Element.Key);
99         TraverseStmt(Element.Value);
100       }
101       return true;
102     }
103     //------------------------------------------------------------------------
104     // Pruning the search for unexpanded parameter packs.
105     //------------------------------------------------------------------------
106 
107     /// \brief Suppress traversal into statements and expressions that
108     /// do not contain unexpanded parameter packs.
TraverseStmt(Stmt * S)109     bool TraverseStmt(Stmt *S) {
110       if (Expr *E = dyn_cast_or_null<Expr>(S))
111         if (E->containsUnexpandedParameterPack())
112           return inherited::TraverseStmt(E);
113 
114       return true;
115     }
116 
117     /// \brief Suppress traversal into types that do not contain
118     /// unexpanded parameter packs.
TraverseType(QualType T)119     bool TraverseType(QualType T) {
120       if (!T.isNull() && T->containsUnexpandedParameterPack())
121         return inherited::TraverseType(T);
122 
123       return true;
124     }
125 
126     /// \brief Suppress traversel into types with location information
127     /// that do not contain unexpanded parameter packs.
TraverseTypeLoc(TypeLoc TL)128     bool TraverseTypeLoc(TypeLoc TL) {
129       if (!TL.getType().isNull() &&
130           TL.getType()->containsUnexpandedParameterPack())
131         return inherited::TraverseTypeLoc(TL);
132 
133       return true;
134     }
135 
136     /// \brief Suppress traversal of non-parameter declarations, since
137     /// they cannot contain unexpanded parameter packs.
TraverseDecl(Decl * D)138     bool TraverseDecl(Decl *D) {
139       if (D && isa<ParmVarDecl>(D))
140         return inherited::TraverseDecl(D);
141 
142       return true;
143     }
144 
145     /// \brief Suppress traversal of template argument pack expansions.
TraverseTemplateArgument(const TemplateArgument & Arg)146     bool TraverseTemplateArgument(const TemplateArgument &Arg) {
147       if (Arg.isPackExpansion())
148         return true;
149 
150       return inherited::TraverseTemplateArgument(Arg);
151     }
152 
153     /// \brief Suppress traversal of template argument pack expansions.
TraverseTemplateArgumentLoc(const TemplateArgumentLoc & ArgLoc)154     bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
155       if (ArgLoc.getArgument().isPackExpansion())
156         return true;
157 
158       return inherited::TraverseTemplateArgumentLoc(ArgLoc);
159     }
160   };
161 }
162 
163 /// \brief Diagnose all of the unexpanded parameter packs in the given
164 /// vector.
165 void
DiagnoseUnexpandedParameterPacks(SourceLocation Loc,UnexpandedParameterPackContext UPPC,ArrayRef<UnexpandedParameterPack> Unexpanded)166 Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
167                                        UnexpandedParameterPackContext UPPC,
168                                  ArrayRef<UnexpandedParameterPack> Unexpanded) {
169   if (Unexpanded.empty())
170     return;
171 
172   SmallVector<SourceLocation, 4> Locations;
173   SmallVector<IdentifierInfo *, 4> Names;
174   llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
175 
176   for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
177     IdentifierInfo *Name = 0;
178     if (const TemplateTypeParmType *TTP
179           = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
180       Name = TTP->getIdentifier();
181     else
182       Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
183 
184     if (Name && NamesKnown.insert(Name))
185       Names.push_back(Name);
186 
187     if (Unexpanded[I].second.isValid())
188       Locations.push_back(Unexpanded[I].second);
189   }
190 
191   DiagnosticBuilder DB
192     = Names.size() == 0? Diag(Loc, diag::err_unexpanded_parameter_pack_0)
193                            << (int)UPPC
194     : Names.size() == 1? Diag(Loc, diag::err_unexpanded_parameter_pack_1)
195                            << (int)UPPC << Names[0]
196     : Names.size() == 2? Diag(Loc, diag::err_unexpanded_parameter_pack_2)
197                            << (int)UPPC << Names[0] << Names[1]
198     : Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
199         << (int)UPPC << Names[0] << Names[1];
200 
201   for (unsigned I = 0, N = Locations.size(); I != N; ++I)
202     DB << SourceRange(Locations[I]);
203 }
204 
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TypeSourceInfo * T,UnexpandedParameterPackContext UPPC)205 bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
206                                            TypeSourceInfo *T,
207                                          UnexpandedParameterPackContext UPPC) {
208   // C++0x [temp.variadic]p5:
209   //   An appearance of a name of a parameter pack that is not expanded is
210   //   ill-formed.
211   if (!T->getType()->containsUnexpandedParameterPack())
212     return false;
213 
214   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
215   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
216                                                               T->getTypeLoc());
217   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
218   DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
219   return true;
220 }
221 
DiagnoseUnexpandedParameterPack(Expr * E,UnexpandedParameterPackContext UPPC)222 bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
223                                         UnexpandedParameterPackContext UPPC) {
224   // C++0x [temp.variadic]p5:
225   //   An appearance of a name of a parameter pack that is not expanded is
226   //   ill-formed.
227   if (!E->containsUnexpandedParameterPack())
228     return false;
229 
230   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
231   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
232   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
233   DiagnoseUnexpandedParameterPacks(E->getLocStart(), UPPC, Unexpanded);
234   return true;
235 }
236 
DiagnoseUnexpandedParameterPack(const CXXScopeSpec & SS,UnexpandedParameterPackContext UPPC)237 bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
238                                         UnexpandedParameterPackContext UPPC) {
239   // C++0x [temp.variadic]p5:
240   //   An appearance of a name of a parameter pack that is not expanded is
241   //   ill-formed.
242   if (!SS.getScopeRep() ||
243       !SS.getScopeRep()->containsUnexpandedParameterPack())
244     return false;
245 
246   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
247   CollectUnexpandedParameterPacksVisitor(Unexpanded)
248     .TraverseNestedNameSpecifier(SS.getScopeRep());
249   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
250   DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
251                                    UPPC, Unexpanded);
252   return true;
253 }
254 
DiagnoseUnexpandedParameterPack(const DeclarationNameInfo & NameInfo,UnexpandedParameterPackContext UPPC)255 bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
256                                          UnexpandedParameterPackContext UPPC) {
257   // C++0x [temp.variadic]p5:
258   //   An appearance of a name of a parameter pack that is not expanded is
259   //   ill-formed.
260   switch (NameInfo.getName().getNameKind()) {
261   case DeclarationName::Identifier:
262   case DeclarationName::ObjCZeroArgSelector:
263   case DeclarationName::ObjCOneArgSelector:
264   case DeclarationName::ObjCMultiArgSelector:
265   case DeclarationName::CXXOperatorName:
266   case DeclarationName::CXXLiteralOperatorName:
267   case DeclarationName::CXXUsingDirective:
268     return false;
269 
270   case DeclarationName::CXXConstructorName:
271   case DeclarationName::CXXDestructorName:
272   case DeclarationName::CXXConversionFunctionName:
273     // FIXME: We shouldn't need this null check!
274     if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
275       return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
276 
277     if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
278       return false;
279 
280     break;
281   }
282 
283   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
284   CollectUnexpandedParameterPacksVisitor(Unexpanded)
285     .TraverseType(NameInfo.getName().getCXXNameType());
286   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
287   DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
288   return true;
289 }
290 
DiagnoseUnexpandedParameterPack(SourceLocation Loc,TemplateName Template,UnexpandedParameterPackContext UPPC)291 bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
292                                            TemplateName Template,
293                                        UnexpandedParameterPackContext UPPC) {
294 
295   if (Template.isNull() || !Template.containsUnexpandedParameterPack())
296     return false;
297 
298   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
299   CollectUnexpandedParameterPacksVisitor(Unexpanded)
300     .TraverseTemplateName(Template);
301   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
302   DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
303   return true;
304 }
305 
DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,UnexpandedParameterPackContext UPPC)306 bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
307                                          UnexpandedParameterPackContext UPPC) {
308   if (Arg.getArgument().isNull() ||
309       !Arg.getArgument().containsUnexpandedParameterPack())
310     return false;
311 
312   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
313   CollectUnexpandedParameterPacksVisitor(Unexpanded)
314     .TraverseTemplateArgumentLoc(Arg);
315   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
316   DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
317   return true;
318 }
319 
collectUnexpandedParameterPacks(TemplateArgument Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)320 void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
321                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
322   CollectUnexpandedParameterPacksVisitor(Unexpanded)
323     .TraverseTemplateArgument(Arg);
324 }
325 
collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)326 void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
327                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
328   CollectUnexpandedParameterPacksVisitor(Unexpanded)
329     .TraverseTemplateArgumentLoc(Arg);
330 }
331 
collectUnexpandedParameterPacks(QualType T,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)332 void Sema::collectUnexpandedParameterPacks(QualType T,
333                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
334   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
335 }
336 
collectUnexpandedParameterPacks(TypeLoc TL,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)337 void Sema::collectUnexpandedParameterPacks(TypeLoc TL,
338                    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
339   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
340 }
341 
collectUnexpandedParameterPacks(CXXScopeSpec & SS,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)342 void Sema::collectUnexpandedParameterPacks(CXXScopeSpec &SS,
343                                            SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
344   NestedNameSpecifier *Qualifier = SS.getScopeRep();
345   if (!Qualifier)
346     return;
347 
348   NestedNameSpecifierLoc QualifierLoc(Qualifier, SS.location_data());
349   CollectUnexpandedParameterPacksVisitor(Unexpanded)
350     .TraverseNestedNameSpecifierLoc(QualifierLoc);
351 }
352 
collectUnexpandedParameterPacks(const DeclarationNameInfo & NameInfo,SmallVectorImpl<UnexpandedParameterPack> & Unexpanded)353 void Sema::collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
354                          SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
355   CollectUnexpandedParameterPacksVisitor(Unexpanded)
356     .TraverseDeclarationNameInfo(NameInfo);
357 }
358 
359 
360 ParsedTemplateArgument
ActOnPackExpansion(const ParsedTemplateArgument & Arg,SourceLocation EllipsisLoc)361 Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
362                          SourceLocation EllipsisLoc) {
363   if (Arg.isInvalid())
364     return Arg;
365 
366   switch (Arg.getKind()) {
367   case ParsedTemplateArgument::Type: {
368     TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
369     if (Result.isInvalid())
370       return ParsedTemplateArgument();
371 
372     return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
373                                   Arg.getLocation());
374   }
375 
376   case ParsedTemplateArgument::NonType: {
377     ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
378     if (Result.isInvalid())
379       return ParsedTemplateArgument();
380 
381     return ParsedTemplateArgument(Arg.getKind(), Result.get(),
382                                   Arg.getLocation());
383   }
384 
385   case ParsedTemplateArgument::Template:
386     if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
387       SourceRange R(Arg.getLocation());
388       if (Arg.getScopeSpec().isValid())
389         R.setBegin(Arg.getScopeSpec().getBeginLoc());
390       Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
391         << R;
392       return ParsedTemplateArgument();
393     }
394 
395     return Arg.getTemplatePackExpansion(EllipsisLoc);
396   }
397   llvm_unreachable("Unhandled template argument kind?");
398 }
399 
ActOnPackExpansion(ParsedType Type,SourceLocation EllipsisLoc)400 TypeResult Sema::ActOnPackExpansion(ParsedType Type,
401                                     SourceLocation EllipsisLoc) {
402   TypeSourceInfo *TSInfo;
403   GetTypeFromParser(Type, &TSInfo);
404   if (!TSInfo)
405     return true;
406 
407   TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc,
408                                                 llvm::Optional<unsigned>());
409   if (!TSResult)
410     return true;
411 
412   return CreateParsedType(TSResult->getType(), TSResult);
413 }
414 
CheckPackExpansion(TypeSourceInfo * Pattern,SourceLocation EllipsisLoc,llvm::Optional<unsigned> NumExpansions)415 TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
416                                          SourceLocation EllipsisLoc,
417                                        llvm::Optional<unsigned> NumExpansions) {
418   // Create the pack expansion type and source-location information.
419   QualType Result = CheckPackExpansion(Pattern->getType(),
420                                        Pattern->getTypeLoc().getSourceRange(),
421                                        EllipsisLoc, NumExpansions);
422   if (Result.isNull())
423     return 0;
424 
425   TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
426   PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc());
427   TL.setEllipsisLoc(EllipsisLoc);
428 
429   // Copy over the source-location information from the type.
430   memcpy(TL.getNextTypeLoc().getOpaqueData(),
431          Pattern->getTypeLoc().getOpaqueData(),
432          Pattern->getTypeLoc().getFullDataSize());
433   return TSResult;
434 }
435 
CheckPackExpansion(QualType Pattern,SourceRange PatternRange,SourceLocation EllipsisLoc,llvm::Optional<unsigned> NumExpansions)436 QualType Sema::CheckPackExpansion(QualType Pattern,
437                                   SourceRange PatternRange,
438                                   SourceLocation EllipsisLoc,
439                                   llvm::Optional<unsigned> NumExpansions) {
440   // C++0x [temp.variadic]p5:
441   //   The pattern of a pack expansion shall name one or more
442   //   parameter packs that are not expanded by a nested pack
443   //   expansion.
444   if (!Pattern->containsUnexpandedParameterPack()) {
445     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
446       << PatternRange;
447     return QualType();
448   }
449 
450   return Context.getPackExpansionType(Pattern, NumExpansions);
451 }
452 
ActOnPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc)453 ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
454   return CheckPackExpansion(Pattern, EllipsisLoc, llvm::Optional<unsigned>());
455 }
456 
CheckPackExpansion(Expr * Pattern,SourceLocation EllipsisLoc,llvm::Optional<unsigned> NumExpansions)457 ExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
458                                     llvm::Optional<unsigned> NumExpansions) {
459   if (!Pattern)
460     return ExprError();
461 
462   // C++0x [temp.variadic]p5:
463   //   The pattern of a pack expansion shall name one or more
464   //   parameter packs that are not expanded by a nested pack
465   //   expansion.
466   if (!Pattern->containsUnexpandedParameterPack()) {
467     Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
468     << Pattern->getSourceRange();
469     return ExprError();
470   }
471 
472   // Create the pack expansion expression and source-location information.
473   return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
474                                                EllipsisLoc, NumExpansions));
475 }
476 
477 /// \brief Retrieve the depth and index of a parameter pack.
478 static std::pair<unsigned, unsigned>
getDepthAndIndex(NamedDecl * ND)479 getDepthAndIndex(NamedDecl *ND) {
480   if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
481     return std::make_pair(TTP->getDepth(), TTP->getIndex());
482 
483   if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
484     return std::make_pair(NTTP->getDepth(), NTTP->getIndex());
485 
486   TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
487   return std::make_pair(TTP->getDepth(), TTP->getIndex());
488 }
489 
CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,SourceRange PatternRange,ArrayRef<UnexpandedParameterPack> Unexpanded,const MultiLevelTemplateArgumentList & TemplateArgs,bool & ShouldExpand,bool & RetainExpansion,llvm::Optional<unsigned> & NumExpansions)490 bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
491                                            SourceRange PatternRange,
492                                    ArrayRef<UnexpandedParameterPack> Unexpanded,
493                              const MultiLevelTemplateArgumentList &TemplateArgs,
494                                            bool &ShouldExpand,
495                                            bool &RetainExpansion,
496                                      llvm::Optional<unsigned> &NumExpansions) {
497   ShouldExpand = true;
498   RetainExpansion = false;
499   std::pair<IdentifierInfo *, SourceLocation> FirstPack;
500   bool HaveFirstPack = false;
501 
502   for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(),
503                                                  end = Unexpanded.end();
504                                                   i != end; ++i) {
505     // Compute the depth and index for this parameter pack.
506     unsigned Depth = 0, Index = 0;
507     IdentifierInfo *Name;
508     bool IsFunctionParameterPack = false;
509 
510     if (const TemplateTypeParmType *TTP
511         = i->first.dyn_cast<const TemplateTypeParmType *>()) {
512       Depth = TTP->getDepth();
513       Index = TTP->getIndex();
514       Name = TTP->getIdentifier();
515     } else {
516       NamedDecl *ND = i->first.get<NamedDecl *>();
517       if (isa<ParmVarDecl>(ND))
518         IsFunctionParameterPack = true;
519       else
520         llvm::tie(Depth, Index) = getDepthAndIndex(ND);
521 
522       Name = ND->getIdentifier();
523     }
524 
525     // Determine the size of this argument pack.
526     unsigned NewPackSize;
527     if (IsFunctionParameterPack) {
528       // Figure out whether we're instantiating to an argument pack or not.
529       typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
530 
531       llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
532         = CurrentInstantiationScope->findInstantiationOf(
533                                         i->first.get<NamedDecl *>());
534       if (Instantiation->is<DeclArgumentPack *>()) {
535         // We could expand this function parameter pack.
536         NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
537       } else {
538         // We can't expand this function parameter pack, so we can't expand
539         // the pack expansion.
540         ShouldExpand = false;
541         continue;
542       }
543     } else {
544       // If we don't have a template argument at this depth/index, then we
545       // cannot expand the pack expansion. Make a note of this, but we still
546       // want to check any parameter packs we *do* have arguments for.
547       if (Depth >= TemplateArgs.getNumLevels() ||
548           !TemplateArgs.hasTemplateArgument(Depth, Index)) {
549         ShouldExpand = false;
550         continue;
551       }
552 
553       // Determine the size of the argument pack.
554       NewPackSize = TemplateArgs(Depth, Index).pack_size();
555     }
556 
557     // C++0x [temp.arg.explicit]p9:
558     //   Template argument deduction can extend the sequence of template
559     //   arguments corresponding to a template parameter pack, even when the
560     //   sequence contains explicitly specified template arguments.
561     if (!IsFunctionParameterPack) {
562       if (NamedDecl *PartialPack
563                     = CurrentInstantiationScope->getPartiallySubstitutedPack()){
564         unsigned PartialDepth, PartialIndex;
565         llvm::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
566         if (PartialDepth == Depth && PartialIndex == Index)
567           RetainExpansion = true;
568       }
569     }
570 
571     if (!NumExpansions) {
572       // The is the first pack we've seen for which we have an argument.
573       // Record it.
574       NumExpansions = NewPackSize;
575       FirstPack.first = Name;
576       FirstPack.second = i->second;
577       HaveFirstPack = true;
578       continue;
579     }
580 
581     if (NewPackSize != *NumExpansions) {
582       // C++0x [temp.variadic]p5:
583       //   All of the parameter packs expanded by a pack expansion shall have
584       //   the same number of arguments specified.
585       if (HaveFirstPack)
586         Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
587           << FirstPack.first << Name << *NumExpansions << NewPackSize
588           << SourceRange(FirstPack.second) << SourceRange(i->second);
589       else
590         Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
591           << Name << *NumExpansions << NewPackSize
592           << SourceRange(i->second);
593       return true;
594     }
595   }
596 
597   return false;
598 }
599 
getNumArgumentsInExpansion(QualType T,const MultiLevelTemplateArgumentList & TemplateArgs)600 unsigned Sema::getNumArgumentsInExpansion(QualType T,
601                           const MultiLevelTemplateArgumentList &TemplateArgs) {
602   QualType Pattern = cast<PackExpansionType>(T)->getPattern();
603   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
604   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
605 
606   for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
607     // Compute the depth and index for this parameter pack.
608     unsigned Depth;
609     unsigned Index;
610 
611     if (const TemplateTypeParmType *TTP
612           = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
613       Depth = TTP->getDepth();
614       Index = TTP->getIndex();
615     } else {
616       NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
617       if (isa<ParmVarDecl>(ND)) {
618         // Function parameter pack.
619         typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
620 
621         llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
622           = CurrentInstantiationScope->findInstantiationOf(
623                                         Unexpanded[I].first.get<NamedDecl *>());
624         if (Instantiation->is<DeclArgumentPack *>())
625           return Instantiation->get<DeclArgumentPack *>()->size();
626 
627         continue;
628       }
629 
630       llvm::tie(Depth, Index) = getDepthAndIndex(ND);
631     }
632     if (Depth >= TemplateArgs.getNumLevels() ||
633         !TemplateArgs.hasTemplateArgument(Depth, Index))
634       continue;
635 
636     // Determine the size of the argument pack.
637     return TemplateArgs(Depth, Index).pack_size();
638   }
639 
640   llvm_unreachable("No unexpanded parameter packs in type expansion.");
641 }
642 
containsUnexpandedParameterPacks(Declarator & D)643 bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
644   const DeclSpec &DS = D.getDeclSpec();
645   switch (DS.getTypeSpecType()) {
646   case TST_typename:
647   case TST_typeofType:
648   case TST_underlyingType:
649   case TST_atomic: {
650     QualType T = DS.getRepAsType().get();
651     if (!T.isNull() && T->containsUnexpandedParameterPack())
652       return true;
653     break;
654   }
655 
656   case TST_typeofExpr:
657   case TST_decltype:
658     if (DS.getRepAsExpr() &&
659         DS.getRepAsExpr()->containsUnexpandedParameterPack())
660       return true;
661     break;
662 
663   case TST_unspecified:
664   case TST_void:
665   case TST_char:
666   case TST_wchar:
667   case TST_char16:
668   case TST_char32:
669   case TST_int:
670   case TST_int128:
671   case TST_half:
672   case TST_float:
673   case TST_double:
674   case TST_bool:
675   case TST_decimal32:
676   case TST_decimal64:
677   case TST_decimal128:
678   case TST_enum:
679   case TST_union:
680   case TST_struct:
681   case TST_class:
682   case TST_auto:
683   case TST_unknown_anytype:
684   case TST_error:
685     break;
686   }
687 
688   for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
689     const DeclaratorChunk &Chunk = D.getTypeObject(I);
690     switch (Chunk.Kind) {
691     case DeclaratorChunk::Pointer:
692     case DeclaratorChunk::Reference:
693     case DeclaratorChunk::Paren:
694       // These declarator chunks cannot contain any parameter packs.
695       break;
696 
697     case DeclaratorChunk::Array:
698     case DeclaratorChunk::Function:
699     case DeclaratorChunk::BlockPointer:
700       // Syntactically, these kinds of declarator chunks all come after the
701       // declarator-id (conceptually), so the parser should not invoke this
702       // routine at this time.
703       llvm_unreachable("Could not have seen this kind of declarator chunk");
704 
705     case DeclaratorChunk::MemberPointer:
706       if (Chunk.Mem.Scope().getScopeRep() &&
707           Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
708         return true;
709       break;
710     }
711   }
712 
713   return false;
714 }
715 
716 namespace {
717 
718 // Callback to only accept typo corrections that refer to parameter packs.
719 class ParameterPackValidatorCCC : public CorrectionCandidateCallback {
720  public:
ValidateCandidate(const TypoCorrection & candidate)721   virtual bool ValidateCandidate(const TypoCorrection &candidate) {
722     NamedDecl *ND = candidate.getCorrectionDecl();
723     return ND && ND->isParameterPack();
724   }
725 };
726 
727 }
728 
729 /// \brief Called when an expression computing the size of a parameter pack
730 /// is parsed.
731 ///
732 /// \code
733 /// template<typename ...Types> struct count {
734 ///   static const unsigned value = sizeof...(Types);
735 /// };
736 /// \endcode
737 ///
738 //
739 /// \param OpLoc The location of the "sizeof" keyword.
740 /// \param Name The name of the parameter pack whose size will be determined.
741 /// \param NameLoc The source location of the name of the parameter pack.
742 /// \param RParenLoc The location of the closing parentheses.
ActOnSizeofParameterPackExpr(Scope * S,SourceLocation OpLoc,IdentifierInfo & Name,SourceLocation NameLoc,SourceLocation RParenLoc)743 ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
744                                               SourceLocation OpLoc,
745                                               IdentifierInfo &Name,
746                                               SourceLocation NameLoc,
747                                               SourceLocation RParenLoc) {
748   // C++0x [expr.sizeof]p5:
749   //   The identifier in a sizeof... expression shall name a parameter pack.
750   LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
751   LookupName(R, S);
752 
753   NamedDecl *ParameterPack = 0;
754   ParameterPackValidatorCCC Validator;
755   switch (R.getResultKind()) {
756   case LookupResult::Found:
757     ParameterPack = R.getFoundDecl();
758     break;
759 
760   case LookupResult::NotFound:
761   case LookupResult::NotFoundInCurrentInstantiation:
762     if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
763                                                R.getLookupKind(), S, 0,
764                                                Validator)) {
765       std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts()));
766       ParameterPack = Corrected.getCorrectionDecl();
767       Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
768         << &Name << CorrectedQuotedStr
769         << FixItHint::CreateReplacement(
770             NameLoc, Corrected.getAsString(getLangOpts()));
771       Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
772         << CorrectedQuotedStr;
773     }
774 
775   case LookupResult::FoundOverloaded:
776   case LookupResult::FoundUnresolvedValue:
777     break;
778 
779   case LookupResult::Ambiguous:
780     DiagnoseAmbiguousLookup(R);
781     return ExprError();
782   }
783 
784   if (!ParameterPack || !ParameterPack->isParameterPack()) {
785     Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
786       << &Name;
787     return ExprError();
788   }
789 
790   MarkAnyDeclReferenced(OpLoc, ParameterPack);
791 
792   return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc,
793                                       ParameterPack, NameLoc, RParenLoc);
794 }
795