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