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