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::FoldingSet<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, 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 getSpecializations().InsertNode(Info, InsertPos); 242 if (ASTMutationListener *L = getASTMutationListener()) 243 L->AddedCXXTemplateSpecialization(this, Info->Function); 244 } 245 246 std::pair<const TemplateArgument *, unsigned> 247 FunctionTemplateDecl::getInjectedTemplateArgs() { 248 TemplateParameterList *Params = getTemplateParameters(); 249 Common *CommonPtr = getCommonPtr(); 250 if (!CommonPtr->InjectedArgs) { 251 CommonPtr->InjectedArgs 252 = new (getASTContext()) TemplateArgument [Params->size()]; 253 GenerateInjectedTemplateArgs(getASTContext(), Params, 254 CommonPtr->InjectedArgs); 255 } 256 257 return std::make_pair(CommonPtr->InjectedArgs, Params->size()); 258 } 259 260 //===----------------------------------------------------------------------===// 261 // ClassTemplateDecl Implementation 262 //===----------------------------------------------------------------------===// 263 264 void ClassTemplateDecl::DeallocateCommon(void *Ptr) { 265 static_cast<Common *>(Ptr)->~Common(); 266 } 267 268 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 269 DeclContext *DC, 270 SourceLocation L, 271 DeclarationName Name, 272 TemplateParameterList *Params, 273 NamedDecl *Decl, 274 ClassTemplateDecl *PrevDecl) { 275 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 276 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl); 277 New->setPreviousDeclaration(PrevDecl); 278 return New; 279 } 280 281 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 282 unsigned ID) { 283 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl)); 284 return new (Mem) ClassTemplateDecl(EmptyShell()); 285 } 286 287 void ClassTemplateDecl::LoadLazySpecializations() { 288 Common *CommonPtr = getCommonPtr(); 289 if (CommonPtr->LazySpecializations) { 290 ASTContext &Context = getASTContext(); 291 uint32_t *Specs = CommonPtr->LazySpecializations; 292 CommonPtr->LazySpecializations = 0; 293 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 294 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 295 } 296 } 297 298 llvm::FoldingSet<ClassTemplateSpecializationDecl> & 299 ClassTemplateDecl::getSpecializations() { 300 LoadLazySpecializations(); 301 return getCommonPtr()->Specializations; 302 } 303 304 llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> & 305 ClassTemplateDecl::getPartialSpecializations() { 306 LoadLazySpecializations(); 307 return getCommonPtr()->PartialSpecializations; 308 } 309 310 RedeclarableTemplateDecl::CommonBase * 311 ClassTemplateDecl::newCommon(ASTContext &C) { 312 Common *CommonPtr = new (C) Common; 313 C.AddDeallocation(DeallocateCommon, CommonPtr); 314 return CommonPtr; 315 } 316 317 ClassTemplateSpecializationDecl * 318 ClassTemplateDecl::findSpecialization(const TemplateArgument *Args, 319 unsigned NumArgs, void *&InsertPos) { 320 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 321 } 322 323 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 324 void *InsertPos) { 325 getSpecializations().InsertNode(D, InsertPos); 326 if (ASTMutationListener *L = getASTMutationListener()) 327 L->AddedCXXTemplateSpecialization(this, D); 328 } 329 330 ClassTemplatePartialSpecializationDecl * 331 ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, 332 unsigned NumArgs, 333 void *&InsertPos) { 334 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs, 335 InsertPos); 336 } 337 338 void ClassTemplateDecl::AddPartialSpecialization( 339 ClassTemplatePartialSpecializationDecl *D, 340 void *InsertPos) { 341 getPartialSpecializations().InsertNode(D, InsertPos); 342 if (ASTMutationListener *L = getASTMutationListener()) 343 L->AddedCXXTemplateSpecialization(this, D); 344 } 345 346 void ClassTemplateDecl::getPartialSpecializations( 347 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) { 348 llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs 349 = getPartialSpecializations(); 350 PS.clear(); 351 PS.resize(PartialSpecs.size()); 352 for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator 353 P = PartialSpecs.begin(), PEnd = PartialSpecs.end(); 354 P != PEnd; ++P) { 355 assert(!PS[P->getSequenceNumber()]); 356 PS[P->getSequenceNumber()] = P->getMostRecentDecl(); 357 } 358 } 359 360 ClassTemplatePartialSpecializationDecl * 361 ClassTemplateDecl::findPartialSpecialization(QualType T) { 362 ASTContext &Context = getASTContext(); 363 typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator 364 partial_spec_iterator; 365 for (partial_spec_iterator P = getPartialSpecializations().begin(), 366 PEnd = getPartialSpecializations().end(); 367 P != PEnd; ++P) { 368 if (Context.hasSameType(P->getInjectedSpecializationType(), T)) 369 return P->getMostRecentDecl(); 370 } 371 372 return 0; 373 } 374 375 ClassTemplatePartialSpecializationDecl * 376 ClassTemplateDecl::findPartialSpecInstantiatedFromMember( 377 ClassTemplatePartialSpecializationDecl *D) { 378 Decl *DCanon = D->getCanonicalDecl(); 379 for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator 380 P = getPartialSpecializations().begin(), 381 PEnd = getPartialSpecializations().end(); 382 P != PEnd; ++P) { 383 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 384 return P->getMostRecentDecl(); 385 } 386 387 return 0; 388 } 389 390 QualType 391 ClassTemplateDecl::getInjectedClassNameSpecialization() { 392 Common *CommonPtr = getCommonPtr(); 393 if (!CommonPtr->InjectedClassNameType.isNull()) 394 return CommonPtr->InjectedClassNameType; 395 396 // C++0x [temp.dep.type]p2: 397 // The template argument list of a primary template is a template argument 398 // list in which the nth template argument has the value of the nth template 399 // parameter of the class template. If the nth template parameter is a 400 // template parameter pack (14.5.3), the nth template argument is a pack 401 // expansion (14.5.3) whose pattern is the name of the template parameter 402 // pack. 403 ASTContext &Context = getASTContext(); 404 TemplateParameterList *Params = getTemplateParameters(); 405 SmallVector<TemplateArgument, 16> TemplateArgs; 406 TemplateArgs.resize(Params->size()); 407 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data()); 408 CommonPtr->InjectedClassNameType 409 = Context.getTemplateSpecializationType(TemplateName(this), 410 &TemplateArgs[0], 411 TemplateArgs.size()); 412 return CommonPtr->InjectedClassNameType; 413 } 414 415 //===----------------------------------------------------------------------===// 416 // TemplateTypeParm Allocation/Deallocation Method Implementations 417 //===----------------------------------------------------------------------===// 418 419 TemplateTypeParmDecl * 420 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC, 421 SourceLocation KeyLoc, SourceLocation NameLoc, 422 unsigned D, unsigned P, IdentifierInfo *Id, 423 bool Typename, bool ParameterPack) { 424 TemplateTypeParmDecl *TTPDecl = 425 new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename); 426 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 427 TTPDecl->TypeForDecl = TTPType.getTypePtr(); 428 return TTPDecl; 429 } 430 431 TemplateTypeParmDecl * 432 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { 433 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl)); 434 return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(), 435 0, false); 436 } 437 438 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 439 return hasDefaultArgument() 440 ? DefaultArgument->getTypeLoc().getBeginLoc() 441 : SourceLocation(); 442 } 443 444 SourceRange TemplateTypeParmDecl::getSourceRange() const { 445 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 446 return SourceRange(getLocStart(), 447 DefaultArgument->getTypeLoc().getEndLoc()); 448 else 449 return TypeDecl::getSourceRange(); 450 } 451 452 unsigned TemplateTypeParmDecl::getDepth() const { 453 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth(); 454 } 455 456 unsigned TemplateTypeParmDecl::getIndex() const { 457 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex(); 458 } 459 460 bool TemplateTypeParmDecl::isParameterPack() const { 461 return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack(); 462 } 463 464 //===----------------------------------------------------------------------===// 465 // NonTypeTemplateParmDecl Method Implementations 466 //===----------------------------------------------------------------------===// 467 468 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 469 SourceLocation StartLoc, 470 SourceLocation IdLoc, 471 unsigned D, unsigned P, 472 IdentifierInfo *Id, 473 QualType T, 474 TypeSourceInfo *TInfo, 475 const QualType *ExpandedTypes, 476 unsigned NumExpandedTypes, 477 TypeSourceInfo **ExpandedTInfos) 478 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 479 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false), 480 ParameterPack(true), ExpandedParameterPack(true), 481 NumExpandedTypes(NumExpandedTypes) 482 { 483 if (ExpandedTypes && ExpandedTInfos) { 484 void **TypesAndInfos = reinterpret_cast<void **>(this + 1); 485 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 486 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr(); 487 TypesAndInfos[2*I + 1] = ExpandedTInfos[I]; 488 } 489 } 490 } 491 492 NonTypeTemplateParmDecl * 493 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 494 SourceLocation StartLoc, SourceLocation IdLoc, 495 unsigned D, unsigned P, IdentifierInfo *Id, 496 QualType T, bool ParameterPack, 497 TypeSourceInfo *TInfo) { 498 return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 499 T, ParameterPack, TInfo); 500 } 501 502 NonTypeTemplateParmDecl * 503 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 504 SourceLocation StartLoc, SourceLocation IdLoc, 505 unsigned D, unsigned P, 506 IdentifierInfo *Id, QualType T, 507 TypeSourceInfo *TInfo, 508 const QualType *ExpandedTypes, 509 unsigned NumExpandedTypes, 510 TypeSourceInfo **ExpandedTInfos) { 511 unsigned Size = sizeof(NonTypeTemplateParmDecl) 512 + NumExpandedTypes * 2 * sizeof(void*); 513 void *Mem = C.Allocate(Size); 514 return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, 515 D, P, Id, T, TInfo, 516 ExpandedTypes, NumExpandedTypes, 517 ExpandedTInfos); 518 } 519 520 NonTypeTemplateParmDecl * 521 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 522 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl)); 523 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 524 SourceLocation(), 0, 0, 0, 525 QualType(), false, 0); 526 } 527 528 NonTypeTemplateParmDecl * 529 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 530 unsigned NumExpandedTypes) { 531 unsigned Size = sizeof(NonTypeTemplateParmDecl) 532 + NumExpandedTypes * 2 * sizeof(void*); 533 534 void *Mem = AllocateDeserializedDecl(C, ID, Size); 535 return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 536 SourceLocation(), 0, 0, 0, 537 QualType(), 0, 0, NumExpandedTypes, 538 0); 539 } 540 541 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 542 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 543 return SourceRange(getOuterLocStart(), 544 getDefaultArgument()->getSourceRange().getEnd()); 545 return DeclaratorDecl::getSourceRange(); 546 } 547 548 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 549 return hasDefaultArgument() 550 ? getDefaultArgument()->getSourceRange().getBegin() 551 : SourceLocation(); 552 } 553 554 //===----------------------------------------------------------------------===// 555 // TemplateTemplateParmDecl Method Implementations 556 //===----------------------------------------------------------------------===// 557 558 void TemplateTemplateParmDecl::anchor() { } 559 560 TemplateTemplateParmDecl * 561 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 562 SourceLocation L, unsigned D, unsigned P, 563 bool ParameterPack, IdentifierInfo *Id, 564 TemplateParameterList *Params) { 565 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 566 Params); 567 } 568 569 TemplateTemplateParmDecl * 570 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 571 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl)); 572 return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false, 573 0, 0); 574 } 575 576 //===----------------------------------------------------------------------===// 577 // TemplateArgumentList Implementation 578 //===----------------------------------------------------------------------===// 579 TemplateArgumentList * 580 TemplateArgumentList::CreateCopy(ASTContext &Context, 581 const TemplateArgument *Args, 582 unsigned NumArgs) { 583 std::size_t Size = sizeof(TemplateArgumentList) 584 + NumArgs * sizeof(TemplateArgument); 585 void *Mem = Context.Allocate(Size); 586 TemplateArgument *StoredArgs 587 = reinterpret_cast<TemplateArgument *>( 588 static_cast<TemplateArgumentList *>(Mem) + 1); 589 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs); 590 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true); 591 } 592 593 FunctionTemplateSpecializationInfo * 594 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 595 FunctionTemplateDecl *Template, 596 TemplateSpecializationKind TSK, 597 const TemplateArgumentList *TemplateArgs, 598 const TemplateArgumentListInfo *TemplateArgsAsWritten, 599 SourceLocation POI) { 600 const ASTTemplateArgumentListInfo *ArgsAsWritten = 0; 601 if (TemplateArgsAsWritten) 602 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 603 *TemplateArgsAsWritten); 604 605 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 606 TemplateArgs, 607 ArgsAsWritten, 608 POI); 609 } 610 611 //===----------------------------------------------------------------------===// 612 // TemplateDecl Implementation 613 //===----------------------------------------------------------------------===// 614 615 void TemplateDecl::anchor() { } 616 617 //===----------------------------------------------------------------------===// 618 // ClassTemplateSpecializationDecl Implementation 619 //===----------------------------------------------------------------------===// 620 ClassTemplateSpecializationDecl:: 621 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 622 DeclContext *DC, SourceLocation StartLoc, 623 SourceLocation IdLoc, 624 ClassTemplateDecl *SpecializedTemplate, 625 const TemplateArgument *Args, 626 unsigned NumArgs, 627 ClassTemplateSpecializationDecl *PrevDecl) 628 : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc, 629 SpecializedTemplate->getIdentifier(), 630 PrevDecl), 631 SpecializedTemplate(SpecializedTemplate), 632 ExplicitInfo(0), 633 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 634 SpecializationKind(TSK_Undeclared) { 635 } 636 637 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK) 638 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0), 639 ExplicitInfo(0), 640 SpecializationKind(TSK_Undeclared) { 641 } 642 643 ClassTemplateSpecializationDecl * 644 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 645 DeclContext *DC, 646 SourceLocation StartLoc, 647 SourceLocation IdLoc, 648 ClassTemplateDecl *SpecializedTemplate, 649 const TemplateArgument *Args, 650 unsigned NumArgs, 651 ClassTemplateSpecializationDecl *PrevDecl) { 652 ClassTemplateSpecializationDecl *Result 653 = new (Context)ClassTemplateSpecializationDecl(Context, 654 ClassTemplateSpecialization, 655 TK, DC, StartLoc, IdLoc, 656 SpecializedTemplate, 657 Args, NumArgs, 658 PrevDecl); 659 Context.getTypeDeclType(Result, PrevDecl); 660 return Result; 661 } 662 663 ClassTemplateSpecializationDecl * 664 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 665 unsigned ID) { 666 void *Mem = AllocateDeserializedDecl(C, ID, 667 sizeof(ClassTemplateSpecializationDecl)); 668 return new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization); 669 } 670 671 void 672 ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S, 673 const PrintingPolicy &Policy, 674 bool Qualified) const { 675 NamedDecl::getNameForDiagnostic(S, Policy, Qualified); 676 677 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 678 S += TemplateSpecializationType::PrintTemplateArgumentList( 679 TemplateArgs.data(), 680 TemplateArgs.size(), 681 Policy); 682 } 683 684 ClassTemplateDecl * 685 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 686 if (SpecializedPartialSpecialization *PartialSpec 687 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 688 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 689 return SpecializedTemplate.get<ClassTemplateDecl*>(); 690 } 691 692 SourceRange 693 ClassTemplateSpecializationDecl::getSourceRange() const { 694 if (ExplicitInfo) { 695 SourceLocation Begin = getExternLoc(); 696 if (Begin.isInvalid()) 697 Begin = getTemplateKeywordLoc(); 698 SourceLocation End = getRBraceLoc(); 699 if (End.isInvalid()) 700 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 701 return SourceRange(Begin, End); 702 } 703 else { 704 // No explicit info available. 705 llvm::PointerUnion<ClassTemplateDecl *, 706 ClassTemplatePartialSpecializationDecl *> 707 inst_from = getInstantiatedFrom(); 708 if (inst_from.isNull()) 709 return getSpecializedTemplate()->getSourceRange(); 710 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>()) 711 return ctd->getSourceRange(); 712 return inst_from.get<ClassTemplatePartialSpecializationDecl*>() 713 ->getSourceRange(); 714 } 715 } 716 717 //===----------------------------------------------------------------------===// 718 // ClassTemplatePartialSpecializationDecl Implementation 719 //===----------------------------------------------------------------------===// 720 void ClassTemplatePartialSpecializationDecl::anchor() { } 721 722 ClassTemplatePartialSpecializationDecl:: 723 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 724 DeclContext *DC, 725 SourceLocation StartLoc, 726 SourceLocation IdLoc, 727 TemplateParameterList *Params, 728 ClassTemplateDecl *SpecializedTemplate, 729 const TemplateArgument *Args, 730 unsigned NumArgs, 731 TemplateArgumentLoc *ArgInfos, 732 unsigned NumArgInfos, 733 ClassTemplatePartialSpecializationDecl *PrevDecl, 734 unsigned SequenceNumber) 735 : ClassTemplateSpecializationDecl(Context, 736 ClassTemplatePartialSpecialization, 737 TK, DC, StartLoc, IdLoc, 738 SpecializedTemplate, 739 Args, NumArgs, PrevDecl), 740 TemplateParams(Params), ArgsAsWritten(ArgInfos), 741 NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber), 742 InstantiatedFromMember(0, false) 743 { 744 AdoptTemplateParameterList(Params, this); 745 } 746 747 ClassTemplatePartialSpecializationDecl * 748 ClassTemplatePartialSpecializationDecl:: 749 Create(ASTContext &Context, TagKind TK,DeclContext *DC, 750 SourceLocation StartLoc, SourceLocation IdLoc, 751 TemplateParameterList *Params, 752 ClassTemplateDecl *SpecializedTemplate, 753 const TemplateArgument *Args, 754 unsigned NumArgs, 755 const TemplateArgumentListInfo &ArgInfos, 756 QualType CanonInjectedType, 757 ClassTemplatePartialSpecializationDecl *PrevDecl, 758 unsigned SequenceNumber) { 759 unsigned N = ArgInfos.size(); 760 TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N]; 761 for (unsigned I = 0; I != N; ++I) 762 ClonedArgs[I] = ArgInfos[I]; 763 764 ClassTemplatePartialSpecializationDecl *Result 765 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC, 766 StartLoc, IdLoc, 767 Params, 768 SpecializedTemplate, 769 Args, NumArgs, 770 ClonedArgs, N, 771 PrevDecl, 772 SequenceNumber); 773 Result->setSpecializationKind(TSK_ExplicitSpecialization); 774 775 Context.getInjectedClassNameType(Result, CanonInjectedType); 776 return Result; 777 } 778 779 ClassTemplatePartialSpecializationDecl * 780 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 781 unsigned ID) { 782 void *Mem = AllocateDeserializedDecl(C, ID, 783 sizeof(ClassTemplatePartialSpecializationDecl)); 784 return new (Mem) ClassTemplatePartialSpecializationDecl(); 785 } 786 787 //===----------------------------------------------------------------------===// 788 // FriendTemplateDecl Implementation 789 //===----------------------------------------------------------------------===// 790 791 void FriendTemplateDecl::anchor() { } 792 793 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 794 DeclContext *DC, 795 SourceLocation L, 796 unsigned NParams, 797 TemplateParameterList **Params, 798 FriendUnion Friend, 799 SourceLocation FLoc) { 800 FriendTemplateDecl *Result 801 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc); 802 return Result; 803 } 804 805 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 806 unsigned ID) { 807 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl)); 808 return new (Mem) FriendTemplateDecl(EmptyShell()); 809 } 810 811 //===----------------------------------------------------------------------===// 812 // TypeAliasTemplateDecl Implementation 813 //===----------------------------------------------------------------------===// 814 815 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 816 DeclContext *DC, 817 SourceLocation L, 818 DeclarationName Name, 819 TemplateParameterList *Params, 820 NamedDecl *Decl) { 821 AdoptTemplateParameterList(Params, DC); 822 return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl); 823 } 824 825 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 826 unsigned ID) { 827 void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl)); 828 return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(), 829 0, 0); 830 } 831 832 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) { 833 static_cast<Common *>(Ptr)->~Common(); 834 } 835 RedeclarableTemplateDecl::CommonBase * 836 TypeAliasTemplateDecl::newCommon(ASTContext &C) { 837 Common *CommonPtr = new (C) Common; 838 C.AddDeallocation(DeallocateCommon, CommonPtr); 839 return CommonPtr; 840 } 841 842 //===----------------------------------------------------------------------===// 843 // ClassScopeFunctionSpecializationDecl Implementation 844 //===----------------------------------------------------------------------===// 845 846 void ClassScopeFunctionSpecializationDecl::anchor() { } 847 848 ClassScopeFunctionSpecializationDecl * 849 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 850 unsigned ID) { 851 void *Mem = AllocateDeserializedDecl(C, ID, 852 sizeof(ClassScopeFunctionSpecializationDecl)); 853 return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0); 854 } 855