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