SemaTemplateVariadic.cpp revision 249423
1218887Sdim//===------- SemaTemplateVariadic.cpp - C++ Variadic Templates ------------===/
2218887Sdim//
3218887Sdim//                     The LLVM Compiler Infrastructure
4218887Sdim//
5218887Sdim// This file is distributed under the University of Illinois Open Source
6218887Sdim// License. See LICENSE.TXT for details.
7218887Sdim//===----------------------------------------------------------------------===/
8218887Sdim//
9218887Sdim//  This file implements semantic analysis for C++0x variadic templates.
10218887Sdim//===----------------------------------------------------------------------===/
11218887Sdim
12218887Sdim#include "clang/Sema/Sema.h"
13249423Sdim#include "clang/AST/Expr.h"
14249423Sdim#include "clang/AST/RecursiveASTVisitor.h"
15249423Sdim#include "clang/AST/TypeLoc.h"
16218887Sdim#include "clang/Sema/Lookup.h"
17218887Sdim#include "clang/Sema/ParsedTemplate.h"
18239462Sdim#include "clang/Sema/ScopeInfo.h"
19218887Sdim#include "clang/Sema/SemaInternal.h"
20218887Sdim#include "clang/Sema/Template.h"
21218887Sdim
22218887Sdimusing namespace clang;
23218887Sdim
24218887Sdim//----------------------------------------------------------------------------
25218887Sdim// Visitor that collects unexpanded parameter packs
26218887Sdim//----------------------------------------------------------------------------
27218887Sdim
28218887Sdimnamespace {
29218887Sdim  /// \brief A class that collects unexpanded parameter packs.
30218887Sdim  class CollectUnexpandedParameterPacksVisitor :
31218887Sdim    public RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
32218887Sdim  {
33218887Sdim    typedef RecursiveASTVisitor<CollectUnexpandedParameterPacksVisitor>
34218887Sdim      inherited;
35218887Sdim
36226633Sdim    SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
37218887Sdim
38239462Sdim    bool InLambda;
39239462Sdim
40218887Sdim  public:
41218887Sdim    explicit CollectUnexpandedParameterPacksVisitor(
42226633Sdim                  SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
43239462Sdim      : Unexpanded(Unexpanded), InLambda(false) { }
44218887Sdim
45218887Sdim    bool shouldWalkTypesOfTypeLocs() const { return false; }
46218887Sdim
47218887Sdim    //------------------------------------------------------------------------
48218887Sdim    // Recording occurrences of (unexpanded) parameter packs.
49218887Sdim    //------------------------------------------------------------------------
50218887Sdim
51218887Sdim    /// \brief Record occurrences of template type parameter packs.
52218887Sdim    bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
53218887Sdim      if (TL.getTypePtr()->isParameterPack())
54218887Sdim        Unexpanded.push_back(std::make_pair(TL.getTypePtr(), TL.getNameLoc()));
55218887Sdim      return true;
56218887Sdim    }
57218887Sdim
58218887Sdim    /// \brief Record occurrences of template type parameter packs
59218887Sdim    /// when we don't have proper source-location information for
60218887Sdim    /// them.
61218887Sdim    ///
62218887Sdim    /// Ideally, this routine would never be used.
63218887Sdim    bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
64218887Sdim      if (T->isParameterPack())
65218887Sdim        Unexpanded.push_back(std::make_pair(T, SourceLocation()));
66218887Sdim
67218887Sdim      return true;
68218887Sdim    }
69218887Sdim
70218887Sdim    /// \brief Record occurrences of function and non-type template
71218887Sdim    /// parameter packs in an expression.
72218887Sdim    bool VisitDeclRefExpr(DeclRefExpr *E) {
73218887Sdim      if (E->getDecl()->isParameterPack())
74218887Sdim        Unexpanded.push_back(std::make_pair(E->getDecl(), E->getLocation()));
75218887Sdim
76218887Sdim      return true;
77218887Sdim    }
78218887Sdim
79218887Sdim    /// \brief Record occurrences of template template parameter packs.
80218887Sdim    bool TraverseTemplateName(TemplateName Template) {
81218887Sdim      if (TemplateTemplateParmDecl *TTP
82218887Sdim            = dyn_cast_or_null<TemplateTemplateParmDecl>(
83218887Sdim                                                  Template.getAsTemplateDecl()))
84218887Sdim        if (TTP->isParameterPack())
85218887Sdim          Unexpanded.push_back(std::make_pair(TTP, SourceLocation()));
86218887Sdim
87218887Sdim      return inherited::TraverseTemplateName(Template);
88218887Sdim    }
89218887Sdim
90234353Sdim    /// \brief Suppress traversal into Objective-C container literal
91234353Sdim    /// elements that are pack expansions.
92234353Sdim    bool TraverseObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
93234353Sdim      if (!E->containsUnexpandedParameterPack())
94234353Sdim        return true;
95234353Sdim
96234353Sdim      for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
97234353Sdim        ObjCDictionaryElement Element = E->getKeyValueElement(I);
98234353Sdim        if (Element.isPackExpansion())
99234353Sdim          continue;
100234353Sdim
101234353Sdim        TraverseStmt(Element.Key);
102234353Sdim        TraverseStmt(Element.Value);
103234353Sdim      }
104234353Sdim      return true;
105234353Sdim    }
106218887Sdim    //------------------------------------------------------------------------
107218887Sdim    // Pruning the search for unexpanded parameter packs.
108218887Sdim    //------------------------------------------------------------------------
109218887Sdim
110218887Sdim    /// \brief Suppress traversal into statements and expressions that
111218887Sdim    /// do not contain unexpanded parameter packs.
112218887Sdim    bool TraverseStmt(Stmt *S) {
113239462Sdim      Expr *E = dyn_cast_or_null<Expr>(S);
114239462Sdim      if ((E && E->containsUnexpandedParameterPack()) || InLambda)
115239462Sdim        return inherited::TraverseStmt(S);
116218887Sdim
117239462Sdim      return true;
118218887Sdim    }
119218887Sdim
120218887Sdim    /// \brief Suppress traversal into types that do not contain
121218887Sdim    /// unexpanded parameter packs.
122218887Sdim    bool TraverseType(QualType T) {
123239462Sdim      if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
124218887Sdim        return inherited::TraverseType(T);
125218887Sdim
126218887Sdim      return true;
127218887Sdim    }
128218887Sdim
129218887Sdim    /// \brief Suppress traversel into types with location information
130218887Sdim    /// that do not contain unexpanded parameter packs.
131218887Sdim    bool TraverseTypeLoc(TypeLoc TL) {
132239462Sdim      if ((!TL.getType().isNull() &&
133239462Sdim           TL.getType()->containsUnexpandedParameterPack()) ||
134239462Sdim          InLambda)
135218887Sdim        return inherited::TraverseTypeLoc(TL);
136218887Sdim
137218887Sdim      return true;
138218887Sdim    }
139218887Sdim
140218887Sdim    /// \brief Suppress traversal of non-parameter declarations, since
141218887Sdim    /// they cannot contain unexpanded parameter packs.
142218887Sdim    bool TraverseDecl(Decl *D) {
143239462Sdim      if ((D && isa<ParmVarDecl>(D)) || InLambda)
144218887Sdim        return inherited::TraverseDecl(D);
145218887Sdim
146239462Sdim      return true;
147218887Sdim    }
148218887Sdim
149218887Sdim    /// \brief Suppress traversal of template argument pack expansions.
150218887Sdim    bool TraverseTemplateArgument(const TemplateArgument &Arg) {
151218887Sdim      if (Arg.isPackExpansion())
152218887Sdim        return true;
153218887Sdim
154218887Sdim      return inherited::TraverseTemplateArgument(Arg);
155218887Sdim    }
156218887Sdim
157218887Sdim    /// \brief Suppress traversal of template argument pack expansions.
158218887Sdim    bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
159218887Sdim      if (ArgLoc.getArgument().isPackExpansion())
160218887Sdim        return true;
161218887Sdim
162218887Sdim      return inherited::TraverseTemplateArgumentLoc(ArgLoc);
163218887Sdim    }
164239462Sdim
165239462Sdim    /// \brief Note whether we're traversing a lambda containing an unexpanded
166239462Sdim    /// parameter pack. In this case, the unexpanded pack can occur anywhere,
167239462Sdim    /// including all the places where we normally wouldn't look. Within a
168239462Sdim    /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
169239462Sdim    /// outside an expression.
170239462Sdim    bool TraverseLambdaExpr(LambdaExpr *Lambda) {
171239462Sdim      // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
172239462Sdim      // even if it's contained within another lambda.
173239462Sdim      if (!Lambda->containsUnexpandedParameterPack())
174239462Sdim        return true;
175239462Sdim
176239462Sdim      bool WasInLambda = InLambda;
177239462Sdim      InLambda = true;
178239462Sdim
179239462Sdim      // If any capture names a function parameter pack, that pack is expanded
180239462Sdim      // when the lambda is expanded.
181239462Sdim      for (LambdaExpr::capture_iterator I = Lambda->capture_begin(),
182239462Sdim                                        E = Lambda->capture_end(); I != E; ++I)
183239462Sdim        if (VarDecl *VD = I->getCapturedVar())
184239462Sdim          if (VD->isParameterPack())
185239462Sdim            Unexpanded.push_back(std::make_pair(VD, I->getLocation()));
186239462Sdim
187239462Sdim      inherited::TraverseLambdaExpr(Lambda);
188239462Sdim
189239462Sdim      InLambda = WasInLambda;
190239462Sdim      return true;
191239462Sdim    }
192218887Sdim  };
193218887Sdim}
194218887Sdim
195218887Sdim/// \brief Diagnose all of the unexpanded parameter packs in the given
196218887Sdim/// vector.
197239462Sdimbool
198234353SdimSema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
199234353Sdim                                       UnexpandedParameterPackContext UPPC,
200234353Sdim                                 ArrayRef<UnexpandedParameterPack> Unexpanded) {
201234353Sdim  if (Unexpanded.empty())
202239462Sdim    return false;
203239462Sdim
204239462Sdim  // If we are within a lambda expression, that lambda contains an unexpanded
205239462Sdim  // parameter pack, and we are done.
206239462Sdim  // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
207239462Sdim  // later.
208239462Sdim  for (unsigned N = FunctionScopes.size(); N; --N) {
209239462Sdim    if (sema::LambdaScopeInfo *LSI =
210239462Sdim          dyn_cast<sema::LambdaScopeInfo>(FunctionScopes[N-1])) {
211239462Sdim      LSI->ContainsUnexpandedParameterPack = true;
212239462Sdim      return false;
213239462Sdim    }
214239462Sdim  }
215234353Sdim
216226633Sdim  SmallVector<SourceLocation, 4> Locations;
217226633Sdim  SmallVector<IdentifierInfo *, 4> Names;
218218887Sdim  llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
219218887Sdim
220218887Sdim  for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
221218887Sdim    IdentifierInfo *Name = 0;
222218887Sdim    if (const TemplateTypeParmType *TTP
223218887Sdim          = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
224221345Sdim      Name = TTP->getIdentifier();
225218887Sdim    else
226218887Sdim      Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
227218887Sdim
228218887Sdim    if (Name && NamesKnown.insert(Name))
229218887Sdim      Names.push_back(Name);
230218887Sdim
231218887Sdim    if (Unexpanded[I].second.isValid())
232218887Sdim      Locations.push_back(Unexpanded[I].second);
233218887Sdim  }
234218887Sdim
235218887Sdim  DiagnosticBuilder DB
236234353Sdim    = Names.size() == 0? Diag(Loc, diag::err_unexpanded_parameter_pack_0)
237218887Sdim                           << (int)UPPC
238234353Sdim    : Names.size() == 1? Diag(Loc, diag::err_unexpanded_parameter_pack_1)
239218887Sdim                           << (int)UPPC << Names[0]
240234353Sdim    : Names.size() == 2? Diag(Loc, diag::err_unexpanded_parameter_pack_2)
241218887Sdim                           << (int)UPPC << Names[0] << Names[1]
242234353Sdim    : Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
243218887Sdim        << (int)UPPC << Names[0] << Names[1];
244218887Sdim
245218887Sdim  for (unsigned I = 0, N = Locations.size(); I != N; ++I)
246218887Sdim    DB << SourceRange(Locations[I]);
247239462Sdim  return true;
248218887Sdim}
249218887Sdim
250218887Sdimbool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
251218887Sdim                                           TypeSourceInfo *T,
252218887Sdim                                         UnexpandedParameterPackContext UPPC) {
253218887Sdim  // C++0x [temp.variadic]p5:
254218887Sdim  //   An appearance of a name of a parameter pack that is not expanded is
255218887Sdim  //   ill-formed.
256218887Sdim  if (!T->getType()->containsUnexpandedParameterPack())
257218887Sdim    return false;
258218887Sdim
259226633Sdim  SmallVector<UnexpandedParameterPack, 2> Unexpanded;
260218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
261218887Sdim                                                              T->getTypeLoc());
262218887Sdim  assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
263239462Sdim  return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
264218887Sdim}
265218887Sdim
266218887Sdimbool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
267218887Sdim                                        UnexpandedParameterPackContext UPPC) {
268218887Sdim  // C++0x [temp.variadic]p5:
269218887Sdim  //   An appearance of a name of a parameter pack that is not expanded is
270218887Sdim  //   ill-formed.
271218887Sdim  if (!E->containsUnexpandedParameterPack())
272218887Sdim    return false;
273218887Sdim
274226633Sdim  SmallVector<UnexpandedParameterPack, 2> Unexpanded;
275218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
276218887Sdim  assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
277239462Sdim  return DiagnoseUnexpandedParameterPacks(E->getLocStart(), UPPC, Unexpanded);
278218887Sdim}
279218887Sdim
280218887Sdimbool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
281218887Sdim                                        UnexpandedParameterPackContext UPPC) {
282218887Sdim  // C++0x [temp.variadic]p5:
283218887Sdim  //   An appearance of a name of a parameter pack that is not expanded is
284218887Sdim  //   ill-formed.
285218887Sdim  if (!SS.getScopeRep() ||
286218887Sdim      !SS.getScopeRep()->containsUnexpandedParameterPack())
287218887Sdim    return false;
288218887Sdim
289226633Sdim  SmallVector<UnexpandedParameterPack, 2> Unexpanded;
290218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded)
291218887Sdim    .TraverseNestedNameSpecifier(SS.getScopeRep());
292218887Sdim  assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
293239462Sdim  return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
294239462Sdim                                          UPPC, Unexpanded);
295218887Sdim}
296218887Sdim
297218887Sdimbool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
298218887Sdim                                         UnexpandedParameterPackContext UPPC) {
299218887Sdim  // C++0x [temp.variadic]p5:
300218887Sdim  //   An appearance of a name of a parameter pack that is not expanded is
301218887Sdim  //   ill-formed.
302218887Sdim  switch (NameInfo.getName().getNameKind()) {
303218887Sdim  case DeclarationName::Identifier:
304218887Sdim  case DeclarationName::ObjCZeroArgSelector:
305218887Sdim  case DeclarationName::ObjCOneArgSelector:
306218887Sdim  case DeclarationName::ObjCMultiArgSelector:
307218887Sdim  case DeclarationName::CXXOperatorName:
308218887Sdim  case DeclarationName::CXXLiteralOperatorName:
309218887Sdim  case DeclarationName::CXXUsingDirective:
310218887Sdim    return false;
311218887Sdim
312218887Sdim  case DeclarationName::CXXConstructorName:
313218887Sdim  case DeclarationName::CXXDestructorName:
314218887Sdim  case DeclarationName::CXXConversionFunctionName:
315218887Sdim    // FIXME: We shouldn't need this null check!
316218887Sdim    if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
317218887Sdim      return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
318218887Sdim
319218887Sdim    if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
320218887Sdim      return false;
321218887Sdim
322218887Sdim    break;
323218887Sdim  }
324218887Sdim
325226633Sdim  SmallVector<UnexpandedParameterPack, 2> Unexpanded;
326218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded)
327218887Sdim    .TraverseType(NameInfo.getName().getCXXNameType());
328218887Sdim  assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
329239462Sdim  return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
330218887Sdim}
331218887Sdim
332218887Sdimbool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
333218887Sdim                                           TemplateName Template,
334218887Sdim                                       UnexpandedParameterPackContext UPPC) {
335218887Sdim
336218887Sdim  if (Template.isNull() || !Template.containsUnexpandedParameterPack())
337218887Sdim    return false;
338218887Sdim
339226633Sdim  SmallVector<UnexpandedParameterPack, 2> Unexpanded;
340218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded)
341218887Sdim    .TraverseTemplateName(Template);
342218887Sdim  assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
343239462Sdim  return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
344218887Sdim}
345218887Sdim
346218887Sdimbool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
347218887Sdim                                         UnexpandedParameterPackContext UPPC) {
348218887Sdim  if (Arg.getArgument().isNull() ||
349218887Sdim      !Arg.getArgument().containsUnexpandedParameterPack())
350218887Sdim    return false;
351218887Sdim
352226633Sdim  SmallVector<UnexpandedParameterPack, 2> Unexpanded;
353218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded)
354218887Sdim    .TraverseTemplateArgumentLoc(Arg);
355218887Sdim  assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
356239462Sdim  return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
357218887Sdim}
358218887Sdim
359218887Sdimvoid Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
360226633Sdim                   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
361218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded)
362218887Sdim    .TraverseTemplateArgument(Arg);
363218887Sdim}
364218887Sdim
365218887Sdimvoid Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
366226633Sdim                   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
367218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded)
368218887Sdim    .TraverseTemplateArgumentLoc(Arg);
369218887Sdim}
370218887Sdim
371218887Sdimvoid Sema::collectUnexpandedParameterPacks(QualType T,
372226633Sdim                   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
373218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
374218887Sdim}
375218887Sdim
376218887Sdimvoid Sema::collectUnexpandedParameterPacks(TypeLoc TL,
377226633Sdim                   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
378218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL);
379218887Sdim}
380218887Sdim
381234353Sdimvoid Sema::collectUnexpandedParameterPacks(CXXScopeSpec &SS,
382234353Sdim                                           SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
383234353Sdim  NestedNameSpecifier *Qualifier = SS.getScopeRep();
384234353Sdim  if (!Qualifier)
385234353Sdim    return;
386234353Sdim
387234353Sdim  NestedNameSpecifierLoc QualifierLoc(Qualifier, SS.location_data());
388234353Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded)
389234353Sdim    .TraverseNestedNameSpecifierLoc(QualifierLoc);
390234353Sdim}
391234353Sdim
392234353Sdimvoid Sema::collectUnexpandedParameterPacks(const DeclarationNameInfo &NameInfo,
393234353Sdim                         SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
394234353Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded)
395234353Sdim    .TraverseDeclarationNameInfo(NameInfo);
396234353Sdim}
397234353Sdim
398234353Sdim
399218887SdimParsedTemplateArgument
400218887SdimSema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
401218887Sdim                         SourceLocation EllipsisLoc) {
402218887Sdim  if (Arg.isInvalid())
403218887Sdim    return Arg;
404218887Sdim
405218887Sdim  switch (Arg.getKind()) {
406218887Sdim  case ParsedTemplateArgument::Type: {
407218887Sdim    TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
408218887Sdim    if (Result.isInvalid())
409218887Sdim      return ParsedTemplateArgument();
410218887Sdim
411218887Sdim    return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
412218887Sdim                                  Arg.getLocation());
413218887Sdim  }
414218887Sdim
415218887Sdim  case ParsedTemplateArgument::NonType: {
416218887Sdim    ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc);
417218887Sdim    if (Result.isInvalid())
418218887Sdim      return ParsedTemplateArgument();
419218887Sdim
420218887Sdim    return ParsedTemplateArgument(Arg.getKind(), Result.get(),
421218887Sdim                                  Arg.getLocation());
422218887Sdim  }
423218887Sdim
424218887Sdim  case ParsedTemplateArgument::Template:
425218887Sdim    if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
426218887Sdim      SourceRange R(Arg.getLocation());
427218887Sdim      if (Arg.getScopeSpec().isValid())
428218887Sdim        R.setBegin(Arg.getScopeSpec().getBeginLoc());
429218887Sdim      Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
430218887Sdim        << R;
431218887Sdim      return ParsedTemplateArgument();
432218887Sdim    }
433218887Sdim
434218887Sdim    return Arg.getTemplatePackExpansion(EllipsisLoc);
435218887Sdim  }
436218887Sdim  llvm_unreachable("Unhandled template argument kind?");
437218887Sdim}
438218887Sdim
439218887SdimTypeResult Sema::ActOnPackExpansion(ParsedType Type,
440218887Sdim                                    SourceLocation EllipsisLoc) {
441218887Sdim  TypeSourceInfo *TSInfo;
442218887Sdim  GetTypeFromParser(Type, &TSInfo);
443218887Sdim  if (!TSInfo)
444218887Sdim    return true;
445218887Sdim
446249423Sdim  TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, None);
447218887Sdim  if (!TSResult)
448218887Sdim    return true;
449218887Sdim
450218887Sdim  return CreateParsedType(TSResult->getType(), TSResult);
451218887Sdim}
452218887Sdim
453249423SdimTypeSourceInfo *
454249423SdimSema::CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc,
455249423Sdim                         Optional<unsigned> NumExpansions) {
456218887Sdim  // Create the pack expansion type and source-location information.
457218887Sdim  QualType Result = CheckPackExpansion(Pattern->getType(),
458218887Sdim                                       Pattern->getTypeLoc().getSourceRange(),
459218887Sdim                                       EllipsisLoc, NumExpansions);
460218887Sdim  if (Result.isNull())
461218887Sdim    return 0;
462218887Sdim
463218887Sdim  TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
464249423Sdim  PackExpansionTypeLoc TL =
465249423Sdim      TSResult->getTypeLoc().castAs<PackExpansionTypeLoc>();
466218887Sdim  TL.setEllipsisLoc(EllipsisLoc);
467218887Sdim
468218887Sdim  // Copy over the source-location information from the type.
469218887Sdim  memcpy(TL.getNextTypeLoc().getOpaqueData(),
470218887Sdim         Pattern->getTypeLoc().getOpaqueData(),
471218887Sdim         Pattern->getTypeLoc().getFullDataSize());
472218887Sdim  return TSResult;
473218887Sdim}
474218887Sdim
475249423SdimQualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange,
476218887Sdim                                  SourceLocation EllipsisLoc,
477249423Sdim                                  Optional<unsigned> NumExpansions) {
478218887Sdim  // C++0x [temp.variadic]p5:
479218887Sdim  //   The pattern of a pack expansion shall name one or more
480218887Sdim  //   parameter packs that are not expanded by a nested pack
481218887Sdim  //   expansion.
482218887Sdim  if (!Pattern->containsUnexpandedParameterPack()) {
483218887Sdim    Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
484218887Sdim      << PatternRange;
485218887Sdim    return QualType();
486218887Sdim  }
487218887Sdim
488218887Sdim  return Context.getPackExpansionType(Pattern, NumExpansions);
489218887Sdim}
490218887Sdim
491218887SdimExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) {
492249423Sdim  return CheckPackExpansion(Pattern, EllipsisLoc, None);
493218887Sdim}
494218887Sdim
495218887SdimExprResult Sema::CheckPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
496249423Sdim                                    Optional<unsigned> NumExpansions) {
497218887Sdim  if (!Pattern)
498218887Sdim    return ExprError();
499218887Sdim
500218887Sdim  // C++0x [temp.variadic]p5:
501218887Sdim  //   The pattern of a pack expansion shall name one or more
502218887Sdim  //   parameter packs that are not expanded by a nested pack
503218887Sdim  //   expansion.
504218887Sdim  if (!Pattern->containsUnexpandedParameterPack()) {
505218887Sdim    Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
506218887Sdim    << Pattern->getSourceRange();
507218887Sdim    return ExprError();
508218887Sdim  }
509218887Sdim
510218887Sdim  // Create the pack expansion expression and source-location information.
511218887Sdim  return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
512218887Sdim                                               EllipsisLoc, NumExpansions));
513218887Sdim}
514218887Sdim
515218887Sdim/// \brief Retrieve the depth and index of a parameter pack.
516218887Sdimstatic std::pair<unsigned, unsigned>
517218887SdimgetDepthAndIndex(NamedDecl *ND) {
518218887Sdim  if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND))
519218887Sdim    return std::make_pair(TTP->getDepth(), TTP->getIndex());
520218887Sdim
521218887Sdim  if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(ND))
522218887Sdim    return std::make_pair(NTTP->getDepth(), NTTP->getIndex());
523218887Sdim
524218887Sdim  TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
525218887Sdim  return std::make_pair(TTP->getDepth(), TTP->getIndex());
526218887Sdim}
527218887Sdim
528249423Sdimbool Sema::CheckParameterPacksForExpansion(
529249423Sdim    SourceLocation EllipsisLoc, SourceRange PatternRange,
530249423Sdim    ArrayRef<UnexpandedParameterPack> Unexpanded,
531249423Sdim    const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand,
532249423Sdim    bool &RetainExpansion, Optional<unsigned> &NumExpansions) {
533218887Sdim  ShouldExpand = true;
534218887Sdim  RetainExpansion = false;
535218887Sdim  std::pair<IdentifierInfo *, SourceLocation> FirstPack;
536218887Sdim  bool HaveFirstPack = false;
537218887Sdim
538226633Sdim  for (ArrayRef<UnexpandedParameterPack>::iterator i = Unexpanded.begin(),
539226633Sdim                                                 end = Unexpanded.end();
540226633Sdim                                                  i != end; ++i) {
541218887Sdim    // Compute the depth and index for this parameter pack.
542218887Sdim    unsigned Depth = 0, Index = 0;
543218887Sdim    IdentifierInfo *Name;
544218887Sdim    bool IsFunctionParameterPack = false;
545218887Sdim
546218887Sdim    if (const TemplateTypeParmType *TTP
547226633Sdim        = i->first.dyn_cast<const TemplateTypeParmType *>()) {
548218887Sdim      Depth = TTP->getDepth();
549218887Sdim      Index = TTP->getIndex();
550221345Sdim      Name = TTP->getIdentifier();
551218887Sdim    } else {
552226633Sdim      NamedDecl *ND = i->first.get<NamedDecl *>();
553218887Sdim      if (isa<ParmVarDecl>(ND))
554218887Sdim        IsFunctionParameterPack = true;
555218887Sdim      else
556218887Sdim        llvm::tie(Depth, Index) = getDepthAndIndex(ND);
557218887Sdim
558218887Sdim      Name = ND->getIdentifier();
559218887Sdim    }
560218887Sdim
561218887Sdim    // Determine the size of this argument pack.
562218887Sdim    unsigned NewPackSize;
563218887Sdim    if (IsFunctionParameterPack) {
564218887Sdim      // Figure out whether we're instantiating to an argument pack or not.
565218887Sdim      typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
566218887Sdim
567218887Sdim      llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
568218887Sdim        = CurrentInstantiationScope->findInstantiationOf(
569226633Sdim                                        i->first.get<NamedDecl *>());
570218887Sdim      if (Instantiation->is<DeclArgumentPack *>()) {
571218887Sdim        // We could expand this function parameter pack.
572218887Sdim        NewPackSize = Instantiation->get<DeclArgumentPack *>()->size();
573218887Sdim      } else {
574218887Sdim        // We can't expand this function parameter pack, so we can't expand
575218887Sdim        // the pack expansion.
576218887Sdim        ShouldExpand = false;
577218887Sdim        continue;
578218887Sdim      }
579218887Sdim    } else {
580218887Sdim      // If we don't have a template argument at this depth/index, then we
581218887Sdim      // cannot expand the pack expansion. Make a note of this, but we still
582218887Sdim      // want to check any parameter packs we *do* have arguments for.
583218887Sdim      if (Depth >= TemplateArgs.getNumLevels() ||
584218887Sdim          !TemplateArgs.hasTemplateArgument(Depth, Index)) {
585218887Sdim        ShouldExpand = false;
586218887Sdim        continue;
587218887Sdim      }
588218887Sdim
589218887Sdim      // Determine the size of the argument pack.
590218887Sdim      NewPackSize = TemplateArgs(Depth, Index).pack_size();
591218887Sdim    }
592218887Sdim
593218887Sdim    // C++0x [temp.arg.explicit]p9:
594218887Sdim    //   Template argument deduction can extend the sequence of template
595218887Sdim    //   arguments corresponding to a template parameter pack, even when the
596218887Sdim    //   sequence contains explicitly specified template arguments.
597218887Sdim    if (!IsFunctionParameterPack) {
598218887Sdim      if (NamedDecl *PartialPack
599218887Sdim                    = CurrentInstantiationScope->getPartiallySubstitutedPack()){
600218887Sdim        unsigned PartialDepth, PartialIndex;
601218887Sdim        llvm::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
602218887Sdim        if (PartialDepth == Depth && PartialIndex == Index)
603218887Sdim          RetainExpansion = true;
604218887Sdim      }
605218887Sdim    }
606218887Sdim
607218887Sdim    if (!NumExpansions) {
608218887Sdim      // The is the first pack we've seen for which we have an argument.
609218887Sdim      // Record it.
610218887Sdim      NumExpansions = NewPackSize;
611218887Sdim      FirstPack.first = Name;
612226633Sdim      FirstPack.second = i->second;
613218887Sdim      HaveFirstPack = true;
614218887Sdim      continue;
615218887Sdim    }
616218887Sdim
617218887Sdim    if (NewPackSize != *NumExpansions) {
618218887Sdim      // C++0x [temp.variadic]p5:
619218887Sdim      //   All of the parameter packs expanded by a pack expansion shall have
620218887Sdim      //   the same number of arguments specified.
621218887Sdim      if (HaveFirstPack)
622218887Sdim        Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
623218887Sdim          << FirstPack.first << Name << *NumExpansions << NewPackSize
624226633Sdim          << SourceRange(FirstPack.second) << SourceRange(i->second);
625218887Sdim      else
626218887Sdim        Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel)
627218887Sdim          << Name << *NumExpansions << NewPackSize
628226633Sdim          << SourceRange(i->second);
629218887Sdim      return true;
630218887Sdim    }
631218887Sdim  }
632218887Sdim
633218887Sdim  return false;
634218887Sdim}
635218887Sdim
636249423SdimOptional<unsigned> Sema::getNumArgumentsInExpansion(QualType T,
637218887Sdim                          const MultiLevelTemplateArgumentList &TemplateArgs) {
638218887Sdim  QualType Pattern = cast<PackExpansionType>(T)->getPattern();
639226633Sdim  SmallVector<UnexpandedParameterPack, 2> Unexpanded;
640218887Sdim  CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(Pattern);
641218887Sdim
642249423Sdim  Optional<unsigned> Result;
643218887Sdim  for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
644218887Sdim    // Compute the depth and index for this parameter pack.
645218887Sdim    unsigned Depth;
646218887Sdim    unsigned Index;
647218887Sdim
648218887Sdim    if (const TemplateTypeParmType *TTP
649218887Sdim          = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
650218887Sdim      Depth = TTP->getDepth();
651218887Sdim      Index = TTP->getIndex();
652218887Sdim    } else {
653218887Sdim      NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
654218887Sdim      if (isa<ParmVarDecl>(ND)) {
655218887Sdim        // Function parameter pack.
656218887Sdim        typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack;
657218887Sdim
658218887Sdim        llvm::PointerUnion<Decl *, DeclArgumentPack *> *Instantiation
659218887Sdim          = CurrentInstantiationScope->findInstantiationOf(
660218887Sdim                                        Unexpanded[I].first.get<NamedDecl *>());
661239462Sdim        if (Instantiation->is<Decl*>())
662239462Sdim          // The pattern refers to an unexpanded pack. We're not ready to expand
663239462Sdim          // this pack yet.
664249423Sdim          return None;
665239462Sdim
666239462Sdim        unsigned Size = Instantiation->get<DeclArgumentPack *>()->size();
667239462Sdim        assert((!Result || *Result == Size) && "inconsistent pack sizes");
668239462Sdim        Result = Size;
669218887Sdim        continue;
670218887Sdim      }
671218887Sdim
672218887Sdim      llvm::tie(Depth, Index) = getDepthAndIndex(ND);
673218887Sdim    }
674218887Sdim    if (Depth >= TemplateArgs.getNumLevels() ||
675218887Sdim        !TemplateArgs.hasTemplateArgument(Depth, Index))
676239462Sdim      // The pattern refers to an unknown template argument. We're not ready to
677239462Sdim      // expand this pack yet.
678249423Sdim      return None;
679218887Sdim
680218887Sdim    // Determine the size of the argument pack.
681239462Sdim    unsigned Size = TemplateArgs(Depth, Index).pack_size();
682239462Sdim    assert((!Result || *Result == Size) && "inconsistent pack sizes");
683239462Sdim    Result = Size;
684218887Sdim  }
685218887Sdim
686239462Sdim  return Result;
687218887Sdim}
688218887Sdim
689218887Sdimbool Sema::containsUnexpandedParameterPacks(Declarator &D) {
690218887Sdim  const DeclSpec &DS = D.getDeclSpec();
691218887Sdim  switch (DS.getTypeSpecType()) {
692218887Sdim  case TST_typename:
693223017Sdim  case TST_typeofType:
694226633Sdim  case TST_underlyingType:
695226633Sdim  case TST_atomic: {
696218887Sdim    QualType T = DS.getRepAsType().get();
697218887Sdim    if (!T.isNull() && T->containsUnexpandedParameterPack())
698218887Sdim      return true;
699218887Sdim    break;
700218887Sdim  }
701218887Sdim
702218887Sdim  case TST_typeofExpr:
703218887Sdim  case TST_decltype:
704218887Sdim    if (DS.getRepAsExpr() &&
705218887Sdim        DS.getRepAsExpr()->containsUnexpandedParameterPack())
706218887Sdim      return true;
707218887Sdim    break;
708218887Sdim
709218887Sdim  case TST_unspecified:
710218887Sdim  case TST_void:
711218887Sdim  case TST_char:
712218887Sdim  case TST_wchar:
713218887Sdim  case TST_char16:
714218887Sdim  case TST_char32:
715218887Sdim  case TST_int:
716234353Sdim  case TST_int128:
717226633Sdim  case TST_half:
718218887Sdim  case TST_float:
719218887Sdim  case TST_double:
720218887Sdim  case TST_bool:
721218887Sdim  case TST_decimal32:
722218887Sdim  case TST_decimal64:
723218887Sdim  case TST_decimal128:
724218887Sdim  case TST_enum:
725218887Sdim  case TST_union:
726218887Sdim  case TST_struct:
727243830Sdim  case TST_interface:
728218887Sdim  case TST_class:
729218887Sdim  case TST_auto:
730221345Sdim  case TST_unknown_anytype:
731249423Sdim  case TST_image1d_t:
732249423Sdim  case TST_image1d_array_t:
733249423Sdim  case TST_image1d_buffer_t:
734249423Sdim  case TST_image2d_t:
735249423Sdim  case TST_image2d_array_t:
736249423Sdim  case TST_image3d_t:
737249423Sdim  case TST_sampler_t:
738249423Sdim  case TST_event_t:
739218887Sdim  case TST_error:
740218887Sdim    break;
741218887Sdim  }
742218887Sdim
743218887Sdim  for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
744218887Sdim    const DeclaratorChunk &Chunk = D.getTypeObject(I);
745218887Sdim    switch (Chunk.Kind) {
746218887Sdim    case DeclaratorChunk::Pointer:
747218887Sdim    case DeclaratorChunk::Reference:
748218887Sdim    case DeclaratorChunk::Paren:
749218887Sdim      // These declarator chunks cannot contain any parameter packs.
750218887Sdim      break;
751218887Sdim
752218887Sdim    case DeclaratorChunk::Array:
753218887Sdim    case DeclaratorChunk::Function:
754218887Sdim    case DeclaratorChunk::BlockPointer:
755218887Sdim      // Syntactically, these kinds of declarator chunks all come after the
756218887Sdim      // declarator-id (conceptually), so the parser should not invoke this
757218887Sdim      // routine at this time.
758218887Sdim      llvm_unreachable("Could not have seen this kind of declarator chunk");
759218887Sdim
760218887Sdim    case DeclaratorChunk::MemberPointer:
761218887Sdim      if (Chunk.Mem.Scope().getScopeRep() &&
762218887Sdim          Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
763218887Sdim        return true;
764218887Sdim      break;
765218887Sdim    }
766218887Sdim  }
767218887Sdim
768218887Sdim  return false;
769218887Sdim}
770218887Sdim
771234353Sdimnamespace {
772234353Sdim
773234353Sdim// Callback to only accept typo corrections that refer to parameter packs.
774234353Sdimclass ParameterPackValidatorCCC : public CorrectionCandidateCallback {
775234353Sdim public:
776234353Sdim  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
777234353Sdim    NamedDecl *ND = candidate.getCorrectionDecl();
778234353Sdim    return ND && ND->isParameterPack();
779234353Sdim  }
780234353Sdim};
781234353Sdim
782234353Sdim}
783234353Sdim
784218887Sdim/// \brief Called when an expression computing the size of a parameter pack
785218887Sdim/// is parsed.
786218887Sdim///
787218887Sdim/// \code
788218887Sdim/// template<typename ...Types> struct count {
789218887Sdim///   static const unsigned value = sizeof...(Types);
790218887Sdim/// };
791218887Sdim/// \endcode
792218887Sdim///
793218887Sdim//
794218887Sdim/// \param OpLoc The location of the "sizeof" keyword.
795218887Sdim/// \param Name The name of the parameter pack whose size will be determined.
796218887Sdim/// \param NameLoc The source location of the name of the parameter pack.
797218887Sdim/// \param RParenLoc The location of the closing parentheses.
798218887SdimExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S,
799218887Sdim                                              SourceLocation OpLoc,
800218887Sdim                                              IdentifierInfo &Name,
801218887Sdim                                              SourceLocation NameLoc,
802218887Sdim                                              SourceLocation RParenLoc) {
803218887Sdim  // C++0x [expr.sizeof]p5:
804218887Sdim  //   The identifier in a sizeof... expression shall name a parameter pack.
805218887Sdim  LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
806218887Sdim  LookupName(R, S);
807218887Sdim
808218887Sdim  NamedDecl *ParameterPack = 0;
809234353Sdim  ParameterPackValidatorCCC Validator;
810218887Sdim  switch (R.getResultKind()) {
811218887Sdim  case LookupResult::Found:
812218887Sdim    ParameterPack = R.getFoundDecl();
813218887Sdim    break;
814218887Sdim
815218887Sdim  case LookupResult::NotFound:
816218887Sdim  case LookupResult::NotFoundInCurrentInstantiation:
817224145Sdim    if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
818234353Sdim                                               R.getLookupKind(), S, 0,
819234353Sdim                                               Validator)) {
820234353Sdim      std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts()));
821234353Sdim      ParameterPack = Corrected.getCorrectionDecl();
822234353Sdim      Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest)
823234353Sdim        << &Name << CorrectedQuotedStr
824234353Sdim        << FixItHint::CreateReplacement(
825234353Sdim            NameLoc, Corrected.getAsString(getLangOpts()));
826234353Sdim      Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here)
827234353Sdim        << CorrectedQuotedStr;
828218887Sdim    }
829218887Sdim
830218887Sdim  case LookupResult::FoundOverloaded:
831218887Sdim  case LookupResult::FoundUnresolvedValue:
832218887Sdim    break;
833218887Sdim
834218887Sdim  case LookupResult::Ambiguous:
835218887Sdim    DiagnoseAmbiguousLookup(R);
836218887Sdim    return ExprError();
837218887Sdim  }
838218887Sdim
839218887Sdim  if (!ParameterPack || !ParameterPack->isParameterPack()) {
840218887Sdim    Diag(NameLoc, diag::err_sizeof_pack_no_pack_name)
841218887Sdim      << &Name;
842218887Sdim    return ExprError();
843218887Sdim  }
844218887Sdim
845249423Sdim  MarkAnyDeclReferenced(OpLoc, ParameterPack, true);
846234353Sdim
847218887Sdim  return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc,
848218887Sdim                                      ParameterPack, NameLoc, RParenLoc);
849218887Sdim}
850