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