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 // Walk the previous-declaration chain until we either find a declaration 134 // with a common pointer or we run out of previous declarations. 135 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls; 136 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev; 137 Prev = Prev->getPreviousDecl()) { 138 if (Prev->Common) { 139 Common = Prev->Common; 140 break; 141 } 142 143 PrevDecls.push_back(Prev); 144 } 145 146 // If we never found a common pointer, allocate one now. 147 if (!Common) { 148 // FIXME: If any of the declarations is from an AST file, we probably 149 // need an update record to add the common data. 150 151 Common = newCommon(getASTContext()); 152 } 153 154 // Update any previous declarations we saw with the common pointer. 155 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I) 156 PrevDecls[I]->Common = Common; 157 } 158 159 return Common; 160 } 161 162 template <class EntryType> 163 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType* 164 RedeclarableTemplateDecl::findSpecializationImpl( 165 llvm::FoldingSetVector<EntryType> &Specs, 166 const TemplateArgument *Args, unsigned NumArgs, 167 void *&InsertPos) { 168 typedef SpecEntryTraits<EntryType> SETraits; 169 llvm::FoldingSetNodeID ID; 170 EntryType::Profile(ID,Args,NumArgs, getASTContext()); 171 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 172 return Entry ? SETraits::getMostRecentDecl(Entry) : 0; 173 } 174 175 /// \brief Generate the injected template arguments for the given template 176 /// parameter list, e.g., for the injected-class-name of a class template. 177 static void GenerateInjectedTemplateArgs(ASTContext &Context, 178 TemplateParameterList *Params, 179 TemplateArgument *Args) { 180 for (TemplateParameterList::iterator Param = Params->begin(), 181 ParamEnd = Params->end(); 182 Param != ParamEnd; ++Param) { 183 TemplateArgument Arg; 184 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { 185 QualType ArgType = Context.getTypeDeclType(TTP); 186 if (TTP->isParameterPack()) 187 ArgType = Context.getPackExpansionType(ArgType, None); 188 189 Arg = TemplateArgument(ArgType); 190 } else if (NonTypeTemplateParmDecl *NTTP = 191 dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 192 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false, 193 NTTP->getType().getNonLValueExprType(Context), 194 Expr::getValueKindForType(NTTP->getType()), 195 NTTP->getLocation()); 196 197 if (NTTP->isParameterPack()) 198 E = new (Context) PackExpansionExpr(Context.DependentTy, E, 199 NTTP->getLocation(), None); 200 Arg = TemplateArgument(E); 201 } else { 202 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 203 if (TTP->isParameterPack()) 204 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>()); 205 else 206 Arg = TemplateArgument(TemplateName(TTP)); 207 } 208 209 if ((*Param)->isTemplateParameterPack()) 210 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1); 211 212 *Args++ = Arg; 213 } 214 } 215 216 //===----------------------------------------------------------------------===// 217 // FunctionTemplateDecl Implementation 218 //===----------------------------------------------------------------------===// 219 220 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) { 221 static_cast<Common *>(Ptr)->~Common(); 222 } 223 224 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 225 DeclContext *DC, 226 SourceLocation L, 227 DeclarationName Name, 228 TemplateParameterList *Params, 229 NamedDecl *Decl) { 230 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 231 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl); 232 } 233 234 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, 235 unsigned ID) { 236 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl)); 237 return new (Mem) 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 = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl); 311 New->setPreviousDeclaration(PrevDecl); 312 return New; 313 } 314 315 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 316 unsigned ID) { 317 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl)); 318 return new (Mem) 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) 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 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl)); 482 return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(), 483 0, false); 484 } 485 486 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 487 return hasDefaultArgument() 488 ? DefaultArgument->getTypeLoc().getBeginLoc() 489 : SourceLocation(); 490 } 491 492 SourceRange TemplateTypeParmDecl::getSourceRange() const { 493 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 494 return SourceRange(getLocStart(), 495 DefaultArgument->getTypeLoc().getEndLoc()); 496 else 497 return TypeDecl::getSourceRange(); 498 } 499 500 unsigned TemplateTypeParmDecl::getDepth() const { 501 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth(); 502 } 503 504 unsigned TemplateTypeParmDecl::getIndex() const { 505 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex(); 506 } 507 508 bool TemplateTypeParmDecl::isParameterPack() const { 509 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack(); 510 } 511 512 //===----------------------------------------------------------------------===// 513 // NonTypeTemplateParmDecl Method Implementations 514 //===----------------------------------------------------------------------===// 515 516 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 517 SourceLocation StartLoc, 518 SourceLocation IdLoc, 519 unsigned D, unsigned P, 520 IdentifierInfo *Id, 521 QualType T, 522 TypeSourceInfo *TInfo, 523 const QualType *ExpandedTypes, 524 unsigned NumExpandedTypes, 525 TypeSourceInfo **ExpandedTInfos) 526 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 527 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false), 528 ParameterPack(true), ExpandedParameterPack(true), 529 NumExpandedTypes(NumExpandedTypes) 530 { 531 if (ExpandedTypes && ExpandedTInfos) { 532 void **TypesAndInfos = reinterpret_cast<void **>(this + 1); 533 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 534 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr(); 535 TypesAndInfos[2*I + 1] = ExpandedTInfos[I]; 536 } 537 } 538 } 539 540 NonTypeTemplateParmDecl * 541 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 542 SourceLocation StartLoc, SourceLocation IdLoc, 543 unsigned D, unsigned P, IdentifierInfo *Id, 544 QualType T, bool ParameterPack, 545 TypeSourceInfo *TInfo) { 546 return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 547 T, ParameterPack, TInfo); 548 } 549 550 NonTypeTemplateParmDecl * 551 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 552 SourceLocation StartLoc, SourceLocation IdLoc, 553 unsigned D, unsigned P, 554 IdentifierInfo *Id, QualType T, 555 TypeSourceInfo *TInfo, 556 const QualType *ExpandedTypes, 557 unsigned NumExpandedTypes, 558 TypeSourceInfo **ExpandedTInfos) { 559 unsigned Size = sizeof(NonTypeTemplateParmDecl) 560 + NumExpandedTypes * 2 * sizeof(void*); 561 void *Mem = C.Allocate(Size); 562 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, 563 D, P, Id, T, TInfo, 564 ExpandedTypes, NumExpandedTypes, 565 ExpandedTInfos); 566 } 567 568 NonTypeTemplateParmDecl * 569 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 570 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl)); 571 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 572 SourceLocation(), 0, 0, 0, 573 QualType(), false, 0); 574 } 575 576 NonTypeTemplateParmDecl * 577 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 578 unsigned NumExpandedTypes) { 579 unsigned Size = sizeof(NonTypeTemplateParmDecl) 580 + NumExpandedTypes * 2 * sizeof(void*); 581 582 void *Mem = AllocateDeserializedDecl(C, ID, Size); 583 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 584 SourceLocation(), 0, 0, 0, 585 QualType(), 0, 0, NumExpandedTypes, 586 0); 587 } 588 589 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 590 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 591 return SourceRange(getOuterLocStart(), 592 getDefaultArgument()->getSourceRange().getEnd()); 593 return DeclaratorDecl::getSourceRange(); 594 } 595 596 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 597 return hasDefaultArgument() 598 ? getDefaultArgument()->getSourceRange().getBegin() 599 : SourceLocation(); 600 } 601 602 //===----------------------------------------------------------------------===// 603 // TemplateTemplateParmDecl Method Implementations 604 //===----------------------------------------------------------------------===// 605 606 void TemplateTemplateParmDecl::anchor() { } 607 608 TemplateTemplateParmDecl::TemplateTemplateParmDecl( 609 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 610 IdentifierInfo *Id, TemplateParameterList *Params, 611 unsigned NumExpansions, TemplateParameterList * const *Expansions) 612 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 613 TemplateParmPosition(D, P), DefaultArgument(), 614 DefaultArgumentWasInherited(false), ParameterPack(true), 615 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) { 616 if (Expansions) 617 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions, 618 sizeof(TemplateParameterList*) * NumExpandedParams); 619 } 620 621 TemplateTemplateParmDecl * 622 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 623 SourceLocation L, unsigned D, unsigned P, 624 bool ParameterPack, IdentifierInfo *Id, 625 TemplateParameterList *Params) { 626 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 627 Params); 628 } 629 630 TemplateTemplateParmDecl * 631 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 632 SourceLocation L, unsigned D, unsigned P, 633 IdentifierInfo *Id, 634 TemplateParameterList *Params, 635 ArrayRef<TemplateParameterList *> Expansions) { 636 void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) + 637 sizeof(TemplateParameterList*) * Expansions.size()); 638 return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params, 639 Expansions.size(), 640 Expansions.data()); 641 } 642 643 TemplateTemplateParmDecl * 644 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 645 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl)); 646 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false, 647 0, 0); 648 } 649 650 TemplateTemplateParmDecl * 651 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 652 unsigned NumExpansions) { 653 unsigned Size = sizeof(TemplateTemplateParmDecl) + 654 sizeof(TemplateParameterList*) * NumExpansions; 655 void *Mem = AllocateDeserializedDecl(C, ID, Size); 656 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0, 657 NumExpansions, 0); 658 } 659 660 //===----------------------------------------------------------------------===// 661 // TemplateArgumentList Implementation 662 //===----------------------------------------------------------------------===// 663 TemplateArgumentList * 664 TemplateArgumentList::CreateCopy(ASTContext &Context, 665 const TemplateArgument *Args, 666 unsigned NumArgs) { 667 std::size_t Size = sizeof(TemplateArgumentList) 668 + NumArgs * sizeof(TemplateArgument); 669 void *Mem = Context.Allocate(Size); 670 TemplateArgument *StoredArgs 671 = reinterpret_cast<TemplateArgument *>( 672 static_cast<TemplateArgumentList *>(Mem) + 1); 673 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs); 674 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true); 675 } 676 677 FunctionTemplateSpecializationInfo * 678 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 679 FunctionTemplateDecl *Template, 680 TemplateSpecializationKind TSK, 681 const TemplateArgumentList *TemplateArgs, 682 const TemplateArgumentListInfo *TemplateArgsAsWritten, 683 SourceLocation POI) { 684 const ASTTemplateArgumentListInfo *ArgsAsWritten = 0; 685 if (TemplateArgsAsWritten) 686 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 687 *TemplateArgsAsWritten); 688 689 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 690 TemplateArgs, 691 ArgsAsWritten, 692 POI); 693 } 694 695 //===----------------------------------------------------------------------===// 696 // TemplateDecl Implementation 697 //===----------------------------------------------------------------------===// 698 699 void TemplateDecl::anchor() { } 700 701 //===----------------------------------------------------------------------===// 702 // ClassTemplateSpecializationDecl Implementation 703 //===----------------------------------------------------------------------===// 704 ClassTemplateSpecializationDecl:: 705 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 706 DeclContext *DC, SourceLocation StartLoc, 707 SourceLocation IdLoc, 708 ClassTemplateDecl *SpecializedTemplate, 709 const TemplateArgument *Args, 710 unsigned NumArgs, 711 ClassTemplateSpecializationDecl *PrevDecl) 712 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc, 713 SpecializedTemplate->getIdentifier(), 714 PrevDecl), 715 SpecializedTemplate(SpecializedTemplate), 716 ExplicitInfo(0), 717 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 718 SpecializationKind(TSK_Undeclared) { 719 } 720 721 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK) 722 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0), 723 ExplicitInfo(0), 724 SpecializationKind(TSK_Undeclared) { 725 } 726 727 ClassTemplateSpecializationDecl * 728 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 729 DeclContext *DC, 730 SourceLocation StartLoc, 731 SourceLocation IdLoc, 732 ClassTemplateDecl *SpecializedTemplate, 733 const TemplateArgument *Args, 734 unsigned NumArgs, 735 ClassTemplateSpecializationDecl *PrevDecl) { 736 ClassTemplateSpecializationDecl *Result 737 = new (Context)ClassTemplateSpecializationDecl(Context, 738 ClassTemplateSpecialization, 739 TK, DC, StartLoc, IdLoc, 740 SpecializedTemplate, 741 Args, NumArgs, 742 PrevDecl); 743 Result->MayHaveOutOfDateDef = false; 744 745 Context.getTypeDeclType(Result, PrevDecl); 746 return Result; 747 } 748 749 ClassTemplateSpecializationDecl * 750 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 751 unsigned ID) { 752 void *Mem = AllocateDeserializedDecl(C, ID, 753 sizeof(ClassTemplateSpecializationDecl)); 754 ClassTemplateSpecializationDecl *Result = 755 new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization); 756 Result->MayHaveOutOfDateDef = false; 757 return Result; 758 } 759 760 void ClassTemplateSpecializationDecl::getNameForDiagnostic( 761 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 762 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 763 764 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 765 TemplateSpecializationType::PrintTemplateArgumentList( 766 OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 767 } 768 769 ClassTemplateDecl * 770 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 771 if (SpecializedPartialSpecialization *PartialSpec 772 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 773 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 774 return SpecializedTemplate.get<ClassTemplateDecl*>(); 775 } 776 777 SourceRange 778 ClassTemplateSpecializationDecl::getSourceRange() const { 779 if (ExplicitInfo) { 780 SourceLocation Begin = getTemplateKeywordLoc(); 781 if (Begin.isValid()) { 782 // Here we have an explicit (partial) specialization or instantiation. 783 assert(getSpecializationKind() == TSK_ExplicitSpecialization || 784 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || 785 getSpecializationKind() == TSK_ExplicitInstantiationDefinition); 786 if (getExternLoc().isValid()) 787 Begin = getExternLoc(); 788 SourceLocation End = getRBraceLoc(); 789 if (End.isInvalid()) 790 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 791 return SourceRange(Begin, End); 792 } 793 // An implicit instantiation of a class template partial specialization 794 // uses ExplicitInfo to record the TypeAsWritten, but the source 795 // locations should be retrieved from the instantiation pattern. 796 typedef ClassTemplatePartialSpecializationDecl CTPSDecl; 797 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this)); 798 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); 799 assert(inst_from != 0); 800 return inst_from->getSourceRange(); 801 } 802 else { 803 // No explicit info available. 804 llvm::PointerUnion<ClassTemplateDecl *, 805 ClassTemplatePartialSpecializationDecl *> 806 inst_from = getInstantiatedFrom(); 807 if (inst_from.isNull()) 808 return getSpecializedTemplate()->getSourceRange(); 809 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>()) 810 return ctd->getSourceRange(); 811 return inst_from.get<ClassTemplatePartialSpecializationDecl*>() 812 ->getSourceRange(); 813 } 814 } 815 816 //===----------------------------------------------------------------------===// 817 // ClassTemplatePartialSpecializationDecl Implementation 818 //===----------------------------------------------------------------------===// 819 void ClassTemplatePartialSpecializationDecl::anchor() { } 820 821 ClassTemplatePartialSpecializationDecl:: 822 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 823 DeclContext *DC, 824 SourceLocation StartLoc, 825 SourceLocation IdLoc, 826 TemplateParameterList *Params, 827 ClassTemplateDecl *SpecializedTemplate, 828 const TemplateArgument *Args, 829 unsigned NumArgs, 830 const ASTTemplateArgumentListInfo *ArgInfos, 831 ClassTemplatePartialSpecializationDecl *PrevDecl) 832 : ClassTemplateSpecializationDecl(Context, 833 ClassTemplatePartialSpecialization, 834 TK, DC, StartLoc, IdLoc, 835 SpecializedTemplate, 836 Args, NumArgs, PrevDecl), 837 TemplateParams(Params), ArgsAsWritten(ArgInfos), 838 InstantiatedFromMember(0, false) 839 { 840 AdoptTemplateParameterList(Params, this); 841 } 842 843 ClassTemplatePartialSpecializationDecl * 844 ClassTemplatePartialSpecializationDecl:: 845 Create(ASTContext &Context, TagKind TK,DeclContext *DC, 846 SourceLocation StartLoc, SourceLocation IdLoc, 847 TemplateParameterList *Params, 848 ClassTemplateDecl *SpecializedTemplate, 849 const TemplateArgument *Args, 850 unsigned NumArgs, 851 const TemplateArgumentListInfo &ArgInfos, 852 QualType CanonInjectedType, 853 ClassTemplatePartialSpecializationDecl *PrevDecl) { 854 const ASTTemplateArgumentListInfo *ASTArgInfos = 855 ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 856 857 ClassTemplatePartialSpecializationDecl *Result 858 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC, 859 StartLoc, IdLoc, 860 Params, 861 SpecializedTemplate, 862 Args, NumArgs, 863 ASTArgInfos, 864 PrevDecl); 865 Result->setSpecializationKind(TSK_ExplicitSpecialization); 866 Result->MayHaveOutOfDateDef = false; 867 868 Context.getInjectedClassNameType(Result, CanonInjectedType); 869 return Result; 870 } 871 872 ClassTemplatePartialSpecializationDecl * 873 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 874 unsigned ID) { 875 void *Mem = AllocateDeserializedDecl(C, ID, 876 sizeof(ClassTemplatePartialSpecializationDecl)); 877 ClassTemplatePartialSpecializationDecl *Result 878 = new (Mem) ClassTemplatePartialSpecializationDecl(); 879 Result->MayHaveOutOfDateDef = false; 880 return Result; 881 } 882 883 //===----------------------------------------------------------------------===// 884 // FriendTemplateDecl Implementation 885 //===----------------------------------------------------------------------===// 886 887 void FriendTemplateDecl::anchor() { } 888 889 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 890 DeclContext *DC, 891 SourceLocation L, 892 unsigned NParams, 893 TemplateParameterList **Params, 894 FriendUnion Friend, 895 SourceLocation FLoc) { 896 FriendTemplateDecl *Result 897 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc); 898 return Result; 899 } 900 901 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 902 unsigned ID) { 903 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl)); 904 return new (Mem) FriendTemplateDecl(EmptyShell()); 905 } 906 907 //===----------------------------------------------------------------------===// 908 // TypeAliasTemplateDecl Implementation 909 //===----------------------------------------------------------------------===// 910 911 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 912 DeclContext *DC, 913 SourceLocation L, 914 DeclarationName Name, 915 TemplateParameterList *Params, 916 NamedDecl *Decl) { 917 AdoptTemplateParameterList(Params, DC); 918 return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl); 919 } 920 921 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 922 unsigned ID) { 923 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl)); 924 return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(), 925 0, 0); 926 } 927 928 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) { 929 static_cast<Common *>(Ptr)->~Common(); 930 } 931 RedeclarableTemplateDecl::CommonBase * 932 TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 933 Common *CommonPtr = new (C) Common; 934 C.AddDeallocation(DeallocateCommon, CommonPtr); 935 return CommonPtr; 936 } 937 938 //===----------------------------------------------------------------------===// 939 // ClassScopeFunctionSpecializationDecl Implementation 940 //===----------------------------------------------------------------------===// 941 942 void ClassScopeFunctionSpecializationDecl::anchor() { } 943 944 ClassScopeFunctionSpecializationDecl * 945 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 946 unsigned ID) { 947 void *Mem = AllocateDeserializedDecl(C, ID, 948 sizeof(ClassScopeFunctionSpecializationDecl)); 949 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0, 950 false, TemplateArgumentListInfo()); 951 } 952 953 //===----------------------------------------------------------------------===// 954 // VarTemplateDecl Implementation 955 //===----------------------------------------------------------------------===// 956 957 void VarTemplateDecl::DeallocateCommon(void *Ptr) { 958 static_cast<Common *>(Ptr)->~Common(); 959 } 960 961 VarTemplateDecl *VarTemplateDecl::getDefinition() { 962 VarTemplateDecl *CurD = this; 963 while (CurD) { 964 if (CurD->isThisDeclarationADefinition()) 965 return CurD; 966 CurD = CurD->getPreviousDecl(); 967 } 968 return 0; 969 } 970 971 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 972 SourceLocation L, DeclarationName Name, 973 TemplateParameterList *Params, 974 NamedDecl *Decl, 975 VarTemplateDecl *PrevDecl) { 976 VarTemplateDecl *New = new (C) VarTemplateDecl(DC, L, Name, Params, Decl); 977 New->setPreviousDeclaration(PrevDecl); 978 return New; 979 } 980 981 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 982 unsigned ID) { 983 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarTemplateDecl)); 984 return new (Mem) VarTemplateDecl(EmptyShell()); 985 } 986 987 // TODO: Unify accross class, function and variable templates? 988 // May require moving this and Common to RedeclarableTemplateDecl. 989 void VarTemplateDecl::LoadLazySpecializations() const { 990 Common *CommonPtr = getCommonPtr(); 991 if (CommonPtr->LazySpecializations) { 992 ASTContext &Context = getASTContext(); 993 uint32_t *Specs = CommonPtr->LazySpecializations; 994 CommonPtr->LazySpecializations = 0; 995 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 996 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 997 } 998 } 999 1000 llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 1001 VarTemplateDecl::getSpecializations() const { 1002 LoadLazySpecializations(); 1003 return getCommonPtr()->Specializations; 1004 } 1005 1006 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 1007 VarTemplateDecl::getPartialSpecializations() { 1008 LoadLazySpecializations(); 1009 return getCommonPtr()->PartialSpecializations; 1010 } 1011 1012 RedeclarableTemplateDecl::CommonBase * 1013 VarTemplateDecl::newCommon(ASTContext &C) const { 1014 Common *CommonPtr = new (C) Common; 1015 C.AddDeallocation(DeallocateCommon, CommonPtr); 1016 return CommonPtr; 1017 } 1018 1019 VarTemplateSpecializationDecl * 1020 VarTemplateDecl::findSpecialization(const TemplateArgument *Args, 1021 unsigned NumArgs, void *&InsertPos) { 1022 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 1023 } 1024 1025 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 1026 void *InsertPos) { 1027 if (InsertPos) 1028 getSpecializations().InsertNode(D, InsertPos); 1029 else { 1030 VarTemplateSpecializationDecl *Existing = 1031 getSpecializations().GetOrInsertNode(D); 1032 (void)Existing; 1033 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1034 } 1035 if (ASTMutationListener *L = getASTMutationListener()) 1036 L->AddedCXXTemplateSpecialization(this, D); 1037 } 1038 1039 VarTemplatePartialSpecializationDecl * 1040 VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, 1041 unsigned NumArgs, void *&InsertPos) { 1042 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs, 1043 InsertPos); 1044 } 1045 1046 void VarTemplateDecl::AddPartialSpecialization( 1047 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 1048 if (InsertPos) 1049 getPartialSpecializations().InsertNode(D, InsertPos); 1050 else { 1051 VarTemplatePartialSpecializationDecl *Existing = 1052 getPartialSpecializations().GetOrInsertNode(D); 1053 (void)Existing; 1054 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1055 } 1056 1057 if (ASTMutationListener *L = getASTMutationListener()) 1058 L->AddedCXXTemplateSpecialization(this, D); 1059 } 1060 1061 void VarTemplateDecl::getPartialSpecializations( 1062 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) { 1063 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 1064 getPartialSpecializations(); 1065 PS.clear(); 1066 PS.reserve(PartialSpecs.size()); 1067 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 1068 P = PartialSpecs.begin(), 1069 PEnd = PartialSpecs.end(); 1070 P != PEnd; ++P) 1071 PS.push_back(P->getMostRecentDecl()); 1072 } 1073 1074 VarTemplatePartialSpecializationDecl * 1075 VarTemplateDecl::findPartialSpecInstantiatedFromMember( 1076 VarTemplatePartialSpecializationDecl *D) { 1077 Decl *DCanon = D->getCanonicalDecl(); 1078 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 1079 P = getPartialSpecializations().begin(), 1080 PEnd = getPartialSpecializations().end(); 1081 P != PEnd; ++P) { 1082 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1083 return P->getMostRecentDecl(); 1084 } 1085 1086 return 0; 1087 } 1088 1089 //===----------------------------------------------------------------------===// 1090 // VarTemplateSpecializationDecl Implementation 1091 //===----------------------------------------------------------------------===// 1092 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1093 ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc, 1094 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1095 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 1096 unsigned NumArgs) 1097 : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T, 1098 TInfo, S), 1099 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0), 1100 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 1101 SpecializationKind(TSK_Undeclared) {} 1102 1103 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK) 1104 : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0, 1105 SC_None), 1106 ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {} 1107 1108 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1109 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1110 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1111 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 1112 unsigned NumArgs) { 1113 VarTemplateSpecializationDecl *Result = new (Context) 1114 VarTemplateSpecializationDecl(Context, VarTemplateSpecialization, DC, 1115 StartLoc, IdLoc, SpecializedTemplate, T, 1116 TInfo, S, Args, NumArgs); 1117 return Result; 1118 } 1119 1120 VarTemplateSpecializationDecl * 1121 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1122 void *Mem = 1123 AllocateDeserializedDecl(C, ID, sizeof(VarTemplateSpecializationDecl)); 1124 VarTemplateSpecializationDecl *Result = 1125 new (Mem) VarTemplateSpecializationDecl(VarTemplateSpecialization); 1126 return Result; 1127 } 1128 1129 void VarTemplateSpecializationDecl::getNameForDiagnostic( 1130 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1131 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1132 1133 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1134 TemplateSpecializationType::PrintTemplateArgumentList( 1135 OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 1136 } 1137 1138 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1139 if (SpecializedPartialSpecialization *PartialSpec = 1140 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1141 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1142 return SpecializedTemplate.get<VarTemplateDecl *>(); 1143 } 1144 1145 void VarTemplateSpecializationDecl::setTemplateArgsInfo( 1146 const TemplateArgumentListInfo &ArgsInfo) { 1147 unsigned N = ArgsInfo.size(); 1148 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc()); 1149 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc()); 1150 for (unsigned I = 0; I != N; ++I) 1151 TemplateArgsInfo.addArgument(ArgsInfo[I]); 1152 } 1153 1154 //===----------------------------------------------------------------------===// 1155 // VarTemplatePartialSpecializationDecl Implementation 1156 //===----------------------------------------------------------------------===// 1157 void VarTemplatePartialSpecializationDecl::anchor() {} 1158 1159 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1160 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1161 SourceLocation IdLoc, TemplateParameterList *Params, 1162 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1163 StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 1164 const ASTTemplateArgumentListInfo *ArgInfos) 1165 : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization, 1166 DC, StartLoc, IdLoc, SpecializedTemplate, T, 1167 TInfo, S, Args, NumArgs), 1168 TemplateParams(Params), ArgsAsWritten(ArgInfos), 1169 InstantiatedFromMember(0, false) { 1170 // TODO: The template parameters should be in DC by now. Verify. 1171 // AdoptTemplateParameterList(Params, DC); 1172 } 1173 1174 VarTemplatePartialSpecializationDecl * 1175 VarTemplatePartialSpecializationDecl::Create( 1176 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1177 SourceLocation IdLoc, TemplateParameterList *Params, 1178 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1179 StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 1180 const TemplateArgumentListInfo &ArgInfos) { 1181 const ASTTemplateArgumentListInfo *ASTArgInfos 1182 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 1183 1184 VarTemplatePartialSpecializationDecl *Result = 1185 new (Context) VarTemplatePartialSpecializationDecl( 1186 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, 1187 S, Args, NumArgs, ASTArgInfos); 1188 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1189 return Result; 1190 } 1191 1192 VarTemplatePartialSpecializationDecl * 1193 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1194 unsigned ID) { 1195 void *Mem = AllocateDeserializedDecl( 1196 C, ID, sizeof(VarTemplatePartialSpecializationDecl)); 1197 VarTemplatePartialSpecializationDecl *Result = 1198 new (Mem) VarTemplatePartialSpecializationDecl(); 1199 return Result; 1200 } 1201