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