1 //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===// 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 // 10 // This file implements the C++ related Decl classes for templates. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/DeclTemplate.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/DeclCXX.h" 18 #include "clang/AST/Expr.h" 19 #include "clang/AST/ExprCXX.h" 20 #include "clang/AST/TypeLoc.h" 21 #include "clang/Basic/Builtins.h" 22 #include "clang/Basic/IdentifierTable.h" 23 #include "llvm/ADT/STLExtras.h" 24 #include <memory> 25 using namespace clang; 26 27 //===----------------------------------------------------------------------===// 28 // TemplateParameterList Implementation 29 //===----------------------------------------------------------------------===// 30 31 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, 32 SourceLocation LAngleLoc, 33 NamedDecl **Params, unsigned NumParams, 34 SourceLocation RAngleLoc) 35 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), 36 NumParams(NumParams), ContainsUnexpandedParameterPack(false) { 37 assert(this->NumParams == NumParams && "Too many template parameters"); 38 for (unsigned Idx = 0; Idx < NumParams; ++Idx) { 39 NamedDecl *P = Params[Idx]; 40 begin()[Idx] = P; 41 42 if (!P->isTemplateParameterPack()) { 43 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) 44 if (NTTP->getType()->containsUnexpandedParameterPack()) 45 ContainsUnexpandedParameterPack = true; 46 47 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) 48 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack()) 49 ContainsUnexpandedParameterPack = true; 50 51 // FIXME: If a default argument contains an unexpanded parameter pack, the 52 // template parameter list does too. 53 } 54 } 55 } 56 57 TemplateParameterList * 58 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, 59 SourceLocation LAngleLoc, NamedDecl **Params, 60 unsigned NumParams, SourceLocation RAngleLoc) { 61 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(NumParams), 62 llvm::alignOf<TemplateParameterList>()); 63 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, 64 NumParams, RAngleLoc); 65 } 66 67 unsigned TemplateParameterList::getMinRequiredArguments() const { 68 unsigned NumRequiredArgs = 0; 69 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(), 70 PEnd = const_cast<TemplateParameterList *>(this)->end(); 71 P != PEnd; ++P) { 72 if ((*P)->isTemplateParameterPack()) { 73 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) 74 if (NTTP->isExpandedParameterPack()) { 75 NumRequiredArgs += NTTP->getNumExpansionTypes(); 76 continue; 77 } 78 79 break; 80 } 81 82 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { 83 if (TTP->hasDefaultArgument()) 84 break; 85 } else if (NonTypeTemplateParmDecl *NTTP 86 = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 87 if (NTTP->hasDefaultArgument()) 88 break; 89 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument()) 90 break; 91 92 ++NumRequiredArgs; 93 } 94 95 return NumRequiredArgs; 96 } 97 98 unsigned TemplateParameterList::getDepth() const { 99 if (size() == 0) 100 return 0; 101 102 const NamedDecl *FirstParm = getParam(0); 103 if (const TemplateTypeParmDecl *TTP 104 = dyn_cast<TemplateTypeParmDecl>(FirstParm)) 105 return TTP->getDepth(); 106 else if (const NonTypeTemplateParmDecl *NTTP 107 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm)) 108 return NTTP->getDepth(); 109 else 110 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth(); 111 } 112 113 static void AdoptTemplateParameterList(TemplateParameterList *Params, 114 DeclContext *Owner) { 115 for (TemplateParameterList::iterator P = Params->begin(), 116 PEnd = Params->end(); 117 P != PEnd; ++P) { 118 (*P)->setDeclContext(Owner); 119 120 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P)) 121 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner); 122 } 123 } 124 125 namespace clang { 126 void *allocateDefaultArgStorageChain(const ASTContext &C) { 127 return new (C) char[sizeof(void*) * 2]; 128 } 129 } 130 131 //===----------------------------------------------------------------------===// 132 // RedeclarableTemplateDecl Implementation 133 //===----------------------------------------------------------------------===// 134 135 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const { 136 if (Common) 137 return Common; 138 139 // Walk the previous-declaration chain until we either find a declaration 140 // with a common pointer or we run out of previous declarations. 141 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls; 142 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev; 143 Prev = Prev->getPreviousDecl()) { 144 if (Prev->Common) { 145 Common = Prev->Common; 146 break; 147 } 148 149 PrevDecls.push_back(Prev); 150 } 151 152 // If we never found a common pointer, allocate one now. 153 if (!Common) { 154 // FIXME: If any of the declarations is from an AST file, we probably 155 // need an update record to add the common data. 156 157 Common = newCommon(getASTContext()); 158 } 159 160 // Update any previous declarations we saw with the common pointer. 161 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I) 162 PrevDecls[I]->Common = Common; 163 164 return Common; 165 } 166 167 template<class EntryType> 168 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType * 169 RedeclarableTemplateDecl::findSpecializationImpl( 170 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args, 171 void *&InsertPos) { 172 typedef SpecEntryTraits<EntryType> SETraits; 173 llvm::FoldingSetNodeID ID; 174 EntryType::Profile(ID,Args, getASTContext()); 175 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 176 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr; 177 } 178 179 template<class Derived, class EntryType> 180 void RedeclarableTemplateDecl::addSpecializationImpl( 181 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry, 182 void *InsertPos) { 183 typedef SpecEntryTraits<EntryType> SETraits; 184 if (InsertPos) { 185 #ifndef NDEBUG 186 void *CorrectInsertPos; 187 assert(!findSpecializationImpl(Specializations, 188 SETraits::getTemplateArgs(Entry), 189 CorrectInsertPos) && 190 InsertPos == CorrectInsertPos && 191 "given incorrect InsertPos for specialization"); 192 #endif 193 Specializations.InsertNode(Entry, InsertPos); 194 } else { 195 EntryType *Existing = Specializations.GetOrInsertNode(Entry); 196 (void)Existing; 197 assert(SETraits::getDecl(Existing)->isCanonicalDecl() && 198 "non-canonical specialization?"); 199 } 200 201 if (ASTMutationListener *L = getASTMutationListener()) 202 L->AddedCXXTemplateSpecialization(cast<Derived>(this), 203 SETraits::getDecl(Entry)); 204 } 205 206 /// \brief Generate the injected template arguments for the given template 207 /// parameter list, e.g., for the injected-class-name of a class template. 208 static void GenerateInjectedTemplateArgs(ASTContext &Context, 209 TemplateParameterList *Params, 210 TemplateArgument *Args) { 211 for (TemplateParameterList::iterator Param = Params->begin(), 212 ParamEnd = Params->end(); 213 Param != ParamEnd; ++Param) { 214 TemplateArgument Arg; 215 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { 216 QualType ArgType = Context.getTypeDeclType(TTP); 217 if (TTP->isParameterPack()) 218 ArgType = Context.getPackExpansionType(ArgType, None); 219 220 Arg = TemplateArgument(ArgType); 221 } else if (NonTypeTemplateParmDecl *NTTP = 222 dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 223 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false, 224 NTTP->getType().getNonLValueExprType(Context), 225 Expr::getValueKindForType(NTTP->getType()), 226 NTTP->getLocation()); 227 228 if (NTTP->isParameterPack()) 229 E = new (Context) PackExpansionExpr(Context.DependentTy, E, 230 NTTP->getLocation(), None); 231 Arg = TemplateArgument(E); 232 } else { 233 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 234 if (TTP->isParameterPack()) 235 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>()); 236 else 237 Arg = TemplateArgument(TemplateName(TTP)); 238 } 239 240 if ((*Param)->isTemplateParameterPack()) 241 Arg = TemplateArgument::CreatePackCopy(Context, Arg); 242 243 *Args++ = Arg; 244 } 245 } 246 247 //===----------------------------------------------------------------------===// 248 // FunctionTemplateDecl Implementation 249 //===----------------------------------------------------------------------===// 250 251 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) { 252 static_cast<Common *>(Ptr)->~Common(); 253 } 254 255 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 256 DeclContext *DC, 257 SourceLocation L, 258 DeclarationName Name, 259 TemplateParameterList *Params, 260 NamedDecl *Decl) { 261 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 262 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl); 263 } 264 265 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, 266 unsigned ID) { 267 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), 268 DeclarationName(), nullptr, nullptr); 269 } 270 271 RedeclarableTemplateDecl::CommonBase * 272 FunctionTemplateDecl::newCommon(ASTContext &C) const { 273 Common *CommonPtr = new (C) Common; 274 C.AddDeallocation(DeallocateCommon, CommonPtr); 275 return CommonPtr; 276 } 277 278 void FunctionTemplateDecl::LoadLazySpecializations() const { 279 // Grab the most recent declaration to ensure we've loaded any lazy 280 // redeclarations of this template. 281 // 282 // FIXME: Avoid walking the entire redeclaration chain here. 283 Common *CommonPtr = getMostRecentDecl()->getCommonPtr(); 284 if (CommonPtr->LazySpecializations) { 285 ASTContext &Context = getASTContext(); 286 uint32_t *Specs = CommonPtr->LazySpecializations; 287 CommonPtr->LazySpecializations = nullptr; 288 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 289 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 290 } 291 } 292 293 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & 294 FunctionTemplateDecl::getSpecializations() const { 295 LoadLazySpecializations(); 296 return getCommonPtr()->Specializations; 297 } 298 299 FunctionDecl * 300 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 301 void *&InsertPos) { 302 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 303 } 304 305 void FunctionTemplateDecl::addSpecialization( 306 FunctionTemplateSpecializationInfo *Info, void *InsertPos) { 307 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info, 308 InsertPos); 309 } 310 311 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() { 312 TemplateParameterList *Params = getTemplateParameters(); 313 Common *CommonPtr = getCommonPtr(); 314 if (!CommonPtr->InjectedArgs) { 315 CommonPtr->InjectedArgs 316 = new (getASTContext()) TemplateArgument[Params->size()]; 317 GenerateInjectedTemplateArgs(getASTContext(), Params, 318 CommonPtr->InjectedArgs); 319 } 320 321 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size()); 322 } 323 324 //===----------------------------------------------------------------------===// 325 // ClassTemplateDecl Implementation 326 //===----------------------------------------------------------------------===// 327 328 void ClassTemplateDecl::DeallocateCommon(void *Ptr) { 329 static_cast<Common *>(Ptr)->~Common(); 330 } 331 332 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 333 DeclContext *DC, 334 SourceLocation L, 335 DeclarationName Name, 336 TemplateParameterList *Params, 337 NamedDecl *Decl, 338 ClassTemplateDecl *PrevDecl) { 339 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 340 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name, 341 Params, Decl); 342 New->setPreviousDecl(PrevDecl); 343 return New; 344 } 345 346 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 347 unsigned ID) { 348 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), 349 DeclarationName(), nullptr, nullptr); 350 } 351 352 void ClassTemplateDecl::LoadLazySpecializations() const { 353 // Grab the most recent declaration to ensure we've loaded any lazy 354 // redeclarations of this template. 355 // 356 // FIXME: Avoid walking the entire redeclaration chain here. 357 Common *CommonPtr = getMostRecentDecl()->getCommonPtr(); 358 if (CommonPtr->LazySpecializations) { 359 ASTContext &Context = getASTContext(); 360 uint32_t *Specs = CommonPtr->LazySpecializations; 361 CommonPtr->LazySpecializations = nullptr; 362 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 363 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 364 } 365 } 366 367 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 368 ClassTemplateDecl::getSpecializations() const { 369 LoadLazySpecializations(); 370 return getCommonPtr()->Specializations; 371 } 372 373 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 374 ClassTemplateDecl::getPartialSpecializations() { 375 LoadLazySpecializations(); 376 return getCommonPtr()->PartialSpecializations; 377 } 378 379 RedeclarableTemplateDecl::CommonBase * 380 ClassTemplateDecl::newCommon(ASTContext &C) const { 381 Common *CommonPtr = new (C) Common; 382 C.AddDeallocation(DeallocateCommon, CommonPtr); 383 return CommonPtr; 384 } 385 386 ClassTemplateSpecializationDecl * 387 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 388 void *&InsertPos) { 389 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 390 } 391 392 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 393 void *InsertPos) { 394 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos); 395 } 396 397 ClassTemplatePartialSpecializationDecl * 398 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 399 void *&InsertPos) { 400 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); 401 } 402 403 void ClassTemplateDecl::AddPartialSpecialization( 404 ClassTemplatePartialSpecializationDecl *D, 405 void *InsertPos) { 406 if (InsertPos) 407 getPartialSpecializations().InsertNode(D, InsertPos); 408 else { 409 ClassTemplatePartialSpecializationDecl *Existing 410 = getPartialSpecializations().GetOrInsertNode(D); 411 (void)Existing; 412 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 413 } 414 415 if (ASTMutationListener *L = getASTMutationListener()) 416 L->AddedCXXTemplateSpecialization(this, D); 417 } 418 419 void ClassTemplateDecl::getPartialSpecializations( 420 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) { 421 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs 422 = getPartialSpecializations(); 423 PS.clear(); 424 PS.reserve(PartialSpecs.size()); 425 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 426 P = PartialSpecs.begin(), PEnd = PartialSpecs.end(); 427 P != PEnd; ++P) 428 PS.push_back(P->getMostRecentDecl()); 429 } 430 431 ClassTemplatePartialSpecializationDecl * 432 ClassTemplateDecl::findPartialSpecialization(QualType T) { 433 ASTContext &Context = getASTContext(); 434 using llvm::FoldingSetVector; 435 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 436 partial_spec_iterator; 437 for (partial_spec_iterator P = getPartialSpecializations().begin(), 438 PEnd = getPartialSpecializations().end(); 439 P != PEnd; ++P) { 440 if (Context.hasSameType(P->getInjectedSpecializationType(), T)) 441 return P->getMostRecentDecl(); 442 } 443 444 return nullptr; 445 } 446 447 ClassTemplatePartialSpecializationDecl * 448 ClassTemplateDecl::findPartialSpecInstantiatedFromMember( 449 ClassTemplatePartialSpecializationDecl *D) { 450 Decl *DCanon = D->getCanonicalDecl(); 451 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 452 P = getPartialSpecializations().begin(), 453 PEnd = getPartialSpecializations().end(); 454 P != PEnd; ++P) { 455 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 456 return P->getMostRecentDecl(); 457 } 458 459 return nullptr; 460 } 461 462 QualType 463 ClassTemplateDecl::getInjectedClassNameSpecialization() { 464 Common *CommonPtr = getCommonPtr(); 465 if (!CommonPtr->InjectedClassNameType.isNull()) 466 return CommonPtr->InjectedClassNameType; 467 468 // C++0x [temp.dep.type]p2: 469 // The template argument list of a primary template is a template argument 470 // list in which the nth template argument has the value of the nth template 471 // parameter of the class template. If the nth template parameter is a 472 // template parameter pack (14.5.3), the nth template argument is a pack 473 // expansion (14.5.3) whose pattern is the name of the template parameter 474 // pack. 475 ASTContext &Context = getASTContext(); 476 TemplateParameterList *Params = getTemplateParameters(); 477 SmallVector<TemplateArgument, 16> TemplateArgs; 478 TemplateArgs.resize(Params->size()); 479 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data()); 480 CommonPtr->InjectedClassNameType 481 = Context.getTemplateSpecializationType(TemplateName(this), 482 &TemplateArgs[0], 483 TemplateArgs.size()); 484 return CommonPtr->InjectedClassNameType; 485 } 486 487 //===----------------------------------------------------------------------===// 488 // TemplateTypeParm Allocation/Deallocation Method Implementations 489 //===----------------------------------------------------------------------===// 490 491 TemplateTypeParmDecl * 492 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC, 493 SourceLocation KeyLoc, SourceLocation NameLoc, 494 unsigned D, unsigned P, IdentifierInfo *Id, 495 bool Typename, bool ParameterPack) { 496 TemplateTypeParmDecl *TTPDecl = 497 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename); 498 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 499 TTPDecl->setTypeForDecl(TTPType.getTypePtr()); 500 return TTPDecl; 501 } 502 503 TemplateTypeParmDecl * 504 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { 505 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), 506 SourceLocation(), nullptr, false); 507 } 508 509 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 510 return hasDefaultArgument() 511 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc() 512 : SourceLocation(); 513 } 514 515 SourceRange TemplateTypeParmDecl::getSourceRange() const { 516 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 517 return SourceRange(getLocStart(), 518 getDefaultArgumentInfo()->getTypeLoc().getEndLoc()); 519 else 520 return TypeDecl::getSourceRange(); 521 } 522 523 unsigned TemplateTypeParmDecl::getDepth() const { 524 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth(); 525 } 526 527 unsigned TemplateTypeParmDecl::getIndex() const { 528 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex(); 529 } 530 531 bool TemplateTypeParmDecl::isParameterPack() const { 532 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack(); 533 } 534 535 //===----------------------------------------------------------------------===// 536 // NonTypeTemplateParmDecl Method Implementations 537 //===----------------------------------------------------------------------===// 538 539 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 540 SourceLocation StartLoc, 541 SourceLocation IdLoc, 542 unsigned D, unsigned P, 543 IdentifierInfo *Id, 544 QualType T, 545 TypeSourceInfo *TInfo, 546 const QualType *ExpandedTypes, 547 unsigned NumExpandedTypes, 548 TypeSourceInfo **ExpandedTInfos) 549 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 550 TemplateParmPosition(D, P), ParameterPack(true), 551 ExpandedParameterPack(true), NumExpandedTypes(NumExpandedTypes) { 552 if (ExpandedTypes && ExpandedTInfos) { 553 auto TypesAndInfos = 554 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); 555 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 556 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]); 557 TypesAndInfos[I].second = ExpandedTInfos[I]; 558 } 559 } 560 } 561 562 NonTypeTemplateParmDecl * 563 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 564 SourceLocation StartLoc, SourceLocation IdLoc, 565 unsigned D, unsigned P, IdentifierInfo *Id, 566 QualType T, bool ParameterPack, 567 TypeSourceInfo *TInfo) { 568 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 569 T, ParameterPack, TInfo); 570 } 571 572 NonTypeTemplateParmDecl * 573 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 574 SourceLocation StartLoc, SourceLocation IdLoc, 575 unsigned D, unsigned P, 576 IdentifierInfo *Id, QualType T, 577 TypeSourceInfo *TInfo, 578 const QualType *ExpandedTypes, 579 unsigned NumExpandedTypes, 580 TypeSourceInfo **ExpandedTInfos) { 581 return new (C, DC, 582 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( 583 NumExpandedTypes)) 584 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo, 585 ExpandedTypes, NumExpandedTypes, ExpandedTInfos); 586 } 587 588 NonTypeTemplateParmDecl * 589 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 590 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(), 591 SourceLocation(), 0, 0, nullptr, 592 QualType(), false, nullptr); 593 } 594 595 NonTypeTemplateParmDecl * 596 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 597 unsigned NumExpandedTypes) { 598 return new (C, ID, 599 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( 600 NumExpandedTypes)) 601 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 0, 0, 602 nullptr, QualType(), nullptr, nullptr, 603 NumExpandedTypes, nullptr); 604 } 605 606 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 607 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 608 return SourceRange(getOuterLocStart(), 609 getDefaultArgument()->getSourceRange().getEnd()); 610 return DeclaratorDecl::getSourceRange(); 611 } 612 613 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 614 return hasDefaultArgument() 615 ? getDefaultArgument()->getSourceRange().getBegin() 616 : SourceLocation(); 617 } 618 619 //===----------------------------------------------------------------------===// 620 // TemplateTemplateParmDecl Method Implementations 621 //===----------------------------------------------------------------------===// 622 623 void TemplateTemplateParmDecl::anchor() { } 624 625 TemplateTemplateParmDecl::TemplateTemplateParmDecl( 626 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 627 IdentifierInfo *Id, TemplateParameterList *Params, 628 unsigned NumExpansions, TemplateParameterList * const *Expansions) 629 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 630 TemplateParmPosition(D, P), ParameterPack(true), 631 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) { 632 if (Expansions) 633 std::uninitialized_copy(Expansions, Expansions + NumExpandedParams, 634 getTrailingObjects<TemplateParameterList *>()); 635 } 636 637 TemplateTemplateParmDecl * 638 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 639 SourceLocation L, unsigned D, unsigned P, 640 bool ParameterPack, IdentifierInfo *Id, 641 TemplateParameterList *Params) { 642 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 643 Params); 644 } 645 646 TemplateTemplateParmDecl * 647 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 648 SourceLocation L, unsigned D, unsigned P, 649 IdentifierInfo *Id, 650 TemplateParameterList *Params, 651 ArrayRef<TemplateParameterList *> Expansions) { 652 return new (C, DC, 653 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size())) 654 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions.size(), 655 Expansions.data()); 656 } 657 658 TemplateTemplateParmDecl * 659 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 660 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, 661 false, nullptr, nullptr); 662 } 663 664 TemplateTemplateParmDecl * 665 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 666 unsigned NumExpansions) { 667 return new (C, ID, 668 additionalSizeToAlloc<TemplateParameterList *>(NumExpansions)) 669 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, 670 nullptr, NumExpansions, nullptr); 671 } 672 673 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 674 return hasDefaultArgument() ? getDefaultArgument().getLocation() 675 : SourceLocation(); 676 } 677 678 void TemplateTemplateParmDecl::setDefaultArgument( 679 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 680 if (DefArg.getArgument().isNull()) 681 DefaultArgument.set(nullptr); 682 else 683 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 684 } 685 686 //===----------------------------------------------------------------------===// 687 // TemplateArgumentList Implementation 688 //===----------------------------------------------------------------------===// 689 TemplateArgumentList::TemplateArgumentList(const TemplateArgument *Args, 690 unsigned NumArgs) 691 : Arguments(getTrailingObjects<TemplateArgument>()), NumArguments(NumArgs) { 692 std::uninitialized_copy(Args, Args + NumArgs, 693 getTrailingObjects<TemplateArgument>()); 694 } 695 696 TemplateArgumentList * 697 TemplateArgumentList::CreateCopy(ASTContext &Context, 698 const TemplateArgument *Args, 699 unsigned NumArgs) { 700 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(NumArgs)); 701 return new (Mem) TemplateArgumentList(Args, NumArgs); 702 } 703 704 FunctionTemplateSpecializationInfo * 705 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 706 FunctionTemplateDecl *Template, 707 TemplateSpecializationKind TSK, 708 const TemplateArgumentList *TemplateArgs, 709 const TemplateArgumentListInfo *TemplateArgsAsWritten, 710 SourceLocation POI) { 711 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; 712 if (TemplateArgsAsWritten) 713 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 714 *TemplateArgsAsWritten); 715 716 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 717 TemplateArgs, 718 ArgsAsWritten, 719 POI); 720 } 721 722 //===----------------------------------------------------------------------===// 723 // TemplateDecl Implementation 724 //===----------------------------------------------------------------------===// 725 726 void TemplateDecl::anchor() { } 727 728 //===----------------------------------------------------------------------===// 729 // ClassTemplateSpecializationDecl Implementation 730 //===----------------------------------------------------------------------===// 731 ClassTemplateSpecializationDecl:: 732 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 733 DeclContext *DC, SourceLocation StartLoc, 734 SourceLocation IdLoc, 735 ClassTemplateDecl *SpecializedTemplate, 736 const TemplateArgument *Args, 737 unsigned NumArgs, 738 ClassTemplateSpecializationDecl *PrevDecl) 739 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, 740 SpecializedTemplate->getIdentifier(), 741 PrevDecl), 742 SpecializedTemplate(SpecializedTemplate), 743 ExplicitInfo(nullptr), 744 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 745 SpecializationKind(TSK_Undeclared) { 746 } 747 748 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, 749 Kind DK) 750 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(), 751 SourceLocation(), nullptr, nullptr), 752 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {} 753 754 ClassTemplateSpecializationDecl * 755 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 756 DeclContext *DC, 757 SourceLocation StartLoc, 758 SourceLocation IdLoc, 759 ClassTemplateDecl *SpecializedTemplate, 760 const TemplateArgument *Args, 761 unsigned NumArgs, 762 ClassTemplateSpecializationDecl *PrevDecl) { 763 ClassTemplateSpecializationDecl *Result = 764 new (Context, DC) ClassTemplateSpecializationDecl( 765 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, 766 SpecializedTemplate, Args, NumArgs, PrevDecl); 767 Result->MayHaveOutOfDateDef = false; 768 769 Context.getTypeDeclType(Result, PrevDecl); 770 return Result; 771 } 772 773 ClassTemplateSpecializationDecl * 774 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 775 unsigned ID) { 776 ClassTemplateSpecializationDecl *Result = 777 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); 778 Result->MayHaveOutOfDateDef = false; 779 return Result; 780 } 781 782 void ClassTemplateSpecializationDecl::getNameForDiagnostic( 783 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 784 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 785 786 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 787 TemplateSpecializationType::PrintTemplateArgumentList( 788 OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 789 } 790 791 ClassTemplateDecl * 792 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 793 if (SpecializedPartialSpecialization *PartialSpec 794 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 795 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 796 return SpecializedTemplate.get<ClassTemplateDecl*>(); 797 } 798 799 SourceRange 800 ClassTemplateSpecializationDecl::getSourceRange() const { 801 if (ExplicitInfo) { 802 SourceLocation Begin = getTemplateKeywordLoc(); 803 if (Begin.isValid()) { 804 // Here we have an explicit (partial) specialization or instantiation. 805 assert(getSpecializationKind() == TSK_ExplicitSpecialization || 806 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || 807 getSpecializationKind() == TSK_ExplicitInstantiationDefinition); 808 if (getExternLoc().isValid()) 809 Begin = getExternLoc(); 810 SourceLocation End = getRBraceLoc(); 811 if (End.isInvalid()) 812 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 813 return SourceRange(Begin, End); 814 } 815 // An implicit instantiation of a class template partial specialization 816 // uses ExplicitInfo to record the TypeAsWritten, but the source 817 // locations should be retrieved from the instantiation pattern. 818 typedef ClassTemplatePartialSpecializationDecl CTPSDecl; 819 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this)); 820 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); 821 assert(inst_from != nullptr); 822 return inst_from->getSourceRange(); 823 } 824 else { 825 // No explicit info available. 826 llvm::PointerUnion<ClassTemplateDecl *, 827 ClassTemplatePartialSpecializationDecl *> 828 inst_from = getInstantiatedFrom(); 829 if (inst_from.isNull()) 830 return getSpecializedTemplate()->getSourceRange(); 831 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>()) 832 return ctd->getSourceRange(); 833 return inst_from.get<ClassTemplatePartialSpecializationDecl*>() 834 ->getSourceRange(); 835 } 836 } 837 838 //===----------------------------------------------------------------------===// 839 // ClassTemplatePartialSpecializationDecl Implementation 840 //===----------------------------------------------------------------------===// 841 void ClassTemplatePartialSpecializationDecl::anchor() { } 842 843 ClassTemplatePartialSpecializationDecl:: 844 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 845 DeclContext *DC, 846 SourceLocation StartLoc, 847 SourceLocation IdLoc, 848 TemplateParameterList *Params, 849 ClassTemplateDecl *SpecializedTemplate, 850 const TemplateArgument *Args, 851 unsigned NumArgs, 852 const ASTTemplateArgumentListInfo *ArgInfos, 853 ClassTemplatePartialSpecializationDecl *PrevDecl) 854 : ClassTemplateSpecializationDecl(Context, 855 ClassTemplatePartialSpecialization, 856 TK, DC, StartLoc, IdLoc, 857 SpecializedTemplate, 858 Args, NumArgs, PrevDecl), 859 TemplateParams(Params), ArgsAsWritten(ArgInfos), 860 InstantiatedFromMember(nullptr, false) 861 { 862 AdoptTemplateParameterList(Params, this); 863 } 864 865 ClassTemplatePartialSpecializationDecl * 866 ClassTemplatePartialSpecializationDecl:: 867 Create(ASTContext &Context, TagKind TK,DeclContext *DC, 868 SourceLocation StartLoc, SourceLocation IdLoc, 869 TemplateParameterList *Params, 870 ClassTemplateDecl *SpecializedTemplate, 871 const TemplateArgument *Args, 872 unsigned NumArgs, 873 const TemplateArgumentListInfo &ArgInfos, 874 QualType CanonInjectedType, 875 ClassTemplatePartialSpecializationDecl *PrevDecl) { 876 const ASTTemplateArgumentListInfo *ASTArgInfos = 877 ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 878 879 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC) 880 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc, 881 Params, SpecializedTemplate, Args, 882 NumArgs, ASTArgInfos, PrevDecl); 883 Result->setSpecializationKind(TSK_ExplicitSpecialization); 884 Result->MayHaveOutOfDateDef = false; 885 886 Context.getInjectedClassNameType(Result, CanonInjectedType); 887 return Result; 888 } 889 890 ClassTemplatePartialSpecializationDecl * 891 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 892 unsigned ID) { 893 ClassTemplatePartialSpecializationDecl *Result = 894 new (C, ID) ClassTemplatePartialSpecializationDecl(C); 895 Result->MayHaveOutOfDateDef = false; 896 return Result; 897 } 898 899 //===----------------------------------------------------------------------===// 900 // FriendTemplateDecl Implementation 901 //===----------------------------------------------------------------------===// 902 903 void FriendTemplateDecl::anchor() { } 904 905 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 906 DeclContext *DC, 907 SourceLocation L, 908 unsigned NParams, 909 TemplateParameterList **Params, 910 FriendUnion Friend, 911 SourceLocation FLoc) { 912 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params, 913 Friend, FLoc); 914 } 915 916 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 917 unsigned ID) { 918 return new (C, ID) FriendTemplateDecl(EmptyShell()); 919 } 920 921 //===----------------------------------------------------------------------===// 922 // TypeAliasTemplateDecl Implementation 923 //===----------------------------------------------------------------------===// 924 925 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 926 DeclContext *DC, 927 SourceLocation L, 928 DeclarationName Name, 929 TemplateParameterList *Params, 930 NamedDecl *Decl) { 931 AdoptTemplateParameterList(Params, DC); 932 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); 933 } 934 935 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 936 unsigned ID) { 937 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), 938 DeclarationName(), nullptr, nullptr); 939 } 940 941 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) { 942 static_cast<Common *>(Ptr)->~Common(); 943 } 944 RedeclarableTemplateDecl::CommonBase * 945 TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 946 Common *CommonPtr = new (C) Common; 947 C.AddDeallocation(DeallocateCommon, CommonPtr); 948 return CommonPtr; 949 } 950 951 //===----------------------------------------------------------------------===// 952 // ClassScopeFunctionSpecializationDecl Implementation 953 //===----------------------------------------------------------------------===// 954 955 void ClassScopeFunctionSpecializationDecl::anchor() { } 956 957 ClassScopeFunctionSpecializationDecl * 958 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 959 unsigned ID) { 960 return new (C, ID) ClassScopeFunctionSpecializationDecl( 961 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo()); 962 } 963 964 //===----------------------------------------------------------------------===// 965 // VarTemplateDecl Implementation 966 //===----------------------------------------------------------------------===// 967 968 void VarTemplateDecl::DeallocateCommon(void *Ptr) { 969 static_cast<Common *>(Ptr)->~Common(); 970 } 971 972 VarTemplateDecl *VarTemplateDecl::getDefinition() { 973 VarTemplateDecl *CurD = this; 974 while (CurD) { 975 if (CurD->isThisDeclarationADefinition()) 976 return CurD; 977 CurD = CurD->getPreviousDecl(); 978 } 979 return nullptr; 980 } 981 982 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 983 SourceLocation L, DeclarationName Name, 984 TemplateParameterList *Params, 985 VarDecl *Decl) { 986 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); 987 } 988 989 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 990 unsigned ID) { 991 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), 992 DeclarationName(), nullptr, nullptr); 993 } 994 995 // TODO: Unify across class, function and variable templates? 996 // May require moving this and Common to RedeclarableTemplateDecl. 997 void VarTemplateDecl::LoadLazySpecializations() const { 998 // Grab the most recent declaration to ensure we've loaded any lazy 999 // redeclarations of this template. 1000 // 1001 // FIXME: Avoid walking the entire redeclaration chain here. 1002 Common *CommonPtr = getMostRecentDecl()->getCommonPtr(); 1003 if (CommonPtr->LazySpecializations) { 1004 ASTContext &Context = getASTContext(); 1005 uint32_t *Specs = CommonPtr->LazySpecializations; 1006 CommonPtr->LazySpecializations = nullptr; 1007 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 1008 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 1009 } 1010 } 1011 1012 llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 1013 VarTemplateDecl::getSpecializations() const { 1014 LoadLazySpecializations(); 1015 return getCommonPtr()->Specializations; 1016 } 1017 1018 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 1019 VarTemplateDecl::getPartialSpecializations() { 1020 LoadLazySpecializations(); 1021 return getCommonPtr()->PartialSpecializations; 1022 } 1023 1024 RedeclarableTemplateDecl::CommonBase * 1025 VarTemplateDecl::newCommon(ASTContext &C) const { 1026 Common *CommonPtr = new (C) Common; 1027 C.AddDeallocation(DeallocateCommon, CommonPtr); 1028 return CommonPtr; 1029 } 1030 1031 VarTemplateSpecializationDecl * 1032 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 1033 void *&InsertPos) { 1034 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 1035 } 1036 1037 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 1038 void *InsertPos) { 1039 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos); 1040 } 1041 1042 VarTemplatePartialSpecializationDecl * 1043 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 1044 void *&InsertPos) { 1045 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); 1046 } 1047 1048 void VarTemplateDecl::AddPartialSpecialization( 1049 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 1050 if (InsertPos) 1051 getPartialSpecializations().InsertNode(D, InsertPos); 1052 else { 1053 VarTemplatePartialSpecializationDecl *Existing = 1054 getPartialSpecializations().GetOrInsertNode(D); 1055 (void)Existing; 1056 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1057 } 1058 1059 if (ASTMutationListener *L = getASTMutationListener()) 1060 L->AddedCXXTemplateSpecialization(this, D); 1061 } 1062 1063 void VarTemplateDecl::getPartialSpecializations( 1064 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) { 1065 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 1066 getPartialSpecializations(); 1067 PS.clear(); 1068 PS.reserve(PartialSpecs.size()); 1069 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 1070 P = PartialSpecs.begin(), 1071 PEnd = PartialSpecs.end(); 1072 P != PEnd; ++P) 1073 PS.push_back(P->getMostRecentDecl()); 1074 } 1075 1076 VarTemplatePartialSpecializationDecl * 1077 VarTemplateDecl::findPartialSpecInstantiatedFromMember( 1078 VarTemplatePartialSpecializationDecl *D) { 1079 Decl *DCanon = D->getCanonicalDecl(); 1080 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 1081 P = getPartialSpecializations().begin(), 1082 PEnd = getPartialSpecializations().end(); 1083 P != PEnd; ++P) { 1084 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1085 return P->getMostRecentDecl(); 1086 } 1087 1088 return nullptr; 1089 } 1090 1091 //===----------------------------------------------------------------------===// 1092 // VarTemplateSpecializationDecl Implementation 1093 //===----------------------------------------------------------------------===// 1094 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1095 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1096 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1097 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 1098 unsigned NumArgs) 1099 : VarDecl(DK, Context, DC, StartLoc, IdLoc, 1100 SpecializedTemplate->getIdentifier(), T, TInfo, S), 1101 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr), 1102 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 1103 SpecializationKind(TSK_Undeclared) {} 1104 1105 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, 1106 ASTContext &C) 1107 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, 1108 QualType(), nullptr, SC_None), 1109 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {} 1110 1111 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1112 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1113 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1114 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 1115 unsigned NumArgs) { 1116 return new (Context, DC) VarTemplateSpecializationDecl( 1117 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, 1118 SpecializedTemplate, T, TInfo, S, Args, NumArgs); 1119 } 1120 1121 VarTemplateSpecializationDecl * 1122 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1123 return new (C, ID) 1124 VarTemplateSpecializationDecl(VarTemplateSpecialization, C); 1125 } 1126 1127 void VarTemplateSpecializationDecl::getNameForDiagnostic( 1128 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1129 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1130 1131 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1132 TemplateSpecializationType::PrintTemplateArgumentList( 1133 OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 1134 } 1135 1136 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1137 if (SpecializedPartialSpecialization *PartialSpec = 1138 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1139 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1140 return SpecializedTemplate.get<VarTemplateDecl *>(); 1141 } 1142 1143 void VarTemplateSpecializationDecl::setTemplateArgsInfo( 1144 const TemplateArgumentListInfo &ArgsInfo) { 1145 unsigned N = ArgsInfo.size(); 1146 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc()); 1147 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc()); 1148 for (unsigned I = 0; I != N; ++I) 1149 TemplateArgsInfo.addArgument(ArgsInfo[I]); 1150 } 1151 1152 //===----------------------------------------------------------------------===// 1153 // VarTemplatePartialSpecializationDecl Implementation 1154 //===----------------------------------------------------------------------===// 1155 void VarTemplatePartialSpecializationDecl::anchor() {} 1156 1157 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1158 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1159 SourceLocation IdLoc, TemplateParameterList *Params, 1160 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1161 StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 1162 const ASTTemplateArgumentListInfo *ArgInfos) 1163 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, 1164 DC, StartLoc, IdLoc, SpecializedTemplate, T, 1165 TInfo, S, Args, NumArgs), 1166 TemplateParams(Params), ArgsAsWritten(ArgInfos), 1167 InstantiatedFromMember(nullptr, false) { 1168 // TODO: The template parameters should be in DC by now. Verify. 1169 // AdoptTemplateParameterList(Params, DC); 1170 } 1171 1172 VarTemplatePartialSpecializationDecl * 1173 VarTemplatePartialSpecializationDecl::Create( 1174 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1175 SourceLocation IdLoc, TemplateParameterList *Params, 1176 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1177 StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 1178 const TemplateArgumentListInfo &ArgInfos) { 1179 const ASTTemplateArgumentListInfo *ASTArgInfos 1180 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 1181 1182 VarTemplatePartialSpecializationDecl *Result = 1183 new (Context, DC) VarTemplatePartialSpecializationDecl( 1184 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, 1185 S, Args, NumArgs, ASTArgInfos); 1186 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1187 return Result; 1188 } 1189 1190 VarTemplatePartialSpecializationDecl * 1191 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1192 unsigned ID) { 1193 return new (C, ID) VarTemplatePartialSpecializationDecl(C); 1194 } 1195 1196 static TemplateParameterList * 1197 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) { 1198 // typename T 1199 auto *T = TemplateTypeParmDecl::Create( 1200 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0, 1201 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); 1202 T->setImplicit(true); 1203 1204 // T ...Ints 1205 TypeSourceInfo *TI = 1206 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0)); 1207 auto *N = NonTypeTemplateParmDecl::Create( 1208 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1209 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI); 1210 N->setImplicit(true); 1211 1212 // <typename T, T ...Ints> 1213 NamedDecl *P[2] = {T, N}; 1214 auto *TPL = TemplateParameterList::Create( 1215 C, SourceLocation(), SourceLocation(), P, 2, SourceLocation()); 1216 1217 // template <typename T, ...Ints> class IntSeq 1218 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create( 1219 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0, 1220 /*ParameterPack=*/false, /*Id=*/nullptr, TPL); 1221 TemplateTemplateParm->setImplicit(true); 1222 1223 // typename T 1224 auto *TemplateTypeParm = TemplateTypeParmDecl::Create( 1225 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1226 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); 1227 TemplateTypeParm->setImplicit(true); 1228 1229 // T N 1230 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo( 1231 QualType(TemplateTypeParm->getTypeForDecl(), 0)); 1232 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create( 1233 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2, 1234 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1235 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm, 1236 NonTypeTemplateParm}; 1237 1238 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N> 1239 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1240 Params, 3, SourceLocation()); 1241 } 1242 1243 static TemplateParameterList *createBuiltinTemplateParameterList( 1244 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) { 1245 switch (BTK) { 1246 case BTK__make_integer_seq: 1247 return createMakeIntegerSeqParameterList(C, DC); 1248 } 1249 1250 llvm_unreachable("unhandled BuiltinTemplateKind!"); 1251 } 1252 1253 void BuiltinTemplateDecl::anchor() {} 1254 1255 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC, 1256 DeclarationName Name, 1257 BuiltinTemplateKind BTK) 1258 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name, 1259 createBuiltinTemplateParameterList(C, DC, BTK)), 1260 BTK(BTK) {} 1261