SemaTemplateVariadic.cpp revision ee8aff06f6a96214731de17b2cb6df407c6c1820
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 21using namespace clang; 22 23//---------------------------------------------------------------------------- 24// Visitor that collects unexpanded parameter packs 25//---------------------------------------------------------------------------- 26 27namespace { 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 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded; 36 37 public: 38 explicit CollectUnexpandedParameterPacksVisitor( 39 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) 40 : Unexpanded(Unexpanded) { } 41 42 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. 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. 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 (FIXME: function and) non-type template 68 /// parameter packs in an expression. 69 bool VisitDeclRefExpr(DeclRefExpr *E) { 70 if (NonTypeTemplateParmDecl *NTTP 71 = dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) { 72 if (NTTP->isParameterPack()) 73 Unexpanded.push_back(std::make_pair(NTTP, E->getLocation())); 74 } 75 76 // FIXME: Function parameter packs. 77 78 return true; 79 } 80 81 // FIXME: Record occurrences of template template parameter packs. 82 83 //------------------------------------------------------------------------ 84 // Pruning the search for unexpanded parameter packs. 85 //------------------------------------------------------------------------ 86 87 /// \brief Suppress traversal into statements and expressions that 88 /// do not contain unexpanded parameter packs. 89 bool TraverseStmt(Stmt *S) { 90 if (Expr *E = dyn_cast_or_null<Expr>(S)) 91 if (E->containsUnexpandedParameterPack()) 92 return inherited::TraverseStmt(E); 93 94 return true; 95 } 96 97 /// \brief Suppress traversal into types that do not contain 98 /// unexpanded parameter packs. 99 bool TraverseType(QualType T) { 100 if (!T.isNull() && T->containsUnexpandedParameterPack()) 101 return inherited::TraverseType(T); 102 103 return true; 104 } 105 106 /// \brief Suppress traversel into types with location information 107 /// that do not contain unexpanded parameter packs. 108 bool TraverseTypeLoc(TypeLoc TL) { 109 if (!TL.getType().isNull() && 110 TL.getType()->containsUnexpandedParameterPack()) 111 return inherited::TraverseTypeLoc(TL); 112 113 return true; 114 } 115 116 /// \brief Suppress traversal of non-parameter declarations, since 117 /// they cannot contain unexpanded parameter packs. 118 bool TraverseDecl(Decl *D) { 119 if (D && isa<ParmVarDecl>(D)) 120 return inherited::TraverseDecl(D); 121 122 return true; 123 } 124 }; 125} 126 127/// \brief Diagnose all of the unexpanded parameter packs in the given 128/// vector. 129static void 130DiagnoseUnexpandedParameterPacks(Sema &S, SourceLocation Loc, 131 Sema::UnexpandedParameterPackContext UPPC, 132 const llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { 133 llvm::SmallVector<SourceLocation, 4> Locations; 134 llvm::SmallVector<IdentifierInfo *, 4> Names; 135 llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown; 136 137 for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) { 138 IdentifierInfo *Name = 0; 139 if (const TemplateTypeParmType *TTP 140 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) 141 Name = TTP->getName(); 142 else 143 Name = Unexpanded[I].first.get<NamedDecl *>()->getIdentifier(); 144 145 if (Name && NamesKnown.insert(Name)) 146 Names.push_back(Name); 147 148 if (Unexpanded[I].second.isValid()) 149 Locations.push_back(Unexpanded[I].second); 150 } 151 152 DiagnosticBuilder DB 153 = Names.size() == 0? S.Diag(Loc, diag::err_unexpanded_parameter_pack_0) 154 << (int)UPPC 155 : Names.size() == 1? S.Diag(Loc, diag::err_unexpanded_parameter_pack_1) 156 << (int)UPPC << Names[0] 157 : Names.size() == 2? S.Diag(Loc, diag::err_unexpanded_parameter_pack_2) 158 << (int)UPPC << Names[0] << Names[1] 159 : S.Diag(Loc, diag::err_unexpanded_parameter_pack_3_or_more) 160 << (int)UPPC << Names[0] << Names[1]; 161 162 for (unsigned I = 0, N = Locations.size(); I != N; ++I) 163 DB << SourceRange(Locations[I]); 164} 165 166bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, 167 TypeSourceInfo *T, 168 UnexpandedParameterPackContext UPPC) { 169 // C++0x [temp.variadic]p5: 170 // An appearance of a name of a parameter pack that is not expanded is 171 // ill-formed. 172 if (!T->getType()->containsUnexpandedParameterPack()) 173 return false; 174 175 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; 176 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc( 177 T->getTypeLoc()); 178 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); 179 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded); 180 return true; 181} 182 183bool Sema::DiagnoseUnexpandedParameterPack(Expr *E, 184 UnexpandedParameterPackContext UPPC) { 185 // C++0x [temp.variadic]p5: 186 // An appearance of a name of a parameter pack that is not expanded is 187 // ill-formed. 188 if (!E->containsUnexpandedParameterPack()) 189 return false; 190 191 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; 192 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E); 193 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); 194 DiagnoseUnexpandedParameterPacks(*this, E->getLocStart(), UPPC, Unexpanded); 195 return true; 196} 197 198bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS, 199 UnexpandedParameterPackContext UPPC) { 200 // C++0x [temp.variadic]p5: 201 // An appearance of a name of a parameter pack that is not expanded is 202 // ill-formed. 203 if (!SS.getScopeRep() || 204 !SS.getScopeRep()->containsUnexpandedParameterPack()) 205 return false; 206 207 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; 208 CollectUnexpandedParameterPacksVisitor(Unexpanded) 209 .TraverseNestedNameSpecifier(SS.getScopeRep()); 210 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); 211 DiagnoseUnexpandedParameterPacks(*this, SS.getRange().getBegin(), 212 UPPC, Unexpanded); 213 return true; 214} 215 216bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo, 217 UnexpandedParameterPackContext UPPC) { 218 // C++0x [temp.variadic]p5: 219 // An appearance of a name of a parameter pack that is not expanded is 220 // ill-formed. 221 switch (NameInfo.getName().getNameKind()) { 222 case DeclarationName::Identifier: 223 case DeclarationName::ObjCZeroArgSelector: 224 case DeclarationName::ObjCOneArgSelector: 225 case DeclarationName::ObjCMultiArgSelector: 226 case DeclarationName::CXXOperatorName: 227 case DeclarationName::CXXLiteralOperatorName: 228 case DeclarationName::CXXUsingDirective: 229 return false; 230 231 case DeclarationName::CXXConstructorName: 232 case DeclarationName::CXXDestructorName: 233 case DeclarationName::CXXConversionFunctionName: 234 // FIXME: We shouldn't need this null check! 235 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) 236 return DiagnoseUnexpandedParameterPack(NameInfo.getLoc(), TSInfo, UPPC); 237 238 if (!NameInfo.getName().getCXXNameType()->containsUnexpandedParameterPack()) 239 return false; 240 241 break; 242 } 243 244 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; 245 CollectUnexpandedParameterPacksVisitor(Unexpanded) 246 .TraverseType(NameInfo.getName().getCXXNameType()); 247 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); 248 DiagnoseUnexpandedParameterPacks(*this, NameInfo.getLoc(), UPPC, Unexpanded); 249 return true; 250} 251 252bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, 253 TemplateName Template, 254 UnexpandedParameterPackContext UPPC) { 255 256 if (Template.isNull() || !Template.containsUnexpandedParameterPack()) 257 return false; 258 259 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; 260 CollectUnexpandedParameterPacksVisitor(Unexpanded) 261 .TraverseTemplateName(Template); 262 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); 263 DiagnoseUnexpandedParameterPacks(*this, Loc, UPPC, Unexpanded); 264 return true; 265} 266 267bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg, 268 UnexpandedParameterPackContext UPPC) { 269 if (Arg.getArgument().isNull() || 270 !Arg.getArgument().containsUnexpandedParameterPack()) 271 return false; 272 273 llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; 274 CollectUnexpandedParameterPacksVisitor(Unexpanded) 275 .TraverseTemplateArgumentLoc(Arg); 276 assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs"); 277 DiagnoseUnexpandedParameterPacks(*this, Arg.getLocation(), UPPC, Unexpanded); 278 return true; 279} 280 281void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg, 282 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { 283 CollectUnexpandedParameterPacksVisitor(Unexpanded) 284 .TraverseTemplateArgument(Arg); 285} 286 287void Sema::collectUnexpandedParameterPacks(TemplateArgumentLoc Arg, 288 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { 289 CollectUnexpandedParameterPacksVisitor(Unexpanded) 290 .TraverseTemplateArgumentLoc(Arg); 291} 292 293void Sema::collectUnexpandedParameterPacks(QualType T, 294 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { 295 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseType(T); 296} 297 298void Sema::collectUnexpandedParameterPacks(TypeLoc TL, 299 llvm::SmallVectorImpl<UnexpandedParameterPack> &Unexpanded) { 300 CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(TL); 301} 302 303ParsedTemplateArgument 304Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg, 305 SourceLocation EllipsisLoc) { 306 if (Arg.isInvalid()) 307 return Arg; 308 309 switch (Arg.getKind()) { 310 case ParsedTemplateArgument::Type: { 311 TypeResult Result = ActOnPackExpansion(Arg.getAsType(), EllipsisLoc); 312 if (Result.isInvalid()) 313 return ParsedTemplateArgument(); 314 315 return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(), 316 Arg.getLocation()); 317 } 318 319 case ParsedTemplateArgument::NonType: { 320 ExprResult Result = ActOnPackExpansion(Arg.getAsExpr(), EllipsisLoc); 321 if (Result.isInvalid()) 322 return ParsedTemplateArgument(); 323 324 return ParsedTemplateArgument(Arg.getKind(), Result.get(), 325 Arg.getLocation()); 326 } 327 328 case ParsedTemplateArgument::Template: 329 Diag(EllipsisLoc, diag::err_pack_expansion_unsupported); 330 return ParsedTemplateArgument(); 331 } 332 llvm_unreachable("Unhandled template argument kind?"); 333 return ParsedTemplateArgument(); 334} 335 336TypeResult Sema::ActOnPackExpansion(ParsedType Type, 337 SourceLocation EllipsisLoc) { 338 TypeSourceInfo *TSInfo; 339 GetTypeFromParser(Type, &TSInfo); 340 if (!TSInfo) 341 return true; 342 343 TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc); 344 if (!TSResult) 345 return true; 346 347 return CreateParsedType(TSResult->getType(), TSResult); 348} 349 350TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, 351 SourceLocation EllipsisLoc) { 352 // C++0x [temp.variadic]p5: 353 // The pattern of a pack expansion shall name one or more 354 // parameter packs that are not expanded by a nested pack 355 // expansion. 356 if (!Pattern->getType()->containsUnexpandedParameterPack()) { 357 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) 358 << Pattern->getTypeLoc().getSourceRange(); 359 return 0; 360 } 361 362 // Create the pack expansion type and source-location information. 363 QualType Result = Context.getPackExpansionType(Pattern->getType()); 364 TypeSourceInfo *TSResult = Context.CreateTypeSourceInfo(Result); 365 PackExpansionTypeLoc TL = cast<PackExpansionTypeLoc>(TSResult->getTypeLoc()); 366 TL.setEllipsisLoc(EllipsisLoc); 367 368 // Copy over the source-location information from the type. 369 memcpy(TL.getNextTypeLoc().getOpaqueData(), 370 Pattern->getTypeLoc().getOpaqueData(), 371 Pattern->getTypeLoc().getFullDataSize()); 372 return TSResult; 373} 374 375ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { 376 if (!Pattern) 377 return ExprError(); 378 379 // C++0x [temp.variadic]p5: 380 // The pattern of a pack expansion shall name one or more 381 // parameter packs that are not expanded by a nested pack 382 // expansion. 383 if (!Pattern->containsUnexpandedParameterPack()) { 384 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs) 385 << Pattern->getSourceRange(); 386 return ExprError(); 387 } 388 389 // Create the pack expansion expression and source-location information. 390 return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern, 391 EllipsisLoc)); 392} 393 394bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, 395 SourceRange PatternRange, 396 const UnexpandedParameterPack *Unexpanded, 397 unsigned NumUnexpanded, 398 const MultiLevelTemplateArgumentList &TemplateArgs, 399 bool &ShouldExpand, 400 unsigned &NumExpansions) { 401 ShouldExpand = true; 402 std::pair<IdentifierInfo *, SourceLocation> FirstPack; 403 bool HaveFirstPack = false; 404 405 for (unsigned I = 0; I != NumUnexpanded; ++I) { 406 // Compute the depth and index for this parameter pack. 407 unsigned Depth; 408 unsigned Index; 409 IdentifierInfo *Name; 410 411 if (const TemplateTypeParmType *TTP 412 = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) { 413 Depth = TTP->getDepth(); 414 Index = TTP->getIndex(); 415 Name = TTP->getName(); 416 } else { 417 NamedDecl *ND = Unexpanded[I].first.get<NamedDecl *>(); 418 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ND)) { 419 Depth = TTP->getDepth(); 420 Index = TTP->getIndex(); 421 } else if (NonTypeTemplateParmDecl *NTTP 422 = dyn_cast<NonTypeTemplateParmDecl>(ND)) { 423 Depth = NTTP->getDepth(); 424 Index = NTTP->getIndex(); 425 } else { 426 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(ND); 427 Depth = TTP->getDepth(); 428 Index = TTP->getIndex(); 429 } 430 // FIXME: Variadic templates function parameter packs? 431 Name = ND->getIdentifier(); 432 } 433 434 // If we don't have a template argument at this depth/index, then we 435 // cannot expand the pack expansion. Make a note of this, but we still 436 // want to check any parameter packs we *do* have arguments for. 437 if (Depth >= TemplateArgs.getNumLevels() || 438 !TemplateArgs.hasTemplateArgument(Depth, Index)) { 439 ShouldExpand = false; 440 continue; 441 } 442 443 // Determine the size of the argument pack. 444 unsigned NewPackSize = TemplateArgs(Depth, Index).pack_size(); 445 if (!HaveFirstPack) { 446 // The is the first pack we've seen for which we have an argument. 447 // Record it. 448 NumExpansions = NewPackSize; 449 FirstPack.first = Name; 450 FirstPack.second = Unexpanded[I].second; 451 HaveFirstPack = true; 452 continue; 453 } 454 455 if (NewPackSize != NumExpansions) { 456 // C++0x [temp.variadic]p5: 457 // All of the parameter packs expanded by a pack expansion shall have 458 // the same number of arguments specified. 459 Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) 460 << FirstPack.first << Name << NumExpansions << NewPackSize 461 << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second); 462 return true; 463 } 464 } 465 466 return false; 467} 468 469bool Sema::containsUnexpandedParameterPacks(Declarator &D) { 470 const DeclSpec &DS = D.getDeclSpec(); 471 switch (DS.getTypeSpecType()) { 472 case TST_typename: 473 case TST_typeofType: { 474 QualType T = DS.getRepAsType().get(); 475 if (!T.isNull() && T->containsUnexpandedParameterPack()) 476 return true; 477 break; 478 } 479 480 case TST_typeofExpr: 481 case TST_decltype: 482 if (DS.getRepAsExpr() && 483 DS.getRepAsExpr()->containsUnexpandedParameterPack()) 484 return true; 485 break; 486 487 case TST_unspecified: 488 case TST_void: 489 case TST_char: 490 case TST_wchar: 491 case TST_char16: 492 case TST_char32: 493 case TST_int: 494 case TST_float: 495 case TST_double: 496 case TST_bool: 497 case TST_decimal32: 498 case TST_decimal64: 499 case TST_decimal128: 500 case TST_enum: 501 case TST_union: 502 case TST_struct: 503 case TST_class: 504 case TST_auto: 505 case TST_error: 506 break; 507 } 508 509 for (unsigned I = 0, N = D.getNumTypeObjects(); I != N; ++I) { 510 const DeclaratorChunk &Chunk = D.getTypeObject(I); 511 switch (Chunk.Kind) { 512 case DeclaratorChunk::Pointer: 513 case DeclaratorChunk::Reference: 514 case DeclaratorChunk::Paren: 515 // These declarator chunks cannot contain any parameter packs. 516 break; 517 518 case DeclaratorChunk::Array: 519 case DeclaratorChunk::Function: 520 case DeclaratorChunk::BlockPointer: 521 // Syntactically, these kinds of declarator chunks all come after the 522 // declarator-id (conceptually), so the parser should not invoke this 523 // routine at this time. 524 llvm_unreachable("Could not have seen this kind of declarator chunk"); 525 break; 526 527 case DeclaratorChunk::MemberPointer: 528 if (Chunk.Mem.Scope().getScopeRep() && 529 Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack()) 530 return true; 531 break; 532 } 533 } 534 535 return false; 536} 537 538/// \brief Called when an expression computing the size of a parameter pack 539/// is parsed. 540/// 541/// \code 542/// template<typename ...Types> struct count { 543/// static const unsigned value = sizeof...(Types); 544/// }; 545/// \endcode 546/// 547// 548/// \param OpLoc The location of the "sizeof" keyword. 549/// \param Name The name of the parameter pack whose size will be determined. 550/// \param NameLoc The source location of the name of the parameter pack. 551/// \param RParenLoc The location of the closing parentheses. 552ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, 553 SourceLocation OpLoc, 554 IdentifierInfo &Name, 555 SourceLocation NameLoc, 556 SourceLocation RParenLoc) { 557 // C++0x [expr.sizeof]p5: 558 // The identifier in a sizeof... expression shall name a parameter pack. 559 560 LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName); 561 LookupName(R, S); 562 563 NamedDecl *ParameterPack = 0; 564 switch (R.getResultKind()) { 565 case LookupResult::Found: 566 ParameterPack = R.getFoundDecl(); 567 break; 568 569 case LookupResult::NotFound: 570 case LookupResult::NotFoundInCurrentInstantiation: 571 if (DeclarationName CorrectedName = CorrectTypo(R, S, 0, 0, false, 572 CTC_NoKeywords)) { 573 // FIXME: Variadic templates function parameter packs. 574 if (NamedDecl *CorrectedResult = R.getAsSingle<NamedDecl>()) 575 if (CorrectedResult->isTemplateParameterPack()) { 576 ParameterPack = CorrectedResult; 577 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest) 578 << &Name << CorrectedName 579 << FixItHint::CreateReplacement(NameLoc, 580 CorrectedName.getAsString()); 581 Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here) 582 << CorrectedName; 583 } 584 } 585 586 case LookupResult::FoundOverloaded: 587 case LookupResult::FoundUnresolvedValue: 588 break; 589 590 case LookupResult::Ambiguous: 591 DiagnoseAmbiguousLookup(R); 592 return ExprError(); 593 } 594 595 // FIXME: Variadic templates function parameter packs. 596 if (!ParameterPack || !ParameterPack->isTemplateParameterPack()) { 597 Diag(NameLoc, diag::err_sizeof_pack_no_pack_name) 598 << &Name; 599 return ExprError(); 600 } 601 602 return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc, 603 ParameterPack, NameLoc, RParenLoc); 604} 605