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