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