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