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