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/DeclCXX.h" 15 #include "clang/AST/DeclTemplate.h" 16 #include "clang/AST/Expr.h" 17 #include "clang/AST/ExprCXX.h" 18 #include "clang/AST/ASTContext.h" 19 #include "clang/AST/TypeLoc.h" 20 #include "clang/AST/ASTMutationListener.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) { 36 for (unsigned Idx = 0; Idx < NumParams; ++Idx) 37 begin()[Idx] = Params[Idx]; 38 } 39 40 TemplateParameterList * 41 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, 42 SourceLocation LAngleLoc, NamedDecl **Params, 43 unsigned NumParams, SourceLocation RAngleLoc) { 44 unsigned Size = sizeof(TemplateParameterList) 45 + sizeof(NamedDecl *) * NumParams; 46 unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(), 47 llvm::alignOf<NamedDecl*>()); 48 void *Mem = C.Allocate(Size, Align); 49 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, 50 NumParams, RAngleLoc); 51 } 52 53 unsigned TemplateParameterList::getMinRequiredArguments() const { 54 unsigned NumRequiredArgs = 0; 55 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(), 56 PEnd = const_cast<TemplateParameterList *>(this)->end(); 57 P != PEnd; ++P) { 58 if ((*P)->isTemplateParameterPack()) { 59 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) 60 if (NTTP->isExpandedParameterPack()) { 61 NumRequiredArgs += NTTP->getNumExpansionTypes(); 62 continue; 63 } 64 65 break; 66 } 67 68 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { 69 if (TTP->hasDefaultArgument()) 70 break; 71 } else if (NonTypeTemplateParmDecl *NTTP 72 = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 73 if (NTTP->hasDefaultArgument()) 74 break; 75 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument()) 76 break; 77 78 ++NumRequiredArgs; 79 } 80 81 return NumRequiredArgs; 82 } 83 84 unsigned TemplateParameterList::getDepth() const { 85 if (size() == 0) 86 return 0; 87 88 const NamedDecl *FirstParm = getParam(0); 89 if (const TemplateTypeParmDecl *TTP 90 = dyn_cast<TemplateTypeParmDecl>(FirstParm)) 91 return TTP->getDepth(); 92 else if (const NonTypeTemplateParmDecl *NTTP 93 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm)) 94 return NTTP->getDepth(); 95 else 96 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth(); 97 } 98 99 static void AdoptTemplateParameterList(TemplateParameterList *Params, 100 DeclContext *Owner) { 101 for (TemplateParameterList::iterator P = Params->begin(), 102 PEnd = Params->end(); 103 P != PEnd; ++P) { 104 (*P)->setDeclContext(Owner); 105 106 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P)) 107 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner); 108 } 109 } 110 111 //===----------------------------------------------------------------------===// 112 // RedeclarableTemplateDecl Implementation 113 //===----------------------------------------------------------------------===// 114 115 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() { 116 if (!Common) { 117 // Walk the previous-declaration chain until we either find a declaration 118 // with a common pointer or we run out of previous declarations. 119 llvm::SmallVector<RedeclarableTemplateDecl *, 2> PrevDecls; 120 for (RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev; 121 Prev = Prev->getPreviousDecl()) { 122 if (Prev->Common) { 123 Common = Prev->Common; 124 break; 125 } 126 127 PrevDecls.push_back(Prev); 128 } 129 130 // If we never found a common pointer, allocate one now. 131 if (!Common) { 132 // FIXME: If any of the declarations is from an AST file, we probably 133 // need an update record to add the common data. 134 135 Common = newCommon(getASTContext()); 136 } 137 138 // Update any previous declarations we saw with the common pointer. 139 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I) 140 PrevDecls[I]->Common = Common; 141 } 142 143 return Common; 144 } 145 146 template <class EntryType> 147 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType* 148 RedeclarableTemplateDecl::findSpecializationImpl( 149 llvm::FoldingSetVector<EntryType> &Specs, 150 const TemplateArgument *Args, unsigned NumArgs, 151 void *&InsertPos) { 152 typedef SpecEntryTraits<EntryType> SETraits; 153 llvm::FoldingSetNodeID ID; 154 EntryType::Profile(ID,Args,NumArgs, getASTContext()); 155 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 156 return Entry ? SETraits::getMostRecentDecl(Entry) : 0; 157 } 158 159 /// \brief Generate the injected template arguments for the given template 160 /// parameter list, e.g., for the injected-class-name of a class template. 161 static void GenerateInjectedTemplateArgs(ASTContext &Context, 162 TemplateParameterList *Params, 163 TemplateArgument *Args) { 164 for (TemplateParameterList::iterator Param = Params->begin(), 165 ParamEnd = Params->end(); 166 Param != ParamEnd; ++Param) { 167 TemplateArgument Arg; 168 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { 169 QualType ArgType = Context.getTypeDeclType(TTP); 170 if (TTP->isParameterPack()) 171 ArgType = Context.getPackExpansionType(ArgType, 172 llvm::Optional<unsigned>()); 173 174 Arg = TemplateArgument(ArgType); 175 } else if (NonTypeTemplateParmDecl *NTTP = 176 dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 177 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false, 178 NTTP->getType().getNonLValueExprType(Context), 179 Expr::getValueKindForType(NTTP->getType()), 180 NTTP->getLocation()); 181 182 if (NTTP->isParameterPack()) 183 E = new (Context) PackExpansionExpr(Context.DependentTy, E, 184 NTTP->getLocation(), 185 llvm::Optional<unsigned>()); 186 Arg = TemplateArgument(E); 187 } else { 188 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 189 if (TTP->isParameterPack()) 190 Arg = TemplateArgument(TemplateName(TTP), llvm::Optional<unsigned>()); 191 else 192 Arg = TemplateArgument(TemplateName(TTP)); 193 } 194 195 if ((*Param)->isTemplateParameterPack()) 196 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1); 197 198 *Args++ = Arg; 199 } 200 } 201 202 //===----------------------------------------------------------------------===// 203 // FunctionTemplateDecl Implementation 204 //===----------------------------------------------------------------------===// 205 206 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) { 207 static_cast<Common *>(Ptr)->~Common(); 208 } 209 210 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 211 DeclContext *DC, 212 SourceLocation L, 213 DeclarationName Name, 214 TemplateParameterList *Params, 215 NamedDecl *Decl) { 216 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 217 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl); 218 } 219 220 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, 221 unsigned ID) { 222 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl)); 223 return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(), 224 0, 0); 225 } 226 227 RedeclarableTemplateDecl::CommonBase * 228 FunctionTemplateDecl::newCommon(ASTContext &C) { 229 Common *CommonPtr = new (C) Common; 230 C.AddDeallocation(DeallocateCommon, CommonPtr); 231 return CommonPtr; 232 } 233 234 FunctionDecl * 235 FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args, 236 unsigned NumArgs, void *&InsertPos) { 237 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 238 } 239 240 void FunctionTemplateDecl::addSpecialization( 241 FunctionTemplateSpecializationInfo *Info, void *InsertPos) { 242 if (InsertPos) 243 getSpecializations().InsertNode(Info, InsertPos); 244 else 245 getSpecializations().GetOrInsertNode(Info); 246 if (ASTMutationListener *L = getASTMutationListener()) 247 L->AddedCXXTemplateSpecialization(this, Info->Function); 248 } 249 250 std::pair<const TemplateArgument *, unsigned> 251 FunctionTemplateDecl::getInjectedTemplateArgs() { 252 TemplateParameterList *Params = getTemplateParameters(); 253 Common *CommonPtr = getCommonPtr(); 254 if (!CommonPtr->InjectedArgs) { 255 CommonPtr->InjectedArgs 256 = new (getASTContext()) TemplateArgument [Params->size()]; 257 GenerateInjectedTemplateArgs(getASTContext(), Params, 258 CommonPtr->InjectedArgs); 259 } 260 261 return std::make_pair(CommonPtr->InjectedArgs, Params->size()); 262 } 263 264 //===----------------------------------------------------------------------===// 265 // ClassTemplateDecl Implementation 266 //===----------------------------------------------------------------------===// 267 268 void ClassTemplateDecl::DeallocateCommon(void *Ptr) { 269 static_cast<Common *>(Ptr)->~Common(); 270 } 271 272 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 273 DeclContext *DC, 274 SourceLocation L, 275 DeclarationName Name, 276 TemplateParameterList *Params, 277 NamedDecl *Decl, 278 ClassTemplateDecl *PrevDecl) { 279 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 280 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl); 281 New->setPreviousDeclaration(PrevDecl); 282 return New; 283 } 284 285 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 286 unsigned ID) { 287 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl)); 288 return new (Mem) ClassTemplateDecl(EmptyShell()); 289 } 290 291 void ClassTemplateDecl::LoadLazySpecializations() { 292 Common *CommonPtr = getCommonPtr(); 293 if (CommonPtr->LazySpecializations) { 294 ASTContext &Context = getASTContext(); 295 uint32_t *Specs = CommonPtr->LazySpecializations; 296 CommonPtr->LazySpecializations = 0; 297 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 298 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 299 } 300 } 301 302 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 303 ClassTemplateDecl::getSpecializations() { 304 LoadLazySpecializations(); 305 return getCommonPtr()->Specializations; 306 } 307 308 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 309 ClassTemplateDecl::getPartialSpecializations() { 310 LoadLazySpecializations(); 311 return getCommonPtr()->PartialSpecializations; 312 } 313 314 RedeclarableTemplateDecl::CommonBase * 315 ClassTemplateDecl::newCommon(ASTContext &C) { 316 Common *CommonPtr = new (C) Common; 317 C.AddDeallocation(DeallocateCommon, CommonPtr); 318 return CommonPtr; 319 } 320 321 ClassTemplateSpecializationDecl * 322 ClassTemplateDecl::findSpecialization(const TemplateArgument *Args, 323 unsigned NumArgs, void *&InsertPos) { 324 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 325 } 326 327 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 328 void *InsertPos) { 329 if (InsertPos) 330 getSpecializations().InsertNode(D, InsertPos); 331 else { 332 ClassTemplateSpecializationDecl *Existing 333 = getSpecializations().GetOrInsertNode(D); 334 (void)Existing; 335 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 336 } 337 if (ASTMutationListener *L = getASTMutationListener()) 338 L->AddedCXXTemplateSpecialization(this, D); 339 } 340 341 ClassTemplatePartialSpecializationDecl * 342 ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, 343 unsigned NumArgs, 344 void *&InsertPos) { 345 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs, 346 InsertPos); 347 } 348 349 void ClassTemplateDecl::AddPartialSpecialization( 350 ClassTemplatePartialSpecializationDecl *D, 351 void *InsertPos) { 352 if (InsertPos) 353 getPartialSpecializations().InsertNode(D, InsertPos); 354 else { 355 ClassTemplatePartialSpecializationDecl *Existing 356 = getPartialSpecializations().GetOrInsertNode(D); 357 (void)Existing; 358 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 359 } 360 361 if (ASTMutationListener *L = getASTMutationListener()) 362 L->AddedCXXTemplateSpecialization(this, D); 363 } 364 365 void ClassTemplateDecl::getPartialSpecializations( 366 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) { 367 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs 368 = getPartialSpecializations(); 369 PS.clear(); 370 PS.resize(PartialSpecs.size()); 371 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 372 P = PartialSpecs.begin(), PEnd = PartialSpecs.end(); 373 P != PEnd; ++P) { 374 assert(!PS[P->getSequenceNumber()]); 375 PS[P->getSequenceNumber()] = P->getMostRecentDecl(); 376 } 377 } 378 379 ClassTemplatePartialSpecializationDecl * 380 ClassTemplateDecl::findPartialSpecialization(QualType T) { 381 ASTContext &Context = getASTContext(); 382 using llvm::FoldingSetVector; 383 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 384 partial_spec_iterator; 385 for (partial_spec_iterator P = getPartialSpecializations().begin(), 386 PEnd = getPartialSpecializations().end(); 387 P != PEnd; ++P) { 388 if (Context.hasSameType(P->getInjectedSpecializationType(), T)) 389 return P->getMostRecentDecl(); 390 } 391 392 return 0; 393 } 394 395 ClassTemplatePartialSpecializationDecl * 396 ClassTemplateDecl::findPartialSpecInstantiatedFromMember( 397 ClassTemplatePartialSpecializationDecl *D) { 398 Decl *DCanon = D->getCanonicalDecl(); 399 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 400 P = getPartialSpecializations().begin(), 401 PEnd = getPartialSpecializations().end(); 402 P != PEnd; ++P) { 403 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 404 return P->getMostRecentDecl(); 405 } 406 407 return 0; 408 } 409 410 QualType 411 ClassTemplateDecl::getInjectedClassNameSpecialization() { 412 Common *CommonPtr = getCommonPtr(); 413 if (!CommonPtr->InjectedClassNameType.isNull()) 414 return CommonPtr->InjectedClassNameType; 415 416 // C++0x [temp.dep.type]p2: 417 // The template argument list of a primary template is a template argument 418 // list in which the nth template argument has the value of the nth template 419 // parameter of the class template. If the nth template parameter is a 420 // template parameter pack (14.5.3), the nth template argument is a pack 421 // expansion (14.5.3) whose pattern is the name of the template parameter 422 // pack. 423 ASTContext &Context = getASTContext(); 424 TemplateParameterList *Params = getTemplateParameters(); 425 SmallVector<TemplateArgument, 16> TemplateArgs; 426 TemplateArgs.resize(Params->size()); 427 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data()); 428 CommonPtr->InjectedClassNameType 429 = Context.getTemplateSpecializationType(TemplateName(this), 430 &TemplateArgs[0], 431 TemplateArgs.size()); 432 return CommonPtr->InjectedClassNameType; 433 } 434 435 //===----------------------------------------------------------------------===// 436 // TemplateTypeParm Allocation/Deallocation Method Implementations 437 //===----------------------------------------------------------------------===// 438 439 TemplateTypeParmDecl * 440 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC, 441 SourceLocation KeyLoc, SourceLocation NameLoc, 442 unsigned D, unsigned P, IdentifierInfo *Id, 443 bool Typename, bool ParameterPack) { 444 TemplateTypeParmDecl *TTPDecl = 445 new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename); 446 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 447 TTPDecl->TypeForDecl = TTPType.getTypePtr(); 448 return TTPDecl; 449 } 450 451 TemplateTypeParmDecl * 452 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { 453 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl)); 454 return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(), 455 0, false); 456 } 457 458 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 459 return hasDefaultArgument() 460 ? DefaultArgument->getTypeLoc().getBeginLoc() 461 : SourceLocation(); 462 } 463 464 SourceRange TemplateTypeParmDecl::getSourceRange() const { 465 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 466 return SourceRange(getLocStart(), 467 DefaultArgument->getTypeLoc().getEndLoc()); 468 else 469 return TypeDecl::getSourceRange(); 470 } 471 472 unsigned TemplateTypeParmDecl::getDepth() const { 473 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth(); 474 } 475 476 unsigned TemplateTypeParmDecl::getIndex() const { 477 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex(); 478 } 479 480 bool TemplateTypeParmDecl::isParameterPack() const { 481 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack(); 482 } 483 484 //===----------------------------------------------------------------------===// 485 // NonTypeTemplateParmDecl Method Implementations 486 //===----------------------------------------------------------------------===// 487 488 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 489 SourceLocation StartLoc, 490 SourceLocation IdLoc, 491 unsigned D, unsigned P, 492 IdentifierInfo *Id, 493 QualType T, 494 TypeSourceInfo *TInfo, 495 const QualType *ExpandedTypes, 496 unsigned NumExpandedTypes, 497 TypeSourceInfo **ExpandedTInfos) 498 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 499 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false), 500 ParameterPack(true), ExpandedParameterPack(true), 501 NumExpandedTypes(NumExpandedTypes) 502 { 503 if (ExpandedTypes && ExpandedTInfos) { 504 void **TypesAndInfos = reinterpret_cast<void **>(this + 1); 505 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 506 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr(); 507 TypesAndInfos[2*I + 1] = ExpandedTInfos[I]; 508 } 509 } 510 } 511 512 NonTypeTemplateParmDecl * 513 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 514 SourceLocation StartLoc, SourceLocation IdLoc, 515 unsigned D, unsigned P, IdentifierInfo *Id, 516 QualType T, bool ParameterPack, 517 TypeSourceInfo *TInfo) { 518 return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 519 T, ParameterPack, TInfo); 520 } 521 522 NonTypeTemplateParmDecl * 523 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 524 SourceLocation StartLoc, SourceLocation IdLoc, 525 unsigned D, unsigned P, 526 IdentifierInfo *Id, QualType T, 527 TypeSourceInfo *TInfo, 528 const QualType *ExpandedTypes, 529 unsigned NumExpandedTypes, 530 TypeSourceInfo **ExpandedTInfos) { 531 unsigned Size = sizeof(NonTypeTemplateParmDecl) 532 + NumExpandedTypes * 2 * sizeof(void*); 533 void *Mem = C.Allocate(Size); 534 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, 535 D, P, Id, T, TInfo, 536 ExpandedTypes, NumExpandedTypes, 537 ExpandedTInfos); 538 } 539 540 NonTypeTemplateParmDecl * 541 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 542 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl)); 543 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 544 SourceLocation(), 0, 0, 0, 545 QualType(), false, 0); 546 } 547 548 NonTypeTemplateParmDecl * 549 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 550 unsigned NumExpandedTypes) { 551 unsigned Size = sizeof(NonTypeTemplateParmDecl) 552 + NumExpandedTypes * 2 * sizeof(void*); 553 554 void *Mem = AllocateDeserializedDecl(C, ID, Size); 555 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 556 SourceLocation(), 0, 0, 0, 557 QualType(), 0, 0, NumExpandedTypes, 558 0); 559 } 560 561 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 562 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 563 return SourceRange(getOuterLocStart(), 564 getDefaultArgument()->getSourceRange().getEnd()); 565 return DeclaratorDecl::getSourceRange(); 566 } 567 568 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 569 return hasDefaultArgument() 570 ? getDefaultArgument()->getSourceRange().getBegin() 571 : SourceLocation(); 572 } 573 574 //===----------------------------------------------------------------------===// 575 // TemplateTemplateParmDecl Method Implementations 576 //===----------------------------------------------------------------------===// 577 578 void TemplateTemplateParmDecl::anchor() { } 579 580 TemplateTemplateParmDecl * 581 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 582 SourceLocation L, unsigned D, unsigned P, 583 bool ParameterPack, IdentifierInfo *Id, 584 TemplateParameterList *Params) { 585 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 586 Params); 587 } 588 589 TemplateTemplateParmDecl * 590 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 591 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl)); 592 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false, 593 0, 0); 594 } 595 596 //===----------------------------------------------------------------------===// 597 // TemplateArgumentList Implementation 598 //===----------------------------------------------------------------------===// 599 TemplateArgumentList * 600 TemplateArgumentList::CreateCopy(ASTContext &Context, 601 const TemplateArgument *Args, 602 unsigned NumArgs) { 603 std::size_t Size = sizeof(TemplateArgumentList) 604 + NumArgs * sizeof(TemplateArgument); 605 void *Mem = Context.Allocate(Size); 606 TemplateArgument *StoredArgs 607 = reinterpret_cast<TemplateArgument *>( 608 static_cast<TemplateArgumentList *>(Mem) + 1); 609 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs); 610 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true); 611 } 612 613 FunctionTemplateSpecializationInfo * 614 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 615 FunctionTemplateDecl *Template, 616 TemplateSpecializationKind TSK, 617 const TemplateArgumentList *TemplateArgs, 618 const TemplateArgumentListInfo *TemplateArgsAsWritten, 619 SourceLocation POI) { 620 const ASTTemplateArgumentListInfo *ArgsAsWritten = 0; 621 if (TemplateArgsAsWritten) 622 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 623 *TemplateArgsAsWritten); 624 625 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 626 TemplateArgs, 627 ArgsAsWritten, 628 POI); 629 } 630 631 //===----------------------------------------------------------------------===// 632 // TemplateDecl Implementation 633 //===----------------------------------------------------------------------===// 634 635 void TemplateDecl::anchor() { } 636 637 //===----------------------------------------------------------------------===// 638 // ClassTemplateSpecializationDecl Implementation 639 //===----------------------------------------------------------------------===// 640 ClassTemplateSpecializationDecl:: 641 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 642 DeclContext *DC, SourceLocation StartLoc, 643 SourceLocation IdLoc, 644 ClassTemplateDecl *SpecializedTemplate, 645 const TemplateArgument *Args, 646 unsigned NumArgs, 647 ClassTemplateSpecializationDecl *PrevDecl) 648 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc, 649 SpecializedTemplate->getIdentifier(), 650 PrevDecl), 651 SpecializedTemplate(SpecializedTemplate), 652 ExplicitInfo(0), 653 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 654 SpecializationKind(TSK_Undeclared) { 655 } 656 657 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK) 658 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0), 659 ExplicitInfo(0), 660 SpecializationKind(TSK_Undeclared) { 661 } 662 663 ClassTemplateSpecializationDecl * 664 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 665 DeclContext *DC, 666 SourceLocation StartLoc, 667 SourceLocation IdLoc, 668 ClassTemplateDecl *SpecializedTemplate, 669 const TemplateArgument *Args, 670 unsigned NumArgs, 671 ClassTemplateSpecializationDecl *PrevDecl) { 672 ClassTemplateSpecializationDecl *Result 673 = new (Context)ClassTemplateSpecializationDecl(Context, 674 ClassTemplateSpecialization, 675 TK, DC, StartLoc, IdLoc, 676 SpecializedTemplate, 677 Args, NumArgs, 678 PrevDecl); 679 Context.getTypeDeclType(Result, PrevDecl); 680 return Result; 681 } 682 683 ClassTemplateSpecializationDecl * 684 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 685 unsigned ID) { 686 void *Mem = AllocateDeserializedDecl(C, ID, 687 sizeof(ClassTemplateSpecializationDecl)); 688 return new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization); 689 } 690 691 void 692 ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S, 693 const PrintingPolicy &Policy, 694 bool Qualified) const { 695 NamedDecl::getNameForDiagnostic(S, Policy, Qualified); 696 697 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 698 S += TemplateSpecializationType::PrintTemplateArgumentList( 699 TemplateArgs.data(), 700 TemplateArgs.size(), 701 Policy); 702 } 703 704 ClassTemplateDecl * 705 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 706 if (SpecializedPartialSpecialization *PartialSpec 707 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 708 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 709 return SpecializedTemplate.get<ClassTemplateDecl*>(); 710 } 711 712 SourceRange 713 ClassTemplateSpecializationDecl::getSourceRange() const { 714 if (ExplicitInfo) { 715 SourceLocation Begin = getExternLoc(); 716 if (Begin.isInvalid()) 717 Begin = getTemplateKeywordLoc(); 718 SourceLocation End = getRBraceLoc(); 719 if (End.isInvalid()) 720 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 721 return SourceRange(Begin, End); 722 } 723 else { 724 // No explicit info available. 725 llvm::PointerUnion<ClassTemplateDecl *, 726 ClassTemplatePartialSpecializationDecl *> 727 inst_from = getInstantiatedFrom(); 728 if (inst_from.isNull()) 729 return getSpecializedTemplate()->getSourceRange(); 730 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>()) 731 return ctd->getSourceRange(); 732 return inst_from.get<ClassTemplatePartialSpecializationDecl*>() 733 ->getSourceRange(); 734 } 735 } 736 737 //===----------------------------------------------------------------------===// 738 // ClassTemplatePartialSpecializationDecl Implementation 739 //===----------------------------------------------------------------------===// 740 void ClassTemplatePartialSpecializationDecl::anchor() { } 741 742 ClassTemplatePartialSpecializationDecl:: 743 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 744 DeclContext *DC, 745 SourceLocation StartLoc, 746 SourceLocation IdLoc, 747 TemplateParameterList *Params, 748 ClassTemplateDecl *SpecializedTemplate, 749 const TemplateArgument *Args, 750 unsigned NumArgs, 751 TemplateArgumentLoc *ArgInfos, 752 unsigned NumArgInfos, 753 ClassTemplatePartialSpecializationDecl *PrevDecl, 754 unsigned SequenceNumber) 755 : ClassTemplateSpecializationDecl(Context, 756 ClassTemplatePartialSpecialization, 757 TK, DC, StartLoc, IdLoc, 758 SpecializedTemplate, 759 Args, NumArgs, PrevDecl), 760 TemplateParams(Params), ArgsAsWritten(ArgInfos), 761 NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber), 762 InstantiatedFromMember(0, false) 763 { 764 AdoptTemplateParameterList(Params, this); 765 } 766 767 ClassTemplatePartialSpecializationDecl * 768 ClassTemplatePartialSpecializationDecl:: 769 Create(ASTContext &Context, TagKind TK,DeclContext *DC, 770 SourceLocation StartLoc, SourceLocation IdLoc, 771 TemplateParameterList *Params, 772 ClassTemplateDecl *SpecializedTemplate, 773 const TemplateArgument *Args, 774 unsigned NumArgs, 775 const TemplateArgumentListInfo &ArgInfos, 776 QualType CanonInjectedType, 777 ClassTemplatePartialSpecializationDecl *PrevDecl, 778 unsigned SequenceNumber) { 779 unsigned N = ArgInfos.size(); 780 TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N]; 781 for (unsigned I = 0; I != N; ++I) 782 ClonedArgs[I] = ArgInfos[I]; 783 784 ClassTemplatePartialSpecializationDecl *Result 785 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC, 786 StartLoc, IdLoc, 787 Params, 788 SpecializedTemplate, 789 Args, NumArgs, 790 ClonedArgs, N, 791 PrevDecl, 792 SequenceNumber); 793 Result->setSpecializationKind(TSK_ExplicitSpecialization); 794 795 Context.getInjectedClassNameType(Result, CanonInjectedType); 796 return Result; 797 } 798 799 ClassTemplatePartialSpecializationDecl * 800 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 801 unsigned ID) { 802 void *Mem = AllocateDeserializedDecl(C, ID, 803 sizeof(ClassTemplatePartialSpecializationDecl)); 804 return new (Mem) ClassTemplatePartialSpecializationDecl(); 805 } 806 807 //===----------------------------------------------------------------------===// 808 // FriendTemplateDecl Implementation 809 //===----------------------------------------------------------------------===// 810 811 void FriendTemplateDecl::anchor() { } 812 813 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 814 DeclContext *DC, 815 SourceLocation L, 816 unsigned NParams, 817 TemplateParameterList **Params, 818 FriendUnion Friend, 819 SourceLocation FLoc) { 820 FriendTemplateDecl *Result 821 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc); 822 return Result; 823 } 824 825 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 826 unsigned ID) { 827 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl)); 828 return new (Mem) FriendTemplateDecl(EmptyShell()); 829 } 830 831 //===----------------------------------------------------------------------===// 832 // TypeAliasTemplateDecl Implementation 833 //===----------------------------------------------------------------------===// 834 835 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 836 DeclContext *DC, 837 SourceLocation L, 838 DeclarationName Name, 839 TemplateParameterList *Params, 840 NamedDecl *Decl) { 841 AdoptTemplateParameterList(Params, DC); 842 return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl); 843 } 844 845 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 846 unsigned ID) { 847 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl)); 848 return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(), 849 0, 0); 850 } 851 852 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) { 853 static_cast<Common *>(Ptr)->~Common(); 854 } 855 RedeclarableTemplateDecl::CommonBase * 856 TypeAliasTemplateDecl::newCommon(ASTContext &C) { 857 Common *CommonPtr = new (C) Common; 858 C.AddDeallocation(DeallocateCommon, CommonPtr); 859 return CommonPtr; 860 } 861 862 //===----------------------------------------------------------------------===// 863 // ClassScopeFunctionSpecializationDecl Implementation 864 //===----------------------------------------------------------------------===// 865 866 void ClassScopeFunctionSpecializationDecl::anchor() { } 867 868 ClassScopeFunctionSpecializationDecl * 869 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 870 unsigned ID) { 871 void *Mem = AllocateDeserializedDecl(C, ID, 872 sizeof(ClassScopeFunctionSpecializationDecl)); 873 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0, 874 false, TemplateArgumentListInfo()); 875 } 876