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