blob: d9c7e72a867b6e65afb85bebce42bf0a62eedf07 [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
66 // FIXME: Record occurrences of non-type and template template
67 // parameter packs.
68
69 // FIXME: Once we have pack expansions in the AST, block their
70 // traversal.
71
72 //------------------------------------------------------------------------
73 // Pruning the search for unexpanded parameter packs.
74 //------------------------------------------------------------------------
75
76 /// \brief Suppress traversal into statements and expressions that
77 /// do not contain unexpanded parameter packs.
78 bool TraverseStmt(Stmt *S) {
79 if (Expr *E = dyn_cast_or_null<Expr>(S))
80 if (E->containsUnexpandedParameterPack())
81 return inherited::TraverseStmt(E);
82
83 return true;
84 }
85
86 /// \brief Suppress traversal into types that do not contain
87 /// unexpanded parameter packs.
88 bool TraverseType(QualType T) {
89 if (!T.isNull() && T->containsUnexpandedParameterPack())
90 return inherited::TraverseType(T);
91
92 return true;
93 }
94
95 /// \brief Suppress traversel into types with location information
96 /// that do not contain unexpanded parameter packs.
97 bool TraverseTypeLoc(TypeLoc TL) {
98 if (!TL.getType().isNull() && TL.
99 getType()->containsUnexpandedParameterPack())
100 return inherited::TraverseTypeLoc(TL);
101
102 return true;
103 }
104
Douglas Gregorcff163e2010-12-15 21:57:59 +0000105 /// \brief Suppress traversal of non-parameter declarations, since
106 /// they cannot contain unexpanded parameter packs.
107 bool TraverseDecl(Decl *D) {
108 if (D && isa<ParmVarDecl>(D))
109 return inherited::TraverseDecl(D);
110
111 return true;
112 }
Douglas Gregor9ef75892010-12-15 19:43:21 +0000113 };
114}
115
116/// \brief Diagnose all of the unexpanded parameter packs in the given
117/// vector.
118static void
119DiagnoseUnexpandedParameterPacks(Sema &S, SourceLocation Loc,
120 Sema::UnexpandedParameterPackContext UPPC,
121 const llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
122 llvm::SmallVector<SourceLocation, 4> Locations;
123 llvm::SmallVector<IdentifierInfo *, 4> Names;
124 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
125
126 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
127 IdentifierInfo *Name = 0;
128 if (const TemplateTypeParmType *TTP
129 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
130 Name = TTP->getName();
131 else
132 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
133
134 if (Name && NamesKnown.insert(Name))
135 Names.push_back(Name);
136
137 if (Unexpanded[I].second.isValid())
138 Locations.push_back(Unexpanded[I].second);
139 }
140
141 DiagnosticBuilder DB
142 = Names.size() == 0? S.Diag(Loc, diag::err_unexpanded_parameter_pack_0)
143 << (int)UPPC
144 : Names.size() == 1? S.Diag(Loc, diag::err_unexpanded_parameter_pack_1)
145 << (int)UPPC << Names[0]
146 : Names.size() == 2? S.Diag(Loc, diag::err_unexpanded_parameter_pack_2)
147 << (int)UPPC << Names[0] << Names[1]
148 : S.Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
149 << (int)UPPC << Names[0] << Names[1];
150
151 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
152 DB << SourceRange(Locations[I]);
153}
154
Douglas Gregorc4633352010-12-15 17:38:57 +0000155bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
156 TypeSourceInfo *T,
157 UnexpandedParameterPackContext UPPC) {
158 // C++0x [temp.variadic]p5:
159 // An appearance of a name of a parameter pack that is not expanded is
160 // ill-formed.
161 if (!T->getType()->containsUnexpandedParameterPack())
162 return false;
163
Douglas Gregor9ef75892010-12-15 19:43:21 +0000164 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
165 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
166 T->getTypeLoc());
167 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
168 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
Douglas Gregorc4633352010-12-15 17:38:57 +0000169 return true;
170}
171
172bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
Douglas Gregor56c04582010-12-16 00:46:58 +0000173 UnexpandedParameterPackContext UPPC) {
Douglas Gregorc4633352010-12-15 17:38:57 +0000174 // C++0x [temp.variadic]p5:
175 // An appearance of a name of a parameter pack that is not expanded is
176 // ill-formed.
177 if (!E->containsUnexpandedParameterPack())
178 return false;
179
Douglas Gregor9ef75892010-12-15 19:43:21 +0000180 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
181 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
182 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
183 DiagnoseUnexpandedParameterPacks(*this, E->getLocStart(), UPPC, Unexpanded);
Douglas Gregorc4633352010-12-15 17:38:57 +0000184 return true;
185}
Douglas Gregor56c04582010-12-16 00:46:58 +0000186
187bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
188 UnexpandedParameterPackContext UPPC) {
189 // C++0x [temp.variadic]p5:
190 // An appearance of a name of a parameter pack that is not expanded is
191 // ill-formed.
192 if (!SS.getScopeRep() ||
193 !SS.getScopeRep()->containsUnexpandedParameterPack())
194 return false;
195
196 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
197 CollectUnexpandedParameterPacksVisitor(Unexpanded)
198 .TraverseNestedNameSpecifier(SS.getScopeRep());
199 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
200 DiagnoseUnexpandedParameterPacks(*this, SS.getRange().getBegin(),
201 UPPC, Unexpanded);
202 return true;
203}
204
205bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
206 UnexpandedParameterPackContext UPPC) {
207 // C++0x [temp.variadic]p5:
208 // An appearance of a name of a parameter pack that is not expanded is
209 // ill-formed.
210 switch (NameInfo.getName().getNameKind()) {
211 case DeclarationName::Identifier:
212 case DeclarationName::ObjCZeroArgSelector:
213 case DeclarationName::ObjCOneArgSelector:
214 case DeclarationName::ObjCMultiArgSelector:
215 case DeclarationName::CXXOperatorName:
216 case DeclarationName::CXXLiteralOperatorName:
217 case DeclarationName::CXXUsingDirective:
218 return false;
219
220 case DeclarationName::CXXConstructorName:
221 case DeclarationName::CXXDestructorName:
222 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor099ffe82010-12-16 17:19:19 +0000223 // FIXME: We shouldn't need this null check!
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000224 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
225 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
226
227 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
Douglas Gregor56c04582010-12-16 00:46:58 +0000228 return false;
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000229
Douglas Gregor56c04582010-12-16 00:46:58 +0000230 break;
231 }
232
233 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
234 CollectUnexpandedParameterPacksVisitor(Unexpanded)
Douglas Gregor0762bfd2010-12-16 01:40:04 +0000235 .TraverseType(NameInfo.getName().getCXXNameType());
Douglas Gregor56c04582010-12-16 00:46:58 +0000236 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
237 DiagnoseUnexpandedParameterPacks(*this, NameInfo.getLoc(), UPPC, Unexpanded);
238 return true;
239}
Douglas Gregor6f526752010-12-16 08:48:57 +0000240
241bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
242 TemplateName Template,
243 UnexpandedParameterPackContext UPPC) {
244
245 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
246 return false;
247
248 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
249 CollectUnexpandedParameterPacksVisitor(Unexpanded)
250 .TraverseTemplateName(Template);
251 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
252 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
253 return true;
254}
255
Douglas Gregore02e2622010-12-22 21:19:48 +0000256void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
257 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
258 CollectUnexpandedParameterPacksVisitor(Unexpanded)
259 .TraverseTemplateArgument(Arg);
260}
261
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000262void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
263 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
264 CollectUnexpandedParameterPacksVisitor(Unexpanded)
265 .TraverseTemplateArgumentLoc(Arg);
266}
267
Douglas Gregorb99268b2010-12-21 00:52:54 +0000268void Sema::collectUnexpandedParameterPacks(QualType T,
269 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
270 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
271}
272
Douglas Gregor7536dd52010-12-20 02:24:11 +0000273ParsedTemplateArgument
274Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
275 SourceLocation EllipsisLoc) {
276 if (Arg.isInvalid())
277 return Arg;
278
279 switch (Arg.getKind()) {
280 case ParsedTemplateArgument::Type: {
281 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
282 if (Result.isInvalid())
283 return ParsedTemplateArgument();
284
285 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
286 Arg.getLocation());
287 }
288
289 case ParsedTemplateArgument::NonType:
290 Diag(EllipsisLoc, diag::err_pack_expansion_unsupported)
291 << 0;
292 return ParsedTemplateArgument();
293
294 case ParsedTemplateArgument::Template:
295 Diag(EllipsisLoc, diag::err_pack_expansion_unsupported)
296 << 1;
297 return ParsedTemplateArgument();
298 }
299 llvm_unreachable("Unhandled template argument kind?");
300 return ParsedTemplateArgument();
301}
302
303TypeResult Sema::ActOnPackExpansion(ParsedType Type,
304 SourceLocation EllipsisLoc) {
305 TypeSourceInfo *TSInfo;
306 GetTypeFromParser(Type, &TSInfo);
307 if (!TSInfo)
308 return true;
309
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000310 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc);
311 if (!TSResult)
312 return true;
313
314 return CreateParsedType(TSResult->getType(), TSResult);
315}
316
317TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
318 SourceLocation EllipsisLoc) {
Douglas Gregor7536dd52010-12-20 02:24:11 +0000319 // C++0x [temp.variadic]p5:
320 // The pattern of a pack expansion shall name one or more
321 // parameter packs that are not expanded by a nested pack
322 // expansion.
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000323 if (!Pattern->getType()->containsUnexpandedParameterPack()) {
Douglas Gregor7536dd52010-12-20 02:24:11 +0000324 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000325 << Pattern->getTypeLoc().getSourceRange();
326 return 0;
Douglas Gregor7536dd52010-12-20 02:24:11 +0000327 }
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000328
Douglas Gregor7536dd52010-12-20 02:24:11 +0000329 // Create the pack expansion type and source-location information.
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000330 QualType Result = Context.getPackExpansionType(Pattern->getType());
Douglas Gregor7536dd52010-12-20 02:24:11 +0000331 TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
332 PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc());
333 TL.setEllipsisLoc(EllipsisLoc);
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000334
Douglas Gregor7536dd52010-12-20 02:24:11 +0000335 // Copy over the source-location information from the type.
336 memcpy(TL.getNextTypeLoc().getOpaqueData(),
Douglas Gregor8491ffe2010-12-20 22:05:00 +0000337 Pattern->getTypeLoc().getOpaqueData(),
338 Pattern->getTypeLoc().getFullDataSize());
339 return TSResult;
Douglas Gregor7536dd52010-12-20 02:24:11 +0000340}
Douglas Gregorb99268b2010-12-21 00:52:54 +0000341
342
343bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
344 SourceRange PatternRange,
345 const UnexpandedParameterPack *Unexpanded,
346 unsigned NumUnexpanded,
347 const MultiLevelTemplateArgumentList &TemplateArgs,
348 bool &ShouldExpand,
349 unsigned &NumExpansions) {
350 ShouldExpand = true;
351 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
352 bool HaveFirstPack = false;
353
354 for (unsigned I = 0; I != NumUnexpanded; ++I) {
355 // Compute the depth and index for this parameter pack.
356 unsigned Depth;
357 unsigned Index;
358 IdentifierInfo *Name;
359
360 if (const TemplateTypeParmType *TTP
361 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
362 Depth = TTP->getDepth();
363 Index = TTP->getIndex();
364 Name = TTP->getName();
365 } else {
366 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
367 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) {
368 Depth = TTP->getDepth();
369 Index = TTP->getIndex();
370 } else if (NonTypeTemplateParmDecl *NTTP
371 = dyn_cast<NonTypeTemplateParmDecl>(ND)) {
372 Depth = NTTP->getDepth();
373 Index = NTTP->getIndex();
374 } else {
375 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
376 Depth = TTP->getDepth();
377 Index = TTP->getIndex();
378 }
379 // FIXME: Variadic templates function parameter packs?
380 Name = ND->getIdentifier();
381 }
382
383 // If we don't have a template argument at this depth/index, then we
384 // cannot expand the pack expansion. Make a note of this, but we still
385 // want to check that any parameter packs we *do* have arguments for.
386 if (!TemplateArgs.hasTemplateArgument(Depth, Index)) {
387 ShouldExpand = false;
388 continue;
389 }
390
391 // Determine the size of the argument pack.
392 unsigned NewPackSize = TemplateArgs(Depth, Index).pack_size();
393 if (!HaveFirstPack) {
394 // The is the first pack we've seen for which we have an argument.
395 // Record it.
396 NumExpansions = NewPackSize;
397 FirstPack.first = Name;
398 FirstPack.second = Unexpanded[I].second;
399 HaveFirstPack = true;
400 continue;
401 }
402
403 if (NewPackSize != NumExpansions) {
404 // C++0x [temp.variadic]p5:
405 // All of the parameter packs expanded by a pack expansion shall have
406 // the same number of arguments specified.
407 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
408 << FirstPack.first << Name << NumExpansions << NewPackSize
409 << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
410 return true;
411 }
412 }
413
414 return false;
415}
Douglas Gregora8bc8c92010-12-23 22:44:42 +0000416
417bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
418 const DeclSpec &DS = D.getDeclSpec();
419 switch (DS.getTypeSpecType()) {
420 case TST_typename:
421 case TST_typeofType: {
422 QualType T = DS.getRepAsType().get();
423 if (!T.isNull() && T->containsUnexpandedParameterPack())
424 return true;
425 break;
426 }
427
428 case TST_typeofExpr:
429 case TST_decltype:
430 if (DS.getRepAsExpr() &&
431 DS.getRepAsExpr()->containsUnexpandedParameterPack())
432 return true;
433 break;
434
435 case TST_unspecified:
436 case TST_void:
437 case TST_char:
438 case TST_wchar:
439 case TST_char16:
440 case TST_char32:
441 case TST_int:
442 case TST_float:
443 case TST_double:
444 case TST_bool:
445 case TST_decimal32:
446 case TST_decimal64:
447 case TST_decimal128:
448 case TST_enum:
449 case TST_union:
450 case TST_struct:
451 case TST_class:
452 case TST_auto:
453 case TST_error:
454 break;
455 }
456
457 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
458 const DeclaratorChunk &Chunk = D.getTypeObject(I);
459 switch (Chunk.Kind) {
460 case DeclaratorChunk::Pointer:
461 case DeclaratorChunk::Reference:
462 case DeclaratorChunk::Paren:
463 // These declarator chunks cannot contain any parameter packs.
464 break;
465
466 case DeclaratorChunk::Array:
467 case DeclaratorChunk::Function:
468 case DeclaratorChunk::BlockPointer:
469 // Syntactically, these kinds of declarator chunks all come after the
470 // declarator-id (conceptually), so the parser should not invoke this
471 // routine at this time.
472 llvm_unreachable("Could not have seen this kind of declarator chunk");
473 break;
474
475 case DeclaratorChunk::MemberPointer:
476 if (Chunk.Mem.Scope().getScopeRep() &&
477 Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
478 return true;
479 break;
480 }
481 }
482
483 return false;
484}