blob: fe30ba5845f1f13ff4e25e4c4f38aa1022c278b4 [file] [log] [blame]
Douglas Gregorb55fdf82010-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 Gregord2fa7662010-12-20 02:24:11 +000013#include "clang/Sema/ParsedTemplate.h"
Douglas Gregorb55fdf82010-12-15 17:38:57 +000014#include "clang/Sema/SemaInternal.h"
Douglas Gregor840bd6c2010-12-20 22:05:00 +000015#include "clang/Sema/Template.h"
Douglas Gregorb55fdf82010-12-15 17:38:57 +000016#include "clang/AST/Expr.h"
Douglas Gregor1da294a2010-12-15 19:43:21 +000017#include "clang/AST/RecursiveASTVisitor.h"
Douglas Gregorb55fdf82010-12-15 17:38:57 +000018#include "clang/AST/TypeLoc.h"
19
20using namespace clang;
21
Douglas Gregor1da294a2010-12-15 19:43:21 +000022//----------------------------------------------------------------------------
23// Visitor that collects unexpanded parameter packs
24//----------------------------------------------------------------------------
25
Douglas Gregor1da294a2010-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 Gregor15b4ec22010-12-20 23:07:20 +000041 bool shouldWalkTypesOfTypeLocs() const { return false; }
42
Douglas Gregor1da294a2010-12-15 19:43:21 +000043 //------------------------------------------------------------------------
44 // Recording occurrences of (unexpanded) parameter packs.
45 //------------------------------------------------------------------------
46
47 /// \brief Record occurrences of template type parameter packs.
48 bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
49 if (TL.getTypePtr()->isParameterPack())
50 Unexpanded.push_back(std::make_pair(TL.getTypePtr(), TL.getNameLoc()));
51 return true;
52 }
53
54 /// \brief Record occurrences of template type parameter packs
55 /// when we don't have proper source-location information for
56 /// them.
57 ///
58 /// Ideally, this routine would never be used.
59 bool VisitTemplateTypeParmType(TemplateTypeParmType *T) {
60 if (T->isParameterPack())
61 Unexpanded.push_back(std::make_pair(T, SourceLocation()));
62
63 return true;
64 }
65
Douglas Gregorda3cc0d2010-12-23 23:51:58 +000066 /// \brief Record occurrences of (FIXME: function and) non-type template
67 /// parameter packs in an expression.
68 bool VisitDeclRefExpr(DeclRefExpr *E) {
69 if (NonTypeTemplateParmDecl *NTTP
70 = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) {
71 if (NTTP->isParameterPack())
72 Unexpanded.push_back(std::make_pair(NTTP, E->getLocation()));
73 }
74
75 // FIXME: Function parameter packs.
76
77 return true;
78 }
79
80 // FIXME: Record occurrences of template template parameter packs.
Douglas Gregor1da294a2010-12-15 19:43:21 +000081
82 // FIXME: Once we have pack expansions in the AST, block their
83 // traversal.
84
85 //------------------------------------------------------------------------
86 // Pruning the search for unexpanded parameter packs.
87 //------------------------------------------------------------------------
88
89 /// \brief Suppress traversal into statements and expressions that
90 /// do not contain unexpanded parameter packs.
91 bool TraverseStmt(Stmt *S) {
92 if (Expr *E = dyn_cast_or_null<Expr>(S))
93 if (E->containsUnexpandedParameterPack())
94 return inherited::TraverseStmt(E);
95
96 return true;
97 }
98
99 /// \brief Suppress traversal into types that do not contain
100 /// unexpanded parameter packs.
101 bool TraverseType(QualType T) {
102 if (!T.isNull() && T->containsUnexpandedParameterPack())
103 return inherited::TraverseType(T);
104
105 return true;
106 }
107
108 /// \brief Suppress traversel into types with location information
109 /// that do not contain unexpanded parameter packs.
110 bool TraverseTypeLoc(TypeLoc TL) {
Douglas Gregorda3cc0d2010-12-23 23:51:58 +0000111 if (!TL.getType().isNull() &&
112 TL.getType()->containsUnexpandedParameterPack())
Douglas Gregor1da294a2010-12-15 19:43:21 +0000113 return inherited::TraverseTypeLoc(TL);
114
115 return true;
116 }
117
Douglas Gregora8461bb2010-12-15 21:57:59 +0000118 /// \brief Suppress traversal of non-parameter declarations, since
119 /// they cannot contain unexpanded parameter packs.
120 bool TraverseDecl(Decl *D) {
121 if (D && isa<ParmVarDecl>(D))
122 return inherited::TraverseDecl(D);
123
124 return true;
125 }
Douglas Gregor1da294a2010-12-15 19:43:21 +0000126 };
127}
128
129/// \brief Diagnose all of the unexpanded parameter packs in the given
130/// vector.
131static void
132DiagnoseUnexpandedParameterPacks(Sema &S, SourceLocation Loc,
133 Sema::UnexpandedParameterPackContext UPPC,
134 const llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
135 llvm::SmallVector<SourceLocation, 4> Locations;
136 llvm::SmallVector<IdentifierInfo *, 4> Names;
137 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
138
139 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
140 IdentifierInfo *Name = 0;
141 if (const TemplateTypeParmType *TTP
142 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
143 Name = TTP->getName();
144 else
145 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier();
146
147 if (Name && NamesKnown.insert(Name))
148 Names.push_back(Name);
149
150 if (Unexpanded[I].second.isValid())
151 Locations.push_back(Unexpanded[I].second);
152 }
153
154 DiagnosticBuilder DB
155 = Names.size() == 0? S.Diag(Loc, diag::err_unexpanded_parameter_pack_0)
156 << (int)UPPC
157 : Names.size() == 1? S.Diag(Loc, diag::err_unexpanded_parameter_pack_1)
158 << (int)UPPC << Names[0]
159 : Names.size() == 2? S.Diag(Loc, diag::err_unexpanded_parameter_pack_2)
160 << (int)UPPC << Names[0] << Names[1]
161 : S.Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more)
162 << (int)UPPC << Names[0] << Names[1];
163
164 for (unsigned I = 0, N = Locations.size(); I != N; ++I)
165 DB << SourceRange(Locations[I]);
166}
167
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000168bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
169 TypeSourceInfo *T,
170 UnexpandedParameterPackContext UPPC) {
171 // C++0x [temp.variadic]p5:
172 // An appearance of a name of a parameter pack that is not expanded is
173 // ill-formed.
174 if (!T->getType()->containsUnexpandedParameterPack())
175 return false;
176
Douglas Gregor1da294a2010-12-15 19:43:21 +0000177 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
178 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
179 T->getTypeLoc());
180 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
181 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000182 return true;
183}
184
185bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
Douglas Gregorc4356532010-12-16 00:46:58 +0000186 UnexpandedParameterPackContext UPPC) {
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000187 // C++0x [temp.variadic]p5:
188 // An appearance of a name of a parameter pack that is not expanded is
189 // ill-formed.
190 if (!E->containsUnexpandedParameterPack())
191 return false;
192
Douglas Gregor1da294a2010-12-15 19:43:21 +0000193 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
194 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
195 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
196 DiagnoseUnexpandedParameterPacks(*this, E->getLocStart(), UPPC, Unexpanded);
Douglas Gregorb55fdf82010-12-15 17:38:57 +0000197 return true;
198}
Douglas Gregorc4356532010-12-16 00:46:58 +0000199
200bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
201 UnexpandedParameterPackContext UPPC) {
202 // C++0x [temp.variadic]p5:
203 // An appearance of a name of a parameter pack that is not expanded is
204 // ill-formed.
205 if (!SS.getScopeRep() ||
206 !SS.getScopeRep()->containsUnexpandedParameterPack())
207 return false;
208
209 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
210 CollectUnexpandedParameterPacksVisitor(Unexpanded)
211 .TraverseNestedNameSpecifier(SS.getScopeRep());
212 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
213 DiagnoseUnexpandedParameterPacks(*this, SS.getRange().getBegin(),
214 UPPC, Unexpanded);
215 return true;
216}
217
218bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
219 UnexpandedParameterPackContext UPPC) {
220 // C++0x [temp.variadic]p5:
221 // An appearance of a name of a parameter pack that is not expanded is
222 // ill-formed.
223 switch (NameInfo.getName().getNameKind()) {
224 case DeclarationName::Identifier:
225 case DeclarationName::ObjCZeroArgSelector:
226 case DeclarationName::ObjCOneArgSelector:
227 case DeclarationName::ObjCMultiArgSelector:
228 case DeclarationName::CXXOperatorName:
229 case DeclarationName::CXXLiteralOperatorName:
230 case DeclarationName::CXXUsingDirective:
231 return false;
232
233 case DeclarationName::CXXConstructorName:
234 case DeclarationName::CXXDestructorName:
235 case DeclarationName::CXXConversionFunctionName:
Douglas Gregor062ecac2010-12-16 17:19:19 +0000236 // FIXME: We shouldn't need this null check!
Douglas Gregor6ab34af2010-12-16 01:40:04 +0000237 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
238 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC);
239
240 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack())
Douglas Gregorc4356532010-12-16 00:46:58 +0000241 return false;
Douglas Gregor6ab34af2010-12-16 01:40:04 +0000242
Douglas Gregorc4356532010-12-16 00:46:58 +0000243 break;
244 }
245
246 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
247 CollectUnexpandedParameterPacksVisitor(Unexpanded)
Douglas Gregor6ab34af2010-12-16 01:40:04 +0000248 .TraverseType(NameInfo.getName().getCXXNameType());
Douglas Gregorc4356532010-12-16 00:46:58 +0000249 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
250 DiagnoseUnexpandedParameterPacks(*this, NameInfo.getLoc(), UPPC, Unexpanded);
251 return true;
252}
Douglas Gregor6ff1fbf2010-12-16 08:48:57 +0000253
254bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
255 TemplateName Template,
256 UnexpandedParameterPackContext UPPC) {
257
258 if (Template.isNull() || !Template.containsUnexpandedParameterPack())
259 return false;
260
261 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded;
262 CollectUnexpandedParameterPacksVisitor(Unexpanded)
263 .TraverseTemplateName(Template);
264 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
265 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded);
266 return true;
267}
268
Douglas Gregor0f3feb42010-12-22 21:19:48 +0000269void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
270 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
271 CollectUnexpandedParameterPacksVisitor(Unexpanded)
272 .TraverseTemplateArgument(Arg);
273}
274
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000275void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg,
276 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
277 CollectUnexpandedParameterPacksVisitor(Unexpanded)
278 .TraverseTemplateArgumentLoc(Arg);
279}
280
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000281void Sema::collectUnexpandedParameterPacks(QualType T,
282 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) {
283 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T);
284}
285
Douglas Gregord2fa7662010-12-20 02:24:11 +0000286ParsedTemplateArgument
287Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
288 SourceLocation EllipsisLoc) {
289 if (Arg.isInvalid())
290 return Arg;
291
292 switch (Arg.getKind()) {
293 case ParsedTemplateArgument::Type: {
294 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc);
295 if (Result.isInvalid())
296 return ParsedTemplateArgument();
297
298 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
299 Arg.getLocation());
300 }
301
302 case ParsedTemplateArgument::NonType:
303 Diag(EllipsisLoc, diag::err_pack_expansion_unsupported)
304 << 0;
305 return ParsedTemplateArgument();
306
307 case ParsedTemplateArgument::Template:
308 Diag(EllipsisLoc, diag::err_pack_expansion_unsupported)
309 << 1;
310 return ParsedTemplateArgument();
311 }
312 llvm_unreachable("Unhandled template argument kind?");
313 return ParsedTemplateArgument();
314}
315
316TypeResult Sema::ActOnPackExpansion(ParsedType Type,
317 SourceLocation EllipsisLoc) {
318 TypeSourceInfo *TSInfo;
319 GetTypeFromParser(Type, &TSInfo);
320 if (!TSInfo)
321 return true;
322
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000323 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc);
324 if (!TSResult)
325 return true;
326
327 return CreateParsedType(TSResult->getType(), TSResult);
328}
329
330TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern,
331 SourceLocation EllipsisLoc) {
Douglas Gregord2fa7662010-12-20 02:24:11 +0000332 // C++0x [temp.variadic]p5:
333 // The pattern of a pack expansion shall name one or more
334 // parameter packs that are not expanded by a nested pack
335 // expansion.
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000336 if (!Pattern->getType()->containsUnexpandedParameterPack()) {
Douglas Gregord2fa7662010-12-20 02:24:11 +0000337 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000338 << Pattern->getTypeLoc().getSourceRange();
339 return 0;
Douglas Gregord2fa7662010-12-20 02:24:11 +0000340 }
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000341
Douglas Gregord2fa7662010-12-20 02:24:11 +0000342 // Create the pack expansion type and source-location information.
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000343 QualType Result = Context.getPackExpansionType(Pattern->getType());
Douglas Gregord2fa7662010-12-20 02:24:11 +0000344 TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result);
345 PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc());
346 TL.setEllipsisLoc(EllipsisLoc);
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000347
Douglas Gregord2fa7662010-12-20 02:24:11 +0000348 // Copy over the source-location information from the type.
349 memcpy(TL.getNextTypeLoc().getOpaqueData(),
Douglas Gregor840bd6c2010-12-20 22:05:00 +0000350 Pattern->getTypeLoc().getOpaqueData(),
351 Pattern->getTypeLoc().getFullDataSize());
352 return TSResult;
Douglas Gregord2fa7662010-12-20 02:24:11 +0000353}
Douglas Gregor76aca7b2010-12-21 00:52:54 +0000354
355
356bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
357 SourceRange PatternRange,
358 const UnexpandedParameterPack *Unexpanded,
359 unsigned NumUnexpanded,
360 const MultiLevelTemplateArgumentList &TemplateArgs,
361 bool &ShouldExpand,
362 unsigned &NumExpansions) {
363 ShouldExpand = true;
364 std::pair<IdentifierInfo *, SourceLocation> FirstPack;
365 bool HaveFirstPack = false;
366
367 for (unsigned I = 0; I != NumUnexpanded; ++I) {
368 // Compute the depth and index for this parameter pack.
369 unsigned Depth;
370 unsigned Index;
371 IdentifierInfo *Name;
372
373 if (const TemplateTypeParmType *TTP
374 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
375 Depth = TTP->getDepth();
376 Index = TTP->getIndex();
377 Name = TTP->getName();
378 } else {
379 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>();
380 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) {
381 Depth = TTP->getDepth();
382 Index = TTP->getIndex();
383 } else if (NonTypeTemplateParmDecl *NTTP
384 = dyn_cast<NonTypeTemplateParmDecl>(ND)) {
385 Depth = NTTP->getDepth();
386 Index = NTTP->getIndex();
387 } else {
388 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND);
389 Depth = TTP->getDepth();
390 Index = TTP->getIndex();
391 }
392 // FIXME: Variadic templates function parameter packs?
393 Name = ND->getIdentifier();
394 }
395
396 // If we don't have a template argument at this depth/index, then we
397 // cannot expand the pack expansion. Make a note of this, but we still
398 // want to check that any parameter packs we *do* have arguments for.
399 if (!TemplateArgs.hasTemplateArgument(Depth, Index)) {
400 ShouldExpand = false;
401 continue;
402 }
403
404 // Determine the size of the argument pack.
405 unsigned NewPackSize = TemplateArgs(Depth, Index).pack_size();
406 if (!HaveFirstPack) {
407 // The is the first pack we've seen for which we have an argument.
408 // Record it.
409 NumExpansions = NewPackSize;
410 FirstPack.first = Name;
411 FirstPack.second = Unexpanded[I].second;
412 HaveFirstPack = true;
413 continue;
414 }
415
416 if (NewPackSize != NumExpansions) {
417 // C++0x [temp.variadic]p5:
418 // All of the parameter packs expanded by a pack expansion shall have
419 // the same number of arguments specified.
420 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict)
421 << FirstPack.first << Name << NumExpansions << NewPackSize
422 << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second);
423 return true;
424 }
425 }
426
427 return false;
428}
Douglas Gregor27b4c162010-12-23 22:44:42 +0000429
430bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
431 const DeclSpec &DS = D.getDeclSpec();
432 switch (DS.getTypeSpecType()) {
433 case TST_typename:
434 case TST_typeofType: {
435 QualType T = DS.getRepAsType().get();
436 if (!T.isNull() && T->containsUnexpandedParameterPack())
437 return true;
438 break;
439 }
440
441 case TST_typeofExpr:
442 case TST_decltype:
443 if (DS.getRepAsExpr() &&
444 DS.getRepAsExpr()->containsUnexpandedParameterPack())
445 return true;
446 break;
447
448 case TST_unspecified:
449 case TST_void:
450 case TST_char:
451 case TST_wchar:
452 case TST_char16:
453 case TST_char32:
454 case TST_int:
455 case TST_float:
456 case TST_double:
457 case TST_bool:
458 case TST_decimal32:
459 case TST_decimal64:
460 case TST_decimal128:
461 case TST_enum:
462 case TST_union:
463 case TST_struct:
464 case TST_class:
465 case TST_auto:
466 case TST_error:
467 break;
468 }
469
470 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) {
471 const DeclaratorChunk &Chunk = D.getTypeObject(I);
472 switch (Chunk.Kind) {
473 case DeclaratorChunk::Pointer:
474 case DeclaratorChunk::Reference:
475 case DeclaratorChunk::Paren:
476 // These declarator chunks cannot contain any parameter packs.
477 break;
478
479 case DeclaratorChunk::Array:
480 case DeclaratorChunk::Function:
481 case DeclaratorChunk::BlockPointer:
482 // Syntactically, these kinds of declarator chunks all come after the
483 // declarator-id (conceptually), so the parser should not invoke this
484 // routine at this time.
485 llvm_unreachable("Could not have seen this kind of declarator chunk");
486 break;
487
488 case DeclaratorChunk::MemberPointer:
489 if (Chunk.Mem.Scope().getScopeRep() &&
490 Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
491 return true;
492 break;
493 }
494 }
495
496 return false;
497}