1198893Srdivacky//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the C++ related Decl classes for templates. 11193326Sed// 12193326Sed//===----------------------------------------------------------------------===// 13193326Sed 14252723Sdim#include "clang/AST/DeclTemplate.h" 15252723Sdim#include "clang/AST/ASTContext.h" 16252723Sdim#include "clang/AST/ASTMutationListener.h" 17193326Sed#include "clang/AST/DeclCXX.h" 18193326Sed#include "clang/AST/Expr.h" 19218893Sdim#include "clang/AST/ExprCXX.h" 20198893Srdivacky#include "clang/AST/TypeLoc.h" 21193326Sed#include "clang/Basic/IdentifierTable.h" 22193326Sed#include "llvm/ADT/STLExtras.h" 23218893Sdim#include <memory> 24193326Sedusing namespace clang; 25193326Sed 26193326Sed//===----------------------------------------------------------------------===// 27193326Sed// TemplateParameterList Implementation 28193326Sed//===----------------------------------------------------------------------===// 29193326Sed 30193326SedTemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, 31193326Sed SourceLocation LAngleLoc, 32198092Srdivacky NamedDecl **Params, unsigned NumParams, 33193326Sed SourceLocation RAngleLoc) 34193326Sed : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), 35245431Sdim NumParams(NumParams), ContainsUnexpandedParameterPack(false) { 36245431Sdim assert(this->NumParams == NumParams && "Too many template parameters"); 37245431Sdim for (unsigned Idx = 0; Idx < NumParams; ++Idx) { 38245431Sdim NamedDecl *P = Params[Idx]; 39245431Sdim begin()[Idx] = P; 40245431Sdim 41245431Sdim if (!P->isTemplateParameterPack()) { 42245431Sdim if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) 43245431Sdim if (NTTP->getType()->containsUnexpandedParameterPack()) 44245431Sdim ContainsUnexpandedParameterPack = true; 45245431Sdim 46245431Sdim if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) 47245431Sdim if (TTP->getTemplateParameters()->containsUnexpandedParameterPack()) 48245431Sdim ContainsUnexpandedParameterPack = true; 49245431Sdim 50245431Sdim // FIXME: If a default argument contains an unexpanded parameter pack, the 51245431Sdim // template parameter list does too. 52245431Sdim } 53245431Sdim } 54193326Sed} 55193326Sed 56193326SedTemplateParameterList * 57218893SdimTemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, 58198092Srdivacky SourceLocation LAngleLoc, NamedDecl **Params, 59193326Sed unsigned NumParams, SourceLocation RAngleLoc) { 60198092Srdivacky unsigned Size = sizeof(TemplateParameterList) 61198092Srdivacky + sizeof(NamedDecl *) * NumParams; 62245431Sdim unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(), 63245431Sdim llvm::alignOf<NamedDecl*>()); 64193326Sed void *Mem = C.Allocate(Size, Align); 65198092Srdivacky return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, 66193326Sed NumParams, RAngleLoc); 67193326Sed} 68193326Sed 69193326Sedunsigned TemplateParameterList::getMinRequiredArguments() const { 70218893Sdim unsigned NumRequiredArgs = 0; 71218893Sdim for (iterator P = const_cast<TemplateParameterList *>(this)->begin(), 72218893Sdim PEnd = const_cast<TemplateParameterList *>(this)->end(); 73218893Sdim P != PEnd; ++P) { 74218893Sdim if ((*P)->isTemplateParameterPack()) { 75218893Sdim if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) 76218893Sdim if (NTTP->isExpandedParameterPack()) { 77218893Sdim NumRequiredArgs += NTTP->getNumExpansionTypes(); 78218893Sdim continue; 79218893Sdim } 80218893Sdim 81193326Sed break; 82218893Sdim } 83218893Sdim 84218893Sdim if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { 85218893Sdim if (TTP->hasDefaultArgument()) 86218893Sdim break; 87218893Sdim } else if (NonTypeTemplateParmDecl *NTTP 88218893Sdim = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 89218893Sdim if (NTTP->hasDefaultArgument()) 90218893Sdim break; 91218893Sdim } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument()) 92218893Sdim break; 93218893Sdim 94218893Sdim ++NumRequiredArgs; 95193326Sed } 96218893Sdim 97193326Sed return NumRequiredArgs; 98193326Sed} 99193326Sed 100198893Srdivackyunsigned TemplateParameterList::getDepth() const { 101198893Srdivacky if (size() == 0) 102198893Srdivacky return 0; 103198893Srdivacky 104198893Srdivacky const NamedDecl *FirstParm = getParam(0); 105198893Srdivacky if (const TemplateTypeParmDecl *TTP 106198893Srdivacky = dyn_cast<TemplateTypeParmDecl>(FirstParm)) 107198893Srdivacky return TTP->getDepth(); 108198893Srdivacky else if (const NonTypeTemplateParmDecl *NTTP 109198893Srdivacky = dyn_cast<NonTypeTemplateParmDecl>(FirstParm)) 110198893Srdivacky return NTTP->getDepth(); 111198893Srdivacky else 112198893Srdivacky return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth(); 113198893Srdivacky} 114198893Srdivacky 115221345Sdimstatic void AdoptTemplateParameterList(TemplateParameterList *Params, 116221345Sdim DeclContext *Owner) { 117221345Sdim for (TemplateParameterList::iterator P = Params->begin(), 118221345Sdim PEnd = Params->end(); 119221345Sdim P != PEnd; ++P) { 120221345Sdim (*P)->setDeclContext(Owner); 121221345Sdim 122221345Sdim if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P)) 123221345Sdim AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner); 124221345Sdim } 125221345Sdim} 126221345Sdim 127193326Sed//===----------------------------------------------------------------------===// 128212904Sdim// RedeclarableTemplateDecl Implementation 129193326Sed//===----------------------------------------------------------------------===// 130193326Sed 131252723SdimRedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const { 132263509Sdim if (Common) 133263509Sdim return Common; 134263509Sdim 135263509Sdim // Walk the previous-declaration chain until we either find a declaration 136263509Sdim // with a common pointer or we run out of previous declarations. 137263509Sdim SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls; 138263509Sdim for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev; 139263509Sdim Prev = Prev->getPreviousDecl()) { 140263509Sdim if (Prev->Common) { 141263509Sdim Common = Prev->Common; 142263509Sdim break; 143235633Sdim } 144212904Sdim 145263509Sdim PrevDecls.push_back(Prev); 146212904Sdim } 147193326Sed 148263509Sdim // If we never found a common pointer, allocate one now. 149263509Sdim if (!Common) { 150263509Sdim // FIXME: If any of the declarations is from an AST file, we probably 151263509Sdim // need an update record to add the common data. 152263509Sdim 153263509Sdim Common = newCommon(getASTContext()); 154263509Sdim } 155263509Sdim 156263509Sdim // Update any previous declarations we saw with the common pointer. 157263509Sdim for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I) 158263509Sdim PrevDecls[I]->Common = Common; 159263509Sdim 160235633Sdim return Common; 161212904Sdim} 162212904Sdim 163212904Sdimtemplate <class EntryType> 164212904Sdimtypename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType* 165212904SdimRedeclarableTemplateDecl::findSpecializationImpl( 166245431Sdim llvm::FoldingSetVector<EntryType> &Specs, 167212904Sdim const TemplateArgument *Args, unsigned NumArgs, 168212904Sdim void *&InsertPos) { 169212904Sdim typedef SpecEntryTraits<EntryType> SETraits; 170212904Sdim llvm::FoldingSetNodeID ID; 171212904Sdim EntryType::Profile(ID,Args,NumArgs, getASTContext()); 172212904Sdim EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 173235633Sdim return Entry ? SETraits::getMostRecentDecl(Entry) : 0; 174212904Sdim} 175212904Sdim 176221345Sdim/// \brief Generate the injected template arguments for the given template 177221345Sdim/// parameter list, e.g., for the injected-class-name of a class template. 178221345Sdimstatic void GenerateInjectedTemplateArgs(ASTContext &Context, 179221345Sdim TemplateParameterList *Params, 180221345Sdim TemplateArgument *Args) { 181221345Sdim for (TemplateParameterList::iterator Param = Params->begin(), 182221345Sdim ParamEnd = Params->end(); 183221345Sdim Param != ParamEnd; ++Param) { 184221345Sdim TemplateArgument Arg; 185221345Sdim if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { 186221345Sdim QualType ArgType = Context.getTypeDeclType(TTP); 187221345Sdim if (TTP->isParameterPack()) 188252723Sdim ArgType = Context.getPackExpansionType(ArgType, None); 189252723Sdim 190221345Sdim Arg = TemplateArgument(ArgType); 191221345Sdim } else if (NonTypeTemplateParmDecl *NTTP = 192221345Sdim dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 193235633Sdim Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false, 194221345Sdim NTTP->getType().getNonLValueExprType(Context), 195221345Sdim Expr::getValueKindForType(NTTP->getType()), 196221345Sdim NTTP->getLocation()); 197221345Sdim 198221345Sdim if (NTTP->isParameterPack()) 199221345Sdim E = new (Context) PackExpansionExpr(Context.DependentTy, E, 200252723Sdim NTTP->getLocation(), None); 201221345Sdim Arg = TemplateArgument(E); 202221345Sdim } else { 203221345Sdim TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 204221345Sdim if (TTP->isParameterPack()) 205252723Sdim Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>()); 206221345Sdim else 207221345Sdim Arg = TemplateArgument(TemplateName(TTP)); 208221345Sdim } 209221345Sdim 210221345Sdim if ((*Param)->isTemplateParameterPack()) 211221345Sdim Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1); 212221345Sdim 213221345Sdim *Args++ = Arg; 214221345Sdim } 215221345Sdim} 216221345Sdim 217193326Sed//===----------------------------------------------------------------------===// 218193326Sed// FunctionTemplateDecl Implementation 219193326Sed//===----------------------------------------------------------------------===// 220193326Sed 221208600Srdivackyvoid FunctionTemplateDecl::DeallocateCommon(void *Ptr) { 222208600Srdivacky static_cast<Common *>(Ptr)->~Common(); 223208600Srdivacky} 224208600Srdivacky 225193326SedFunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 226193326Sed DeclContext *DC, 227193326Sed SourceLocation L, 228193326Sed DeclarationName Name, 229195341Sed TemplateParameterList *Params, 230193326Sed NamedDecl *Decl) { 231221345Sdim AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 232193326Sed return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl); 233193326Sed} 234193326Sed 235235633SdimFunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, 236235633Sdim unsigned ID) { 237235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl)); 238235633Sdim return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(), 239235633Sdim 0, 0); 240221345Sdim} 241221345Sdim 242218893SdimRedeclarableTemplateDecl::CommonBase * 243252723SdimFunctionTemplateDecl::newCommon(ASTContext &C) const { 244218893Sdim Common *CommonPtr = new (C) Common; 245218893Sdim C.AddDeallocation(DeallocateCommon, CommonPtr); 246212904Sdim return CommonPtr; 247195341Sed} 248195341Sed 249263509Sdimvoid FunctionTemplateDecl::LoadLazySpecializations() const { 250263509Sdim Common *CommonPtr = getCommonPtr(); 251263509Sdim if (CommonPtr->LazySpecializations) { 252263509Sdim ASTContext &Context = getASTContext(); 253263509Sdim uint32_t *Specs = CommonPtr->LazySpecializations; 254263509Sdim CommonPtr->LazySpecializations = 0; 255263509Sdim for (uint32_t I = 0, N = *Specs++; I != N; ++I) 256263509Sdim (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 257263509Sdim } 258263509Sdim} 259263509Sdim 260263509Sdimllvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & 261263509SdimFunctionTemplateDecl::getSpecializations() const { 262263509Sdim LoadLazySpecializations(); 263263509Sdim return getCommonPtr()->Specializations; 264263509Sdim} 265263509Sdim 266212904SdimFunctionDecl * 267212904SdimFunctionTemplateDecl::findSpecialization(const TemplateArgument *Args, 268212904Sdim unsigned NumArgs, void *&InsertPos) { 269212904Sdim return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 270198092Srdivacky} 271198092Srdivacky 272221345Sdimvoid FunctionTemplateDecl::addSpecialization( 273221345Sdim FunctionTemplateSpecializationInfo *Info, void *InsertPos) { 274235633Sdim if (InsertPos) 275235633Sdim getSpecializations().InsertNode(Info, InsertPos); 276235633Sdim else 277235633Sdim getSpecializations().GetOrInsertNode(Info); 278221345Sdim if (ASTMutationListener *L = getASTMutationListener()) 279221345Sdim L->AddedCXXTemplateSpecialization(this, Info->Function); 280221345Sdim} 281221345Sdim 282263509SdimArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() { 283221345Sdim TemplateParameterList *Params = getTemplateParameters(); 284221345Sdim Common *CommonPtr = getCommonPtr(); 285221345Sdim if (!CommonPtr->InjectedArgs) { 286221345Sdim CommonPtr->InjectedArgs 287263509Sdim = new (getASTContext()) TemplateArgument[Params->size()]; 288263509Sdim GenerateInjectedTemplateArgs(getASTContext(), Params, 289221345Sdim CommonPtr->InjectedArgs); 290221345Sdim } 291263509Sdim 292263509Sdim return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size()); 293221345Sdim} 294221345Sdim 295193326Sed//===----------------------------------------------------------------------===// 296193326Sed// ClassTemplateDecl Implementation 297193326Sed//===----------------------------------------------------------------------===// 298193326Sed 299208600Srdivackyvoid ClassTemplateDecl::DeallocateCommon(void *Ptr) { 300208600Srdivacky static_cast<Common *>(Ptr)->~Common(); 301208600Srdivacky} 302208600Srdivacky 303193326SedClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 304193326Sed DeclContext *DC, 305193326Sed SourceLocation L, 306193326Sed DeclarationName Name, 307193326Sed TemplateParameterList *Params, 308193326Sed NamedDecl *Decl, 309193326Sed ClassTemplateDecl *PrevDecl) { 310221345Sdim AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 311210299Sed ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl); 312263509Sdim New->setPreviousDecl(PrevDecl); 313210299Sed return New; 314193326Sed} 315193326Sed 316235633SdimClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 317235633Sdim unsigned ID) { 318235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl)); 319235633Sdim return new (Mem) ClassTemplateDecl(EmptyShell()); 320221345Sdim} 321221345Sdim 322252723Sdimvoid ClassTemplateDecl::LoadLazySpecializations() const { 323218893Sdim Common *CommonPtr = getCommonPtr(); 324218893Sdim if (CommonPtr->LazySpecializations) { 325218893Sdim ASTContext &Context = getASTContext(); 326218893Sdim uint32_t *Specs = CommonPtr->LazySpecializations; 327218893Sdim CommonPtr->LazySpecializations = 0; 328218893Sdim for (uint32_t I = 0, N = *Specs++; I != N; ++I) 329218893Sdim (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 330218893Sdim } 331218893Sdim} 332218893Sdim 333245431Sdimllvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 334252723SdimClassTemplateDecl::getSpecializations() const { 335218893Sdim LoadLazySpecializations(); 336218893Sdim return getCommonPtr()->Specializations; 337218893Sdim} 338218893Sdim 339245431Sdimllvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 340218893SdimClassTemplateDecl::getPartialSpecializations() { 341218893Sdim LoadLazySpecializations(); 342218893Sdim return getCommonPtr()->PartialSpecializations; 343218893Sdim} 344218893Sdim 345218893SdimRedeclarableTemplateDecl::CommonBase * 346252723SdimClassTemplateDecl::newCommon(ASTContext &C) const { 347218893Sdim Common *CommonPtr = new (C) Common; 348218893Sdim C.AddDeallocation(DeallocateCommon, CommonPtr); 349212904Sdim return CommonPtr; 350193326Sed} 351193326Sed 352212904SdimClassTemplateSpecializationDecl * 353212904SdimClassTemplateDecl::findSpecialization(const TemplateArgument *Args, 354212904Sdim unsigned NumArgs, void *&InsertPos) { 355212904Sdim return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 356212904Sdim} 357212904Sdim 358218893Sdimvoid ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 359218893Sdim void *InsertPos) { 360235633Sdim if (InsertPos) 361235633Sdim getSpecializations().InsertNode(D, InsertPos); 362235633Sdim else { 363235633Sdim ClassTemplateSpecializationDecl *Existing 364235633Sdim = getSpecializations().GetOrInsertNode(D); 365235633Sdim (void)Existing; 366235633Sdim assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 367235633Sdim } 368218893Sdim if (ASTMutationListener *L = getASTMutationListener()) 369218893Sdim L->AddedCXXTemplateSpecialization(this, D); 370218893Sdim} 371218893Sdim 372212904SdimClassTemplatePartialSpecializationDecl * 373212904SdimClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, 374212904Sdim unsigned NumArgs, 375212904Sdim void *&InsertPos) { 376212904Sdim return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs, 377212904Sdim InsertPos); 378212904Sdim} 379212904Sdim 380218893Sdimvoid ClassTemplateDecl::AddPartialSpecialization( 381218893Sdim ClassTemplatePartialSpecializationDecl *D, 382218893Sdim void *InsertPos) { 383235633Sdim if (InsertPos) 384235633Sdim getPartialSpecializations().InsertNode(D, InsertPos); 385235633Sdim else { 386235633Sdim ClassTemplatePartialSpecializationDecl *Existing 387235633Sdim = getPartialSpecializations().GetOrInsertNode(D); 388235633Sdim (void)Existing; 389235633Sdim assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 390235633Sdim } 391235633Sdim 392218893Sdim if (ASTMutationListener *L = getASTMutationListener()) 393218893Sdim L->AddedCXXTemplateSpecialization(this, D); 394218893Sdim} 395218893Sdim 396207619Srdivackyvoid ClassTemplateDecl::getPartialSpecializations( 397226890Sdim SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) { 398245431Sdim llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs 399210299Sed = getPartialSpecializations(); 400207619Srdivacky PS.clear(); 401263509Sdim PS.reserve(PartialSpecs.size()); 402245431Sdim for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 403207619Srdivacky P = PartialSpecs.begin(), PEnd = PartialSpecs.end(); 404263509Sdim P != PEnd; ++P) 405263509Sdim PS.push_back(P->getMostRecentDecl()); 406207619Srdivacky} 407207619Srdivacky 408198092SrdivackyClassTemplatePartialSpecializationDecl * 409198092SrdivackyClassTemplateDecl::findPartialSpecialization(QualType T) { 410198092Srdivacky ASTContext &Context = getASTContext(); 411245431Sdim using llvm::FoldingSetVector; 412245431Sdim typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 413198092Srdivacky partial_spec_iterator; 414198092Srdivacky for (partial_spec_iterator P = getPartialSpecializations().begin(), 415198092Srdivacky PEnd = getPartialSpecializations().end(); 416198092Srdivacky P != PEnd; ++P) { 417207619Srdivacky if (Context.hasSameType(P->getInjectedSpecializationType(), T)) 418235633Sdim return P->getMostRecentDecl(); 419198092Srdivacky } 420198092Srdivacky 421198092Srdivacky return 0; 422198092Srdivacky} 423198092Srdivacky 424212904SdimClassTemplatePartialSpecializationDecl * 425212904SdimClassTemplateDecl::findPartialSpecInstantiatedFromMember( 426212904Sdim ClassTemplatePartialSpecializationDecl *D) { 427212904Sdim Decl *DCanon = D->getCanonicalDecl(); 428245431Sdim for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 429212904Sdim P = getPartialSpecializations().begin(), 430212904Sdim PEnd = getPartialSpecializations().end(); 431212904Sdim P != PEnd; ++P) { 432212904Sdim if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 433235633Sdim return P->getMostRecentDecl(); 434212904Sdim } 435212904Sdim 436212904Sdim return 0; 437212904Sdim} 438212904Sdim 439204962SrdivackyQualType 440210299SedClassTemplateDecl::getInjectedClassNameSpecialization() { 441210299Sed Common *CommonPtr = getCommonPtr(); 442193326Sed if (!CommonPtr->InjectedClassNameType.isNull()) 443193326Sed return CommonPtr->InjectedClassNameType; 444193326Sed 445218893Sdim // C++0x [temp.dep.type]p2: 446218893Sdim // The template argument list of a primary template is a template argument 447218893Sdim // list in which the nth template argument has the value of the nth template 448218893Sdim // parameter of the class template. If the nth template parameter is a 449218893Sdim // template parameter pack (14.5.3), the nth template argument is a pack 450218893Sdim // expansion (14.5.3) whose pattern is the name of the template parameter 451218893Sdim // pack. 452210299Sed ASTContext &Context = getASTContext(); 453193326Sed TemplateParameterList *Params = getTemplateParameters(); 454226890Sdim SmallVector<TemplateArgument, 16> TemplateArgs; 455221345Sdim TemplateArgs.resize(Params->size()); 456221345Sdim GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data()); 457193326Sed CommonPtr->InjectedClassNameType 458198092Srdivacky = Context.getTemplateSpecializationType(TemplateName(this), 459193326Sed &TemplateArgs[0], 460198092Srdivacky TemplateArgs.size()); 461193326Sed return CommonPtr->InjectedClassNameType; 462193326Sed} 463193326Sed 464193326Sed//===----------------------------------------------------------------------===// 465193326Sed// TemplateTypeParm Allocation/Deallocation Method Implementations 466193326Sed//===----------------------------------------------------------------------===// 467193326Sed 468193326SedTemplateTypeParmDecl * 469218893SdimTemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC, 470221345Sdim SourceLocation KeyLoc, SourceLocation NameLoc, 471221345Sdim unsigned D, unsigned P, IdentifierInfo *Id, 472221345Sdim bool Typename, bool ParameterPack) { 473221345Sdim TemplateTypeParmDecl *TTPDecl = 474221345Sdim new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename); 475221345Sdim QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 476221345Sdim TTPDecl->TypeForDecl = TTPType.getTypePtr(); 477221345Sdim return TTPDecl; 478193326Sed} 479193326Sed 480210299SedTemplateTypeParmDecl * 481235633SdimTemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { 482235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl)); 483235633Sdim return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(), 484235633Sdim 0, false); 485210299Sed} 486210299Sed 487198893SrdivackySourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 488221345Sdim return hasDefaultArgument() 489221345Sdim ? DefaultArgument->getTypeLoc().getBeginLoc() 490221345Sdim : SourceLocation(); 491198893Srdivacky} 492198893Srdivacky 493221345SdimSourceRange TemplateTypeParmDecl::getSourceRange() const { 494221345Sdim if (hasDefaultArgument() && !defaultArgumentWasInherited()) 495221345Sdim return SourceRange(getLocStart(), 496221345Sdim DefaultArgument->getTypeLoc().getEndLoc()); 497221345Sdim else 498221345Sdim return TypeDecl::getSourceRange(); 499221345Sdim} 500221345Sdim 501198893Srdivackyunsigned TemplateTypeParmDecl::getDepth() const { 502198893Srdivacky return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth(); 503198893Srdivacky} 504198893Srdivacky 505198893Srdivackyunsigned TemplateTypeParmDecl::getIndex() const { 506198893Srdivacky return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex(); 507198893Srdivacky} 508198893Srdivacky 509221345Sdimbool TemplateTypeParmDecl::isParameterPack() const { 510221345Sdim return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack(); 511221345Sdim} 512221345Sdim 513193326Sed//===----------------------------------------------------------------------===// 514193326Sed// NonTypeTemplateParmDecl Method Implementations 515193326Sed//===----------------------------------------------------------------------===// 516193326Sed 517218893SdimNonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 518221345Sdim SourceLocation StartLoc, 519221345Sdim SourceLocation IdLoc, 520221345Sdim unsigned D, unsigned P, 521221345Sdim IdentifierInfo *Id, 522218893Sdim QualType T, 523218893Sdim TypeSourceInfo *TInfo, 524218893Sdim const QualType *ExpandedTypes, 525218893Sdim unsigned NumExpandedTypes, 526218893Sdim TypeSourceInfo **ExpandedTInfos) 527221345Sdim : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 528218893Sdim TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false), 529218893Sdim ParameterPack(true), ExpandedParameterPack(true), 530218893Sdim NumExpandedTypes(NumExpandedTypes) 531218893Sdim{ 532218893Sdim if (ExpandedTypes && ExpandedTInfos) { 533218893Sdim void **TypesAndInfos = reinterpret_cast<void **>(this + 1); 534218893Sdim for (unsigned I = 0; I != NumExpandedTypes; ++I) { 535218893Sdim TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr(); 536218893Sdim TypesAndInfos[2*I + 1] = ExpandedTInfos[I]; 537218893Sdim } 538218893Sdim } 539218893Sdim} 540218893Sdim 541193326SedNonTypeTemplateParmDecl * 542218893SdimNonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 543221345Sdim SourceLocation StartLoc, SourceLocation IdLoc, 544221345Sdim unsigned D, unsigned P, IdentifierInfo *Id, 545221345Sdim QualType T, bool ParameterPack, 546221345Sdim TypeSourceInfo *TInfo) { 547221345Sdim return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 548221345Sdim T, ParameterPack, TInfo); 549193326Sed} 550193326Sed 551218893SdimNonTypeTemplateParmDecl * 552218893SdimNonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 553221345Sdim SourceLocation StartLoc, SourceLocation IdLoc, 554221345Sdim unsigned D, unsigned P, 555218893Sdim IdentifierInfo *Id, QualType T, 556218893Sdim TypeSourceInfo *TInfo, 557218893Sdim const QualType *ExpandedTypes, 558218893Sdim unsigned NumExpandedTypes, 559218893Sdim TypeSourceInfo **ExpandedTInfos) { 560218893Sdim unsigned Size = sizeof(NonTypeTemplateParmDecl) 561218893Sdim + NumExpandedTypes * 2 * sizeof(void*); 562218893Sdim void *Mem = C.Allocate(Size); 563221345Sdim return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, 564221345Sdim D, P, Id, T, TInfo, 565218893Sdim ExpandedTypes, NumExpandedTypes, 566218893Sdim ExpandedTInfos); 567218893Sdim} 568218893Sdim 569235633SdimNonTypeTemplateParmDecl * 570235633SdimNonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 571235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl)); 572235633Sdim return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 573235633Sdim SourceLocation(), 0, 0, 0, 574235633Sdim QualType(), false, 0); 575235633Sdim} 576235633Sdim 577235633SdimNonTypeTemplateParmDecl * 578235633SdimNonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 579235633Sdim unsigned NumExpandedTypes) { 580235633Sdim unsigned Size = sizeof(NonTypeTemplateParmDecl) 581235633Sdim + NumExpandedTypes * 2 * sizeof(void*); 582235633Sdim 583235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, Size); 584235633Sdim return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 585235633Sdim SourceLocation(), 0, 0, 0, 586235633Sdim QualType(), 0, 0, NumExpandedTypes, 587235633Sdim 0); 588235633Sdim} 589235633Sdim 590218893SdimSourceRange NonTypeTemplateParmDecl::getSourceRange() const { 591221345Sdim if (hasDefaultArgument() && !defaultArgumentWasInherited()) 592221345Sdim return SourceRange(getOuterLocStart(), 593221345Sdim getDefaultArgument()->getSourceRange().getEnd()); 594221345Sdim return DeclaratorDecl::getSourceRange(); 595218893Sdim} 596218893Sdim 597193326SedSourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 598210299Sed return hasDefaultArgument() 599210299Sed ? getDefaultArgument()->getSourceRange().getBegin() 600210299Sed : SourceLocation(); 601193326Sed} 602193326Sed 603193326Sed//===----------------------------------------------------------------------===// 604193326Sed// TemplateTemplateParmDecl Method Implementations 605193326Sed//===----------------------------------------------------------------------===// 606193326Sed 607235633Sdimvoid TemplateTemplateParmDecl::anchor() { } 608235633Sdim 609245431SdimTemplateTemplateParmDecl::TemplateTemplateParmDecl( 610245431Sdim DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 611245431Sdim IdentifierInfo *Id, TemplateParameterList *Params, 612245431Sdim unsigned NumExpansions, TemplateParameterList * const *Expansions) 613245431Sdim : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 614245431Sdim TemplateParmPosition(D, P), DefaultArgument(), 615245431Sdim DefaultArgumentWasInherited(false), ParameterPack(true), 616245431Sdim ExpandedParameterPack(true), NumExpandedParams(NumExpansions) { 617245431Sdim if (Expansions) 618245431Sdim std::memcpy(reinterpret_cast<void*>(this + 1), Expansions, 619245431Sdim sizeof(TemplateParameterList*) * NumExpandedParams); 620245431Sdim} 621245431Sdim 622193326SedTemplateTemplateParmDecl * 623218893SdimTemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 624193326Sed SourceLocation L, unsigned D, unsigned P, 625218893Sdim bool ParameterPack, IdentifierInfo *Id, 626193326Sed TemplateParameterList *Params) { 627218893Sdim return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 628218893Sdim Params); 629193326Sed} 630193326Sed 631235633SdimTemplateTemplateParmDecl * 632245431SdimTemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 633245431Sdim SourceLocation L, unsigned D, unsigned P, 634245431Sdim IdentifierInfo *Id, 635245431Sdim TemplateParameterList *Params, 636252723Sdim ArrayRef<TemplateParameterList *> Expansions) { 637245431Sdim void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) + 638245431Sdim sizeof(TemplateParameterList*) * Expansions.size()); 639245431Sdim return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params, 640245431Sdim Expansions.size(), 641245431Sdim Expansions.data()); 642245431Sdim} 643245431Sdim 644245431SdimTemplateTemplateParmDecl * 645235633SdimTemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 646235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl)); 647235633Sdim return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false, 648235633Sdim 0, 0); 649235633Sdim} 650235633Sdim 651245431SdimTemplateTemplateParmDecl * 652245431SdimTemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 653245431Sdim unsigned NumExpansions) { 654245431Sdim unsigned Size = sizeof(TemplateTemplateParmDecl) + 655245431Sdim sizeof(TemplateParameterList*) * NumExpansions; 656245431Sdim void *Mem = AllocateDeserializedDecl(C, ID, Size); 657245431Sdim return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0, 658245431Sdim NumExpansions, 0); 659245431Sdim} 660245431Sdim 661193326Sed//===----------------------------------------------------------------------===// 662193326Sed// TemplateArgumentList Implementation 663193326Sed//===----------------------------------------------------------------------===// 664218893SdimTemplateArgumentList * 665218893SdimTemplateArgumentList::CreateCopy(ASTContext &Context, 666218893Sdim const TemplateArgument *Args, 667218893Sdim unsigned NumArgs) { 668218893Sdim std::size_t Size = sizeof(TemplateArgumentList) 669218893Sdim + NumArgs * sizeof(TemplateArgument); 670218893Sdim void *Mem = Context.Allocate(Size); 671218893Sdim TemplateArgument *StoredArgs 672218893Sdim = reinterpret_cast<TemplateArgument *>( 673218893Sdim static_cast<TemplateArgumentList *>(Mem) + 1); 674218893Sdim std::uninitialized_copy(Args, Args + NumArgs, StoredArgs); 675218893Sdim return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true); 676193326Sed} 677193326Sed 678226890SdimFunctionTemplateSpecializationInfo * 679226890SdimFunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 680226890Sdim FunctionTemplateDecl *Template, 681226890Sdim TemplateSpecializationKind TSK, 682226890Sdim const TemplateArgumentList *TemplateArgs, 683226890Sdim const TemplateArgumentListInfo *TemplateArgsAsWritten, 684226890Sdim SourceLocation POI) { 685226890Sdim const ASTTemplateArgumentListInfo *ArgsAsWritten = 0; 686226890Sdim if (TemplateArgsAsWritten) 687226890Sdim ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 688226890Sdim *TemplateArgsAsWritten); 689226890Sdim 690226890Sdim return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 691226890Sdim TemplateArgs, 692226890Sdim ArgsAsWritten, 693226890Sdim POI); 694226890Sdim} 695226890Sdim 696193326Sed//===----------------------------------------------------------------------===// 697235633Sdim// TemplateDecl Implementation 698235633Sdim//===----------------------------------------------------------------------===// 699235633Sdim 700235633Sdimvoid TemplateDecl::anchor() { } 701235633Sdim 702235633Sdim//===----------------------------------------------------------------------===// 703193326Sed// ClassTemplateSpecializationDecl Implementation 704193326Sed//===----------------------------------------------------------------------===// 705193326SedClassTemplateSpecializationDecl:: 706208600SrdivackyClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 707221345Sdim DeclContext *DC, SourceLocation StartLoc, 708221345Sdim SourceLocation IdLoc, 709193326Sed ClassTemplateDecl *SpecializedTemplate, 710218893Sdim const TemplateArgument *Args, 711218893Sdim unsigned NumArgs, 712198092Srdivacky ClassTemplateSpecializationDecl *PrevDecl) 713221345Sdim : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc, 714198092Srdivacky SpecializedTemplate->getIdentifier(), 715198092Srdivacky PrevDecl), 716193326Sed SpecializedTemplate(SpecializedTemplate), 717210299Sed ExplicitInfo(0), 718218893Sdim TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 719193326Sed SpecializationKind(TSK_Undeclared) { 720193326Sed} 721198092Srdivacky 722210299SedClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK) 723221345Sdim : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0), 724210299Sed ExplicitInfo(0), 725210299Sed SpecializationKind(TSK_Undeclared) { 726210299Sed} 727210299Sed 728193326SedClassTemplateSpecializationDecl * 729208600SrdivackyClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 730221345Sdim DeclContext *DC, 731221345Sdim SourceLocation StartLoc, 732221345Sdim SourceLocation IdLoc, 733193326Sed ClassTemplateDecl *SpecializedTemplate, 734218893Sdim const TemplateArgument *Args, 735218893Sdim unsigned NumArgs, 736193326Sed ClassTemplateSpecializationDecl *PrevDecl) { 737193326Sed ClassTemplateSpecializationDecl *Result 738198092Srdivacky = new (Context)ClassTemplateSpecializationDecl(Context, 739193326Sed ClassTemplateSpecialization, 740221345Sdim TK, DC, StartLoc, IdLoc, 741193326Sed SpecializedTemplate, 742218893Sdim Args, NumArgs, 743198092Srdivacky PrevDecl); 744252723Sdim Result->MayHaveOutOfDateDef = false; 745252723Sdim 746193326Sed Context.getTypeDeclType(Result, PrevDecl); 747193326Sed return Result; 748193326Sed} 749193326Sed 750210299SedClassTemplateSpecializationDecl * 751235633SdimClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 752235633Sdim unsigned ID) { 753235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, 754235633Sdim sizeof(ClassTemplateSpecializationDecl)); 755252723Sdim ClassTemplateSpecializationDecl *Result = 756252723Sdim new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization); 757252723Sdim Result->MayHaveOutOfDateDef = false; 758252723Sdim return Result; 759210299Sed} 760210299Sed 761252723Sdimvoid ClassTemplateSpecializationDecl::getNameForDiagnostic( 762252723Sdim raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 763252723Sdim NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 764198092Srdivacky 765198092Srdivacky const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 766252723Sdim TemplateSpecializationType::PrintTemplateArgumentList( 767252723Sdim OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 768198092Srdivacky} 769198092Srdivacky 770198092SrdivackyClassTemplateDecl * 771198092SrdivackyClassTemplateSpecializationDecl::getSpecializedTemplate() const { 772198092Srdivacky if (SpecializedPartialSpecialization *PartialSpec 773198092Srdivacky = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 774198092Srdivacky return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 775198092Srdivacky return SpecializedTemplate.get<ClassTemplateDecl*>(); 776198092Srdivacky} 777198092Srdivacky 778221345SdimSourceRange 779221345SdimClassTemplateSpecializationDecl::getSourceRange() const { 780226890Sdim if (ExplicitInfo) { 781245431Sdim SourceLocation Begin = getTemplateKeywordLoc(); 782245431Sdim if (Begin.isValid()) { 783245431Sdim // Here we have an explicit (partial) specialization or instantiation. 784245431Sdim assert(getSpecializationKind() == TSK_ExplicitSpecialization || 785245431Sdim getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || 786245431Sdim getSpecializationKind() == TSK_ExplicitInstantiationDefinition); 787245431Sdim if (getExternLoc().isValid()) 788245431Sdim Begin = getExternLoc(); 789245431Sdim SourceLocation End = getRBraceLoc(); 790245431Sdim if (End.isInvalid()) 791245431Sdim End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 792245431Sdim return SourceRange(Begin, End); 793245431Sdim } 794245431Sdim // An implicit instantiation of a class template partial specialization 795245431Sdim // uses ExplicitInfo to record the TypeAsWritten, but the source 796245431Sdim // locations should be retrieved from the instantiation pattern. 797245431Sdim typedef ClassTemplatePartialSpecializationDecl CTPSDecl; 798245431Sdim CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this)); 799245431Sdim CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); 800245431Sdim assert(inst_from != 0); 801245431Sdim return inst_from->getSourceRange(); 802226890Sdim } 803226890Sdim else { 804226890Sdim // No explicit info available. 805226890Sdim llvm::PointerUnion<ClassTemplateDecl *, 806226890Sdim ClassTemplatePartialSpecializationDecl *> 807226890Sdim inst_from = getInstantiatedFrom(); 808226890Sdim if (inst_from.isNull()) 809226890Sdim return getSpecializedTemplate()->getSourceRange(); 810226890Sdim if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>()) 811226890Sdim return ctd->getSourceRange(); 812226890Sdim return inst_from.get<ClassTemplatePartialSpecializationDecl*>() 813226890Sdim ->getSourceRange(); 814226890Sdim } 815221345Sdim} 816221345Sdim 817193326Sed//===----------------------------------------------------------------------===// 818193326Sed// ClassTemplatePartialSpecializationDecl Implementation 819193326Sed//===----------------------------------------------------------------------===// 820235633Sdimvoid ClassTemplatePartialSpecializationDecl::anchor() { } 821235633Sdim 822221345SdimClassTemplatePartialSpecializationDecl:: 823221345SdimClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 824221345Sdim DeclContext *DC, 825221345Sdim SourceLocation StartLoc, 826221345Sdim SourceLocation IdLoc, 827221345Sdim TemplateParameterList *Params, 828221345Sdim ClassTemplateDecl *SpecializedTemplate, 829221345Sdim const TemplateArgument *Args, 830221345Sdim unsigned NumArgs, 831263509Sdim const ASTTemplateArgumentListInfo *ArgInfos, 832263509Sdim ClassTemplatePartialSpecializationDecl *PrevDecl) 833221345Sdim : ClassTemplateSpecializationDecl(Context, 834221345Sdim ClassTemplatePartialSpecialization, 835221345Sdim TK, DC, StartLoc, IdLoc, 836221345Sdim SpecializedTemplate, 837221345Sdim Args, NumArgs, PrevDecl), 838221345Sdim TemplateParams(Params), ArgsAsWritten(ArgInfos), 839221345Sdim InstantiatedFromMember(0, false) 840263509Sdim{ 841221345Sdim AdoptTemplateParameterList(Params, this); 842221345Sdim} 843221345Sdim 844193326SedClassTemplatePartialSpecializationDecl * 845193326SedClassTemplatePartialSpecializationDecl:: 846221345SdimCreate(ASTContext &Context, TagKind TK,DeclContext *DC, 847221345Sdim SourceLocation StartLoc, SourceLocation IdLoc, 848193326Sed TemplateParameterList *Params, 849193326Sed ClassTemplateDecl *SpecializedTemplate, 850218893Sdim const TemplateArgument *Args, 851218893Sdim unsigned NumArgs, 852199990Srdivacky const TemplateArgumentListInfo &ArgInfos, 853204962Srdivacky QualType CanonInjectedType, 854263509Sdim ClassTemplatePartialSpecializationDecl *PrevDecl) { 855263509Sdim const ASTTemplateArgumentListInfo *ASTArgInfos = 856263509Sdim ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 857198893Srdivacky 858193326Sed ClassTemplatePartialSpecializationDecl *Result 859221345Sdim = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC, 860221345Sdim StartLoc, IdLoc, 861221345Sdim Params, 862193326Sed SpecializedTemplate, 863218893Sdim Args, NumArgs, 864263509Sdim ASTArgInfos, 865263509Sdim PrevDecl); 866193326Sed Result->setSpecializationKind(TSK_ExplicitSpecialization); 867252723Sdim Result->MayHaveOutOfDateDef = false; 868204962Srdivacky 869204962Srdivacky Context.getInjectedClassNameType(Result, CanonInjectedType); 870193326Sed return Result; 871193326Sed} 872198092Srdivacky 873210299SedClassTemplatePartialSpecializationDecl * 874235633SdimClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 875235633Sdim unsigned ID) { 876235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, 877235633Sdim sizeof(ClassTemplatePartialSpecializationDecl)); 878252723Sdim ClassTemplatePartialSpecializationDecl *Result 879252723Sdim = new (Mem) ClassTemplatePartialSpecializationDecl(); 880252723Sdim Result->MayHaveOutOfDateDef = false; 881252723Sdim return Result; 882210299Sed} 883210299Sed 884198092Srdivacky//===----------------------------------------------------------------------===// 885198092Srdivacky// FriendTemplateDecl Implementation 886198092Srdivacky//===----------------------------------------------------------------------===// 887198092Srdivacky 888235633Sdimvoid FriendTemplateDecl::anchor() { } 889235633Sdim 890198092SrdivackyFriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 891198092Srdivacky DeclContext *DC, 892198092Srdivacky SourceLocation L, 893198092Srdivacky unsigned NParams, 894198092Srdivacky TemplateParameterList **Params, 895198092Srdivacky FriendUnion Friend, 896198092Srdivacky SourceLocation FLoc) { 897198092Srdivacky FriendTemplateDecl *Result 898198092Srdivacky = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc); 899198092Srdivacky return Result; 900198092Srdivacky} 901212904Sdim 902235633SdimFriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 903235633Sdim unsigned ID) { 904235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl)); 905235633Sdim return new (Mem) FriendTemplateDecl(EmptyShell()); 906212904Sdim} 907223017Sdim 908223017Sdim//===----------------------------------------------------------------------===// 909223017Sdim// TypeAliasTemplateDecl Implementation 910223017Sdim//===----------------------------------------------------------------------===// 911223017Sdim 912223017SdimTypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 913223017Sdim DeclContext *DC, 914223017Sdim SourceLocation L, 915223017Sdim DeclarationName Name, 916223017Sdim TemplateParameterList *Params, 917223017Sdim NamedDecl *Decl) { 918223017Sdim AdoptTemplateParameterList(Params, DC); 919223017Sdim return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl); 920223017Sdim} 921223017Sdim 922235633SdimTypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 923235633Sdim unsigned ID) { 924235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl)); 925235633Sdim return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(), 926235633Sdim 0, 0); 927223017Sdim} 928223017Sdim 929223017Sdimvoid TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) { 930223017Sdim static_cast<Common *>(Ptr)->~Common(); 931223017Sdim} 932223017SdimRedeclarableTemplateDecl::CommonBase * 933252723SdimTypeAliasTemplateDecl::newCommon(ASTContext &C) const { 934223017Sdim Common *CommonPtr = new (C) Common; 935223017Sdim C.AddDeallocation(DeallocateCommon, CommonPtr); 936223017Sdim return CommonPtr; 937223017Sdim} 938223017Sdim 939235633Sdim//===----------------------------------------------------------------------===// 940235633Sdim// ClassScopeFunctionSpecializationDecl Implementation 941235633Sdim//===----------------------------------------------------------------------===// 942235633Sdim 943235633Sdimvoid ClassScopeFunctionSpecializationDecl::anchor() { } 944235633Sdim 945235633SdimClassScopeFunctionSpecializationDecl * 946235633SdimClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 947235633Sdim unsigned ID) { 948235633Sdim void *Mem = AllocateDeserializedDecl(C, ID, 949235633Sdim sizeof(ClassScopeFunctionSpecializationDecl)); 950245431Sdim return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0, 951245431Sdim false, TemplateArgumentListInfo()); 952235633Sdim} 953263509Sdim 954263509Sdim//===----------------------------------------------------------------------===// 955263509Sdim// VarTemplateDecl Implementation 956263509Sdim//===----------------------------------------------------------------------===// 957263509Sdim 958263509Sdimvoid VarTemplateDecl::DeallocateCommon(void *Ptr) { 959263509Sdim static_cast<Common *>(Ptr)->~Common(); 960263509Sdim} 961263509Sdim 962263509SdimVarTemplateDecl *VarTemplateDecl::getDefinition() { 963263509Sdim VarTemplateDecl *CurD = this; 964263509Sdim while (CurD) { 965263509Sdim if (CurD->isThisDeclarationADefinition()) 966263509Sdim return CurD; 967263509Sdim CurD = CurD->getPreviousDecl(); 968263509Sdim } 969263509Sdim return 0; 970263509Sdim} 971263509Sdim 972263509SdimVarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 973263509Sdim SourceLocation L, DeclarationName Name, 974263509Sdim TemplateParameterList *Params, 975263509Sdim NamedDecl *Decl, 976263509Sdim VarTemplateDecl *PrevDecl) { 977263509Sdim VarTemplateDecl *New = new (C) VarTemplateDecl(DC, L, Name, Params, Decl); 978263509Sdim New->setPreviousDecl(PrevDecl); 979263509Sdim return New; 980263509Sdim} 981263509Sdim 982263509SdimVarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 983263509Sdim unsigned ID) { 984263509Sdim void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarTemplateDecl)); 985263509Sdim return new (Mem) VarTemplateDecl(EmptyShell()); 986263509Sdim} 987263509Sdim 988263509Sdim// TODO: Unify accross class, function and variable templates? 989263509Sdim// May require moving this and Common to RedeclarableTemplateDecl. 990263509Sdimvoid VarTemplateDecl::LoadLazySpecializations() const { 991263509Sdim Common *CommonPtr = getCommonPtr(); 992263509Sdim if (CommonPtr->LazySpecializations) { 993263509Sdim ASTContext &Context = getASTContext(); 994263509Sdim uint32_t *Specs = CommonPtr->LazySpecializations; 995263509Sdim CommonPtr->LazySpecializations = 0; 996263509Sdim for (uint32_t I = 0, N = *Specs++; I != N; ++I) 997263509Sdim (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 998263509Sdim } 999263509Sdim} 1000263509Sdim 1001263509Sdimllvm::FoldingSetVector<VarTemplateSpecializationDecl> & 1002263509SdimVarTemplateDecl::getSpecializations() const { 1003263509Sdim LoadLazySpecializations(); 1004263509Sdim return getCommonPtr()->Specializations; 1005263509Sdim} 1006263509Sdim 1007263509Sdimllvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 1008263509SdimVarTemplateDecl::getPartialSpecializations() { 1009263509Sdim LoadLazySpecializations(); 1010263509Sdim return getCommonPtr()->PartialSpecializations; 1011263509Sdim} 1012263509Sdim 1013263509SdimRedeclarableTemplateDecl::CommonBase * 1014263509SdimVarTemplateDecl::newCommon(ASTContext &C) const { 1015263509Sdim Common *CommonPtr = new (C) Common; 1016263509Sdim C.AddDeallocation(DeallocateCommon, CommonPtr); 1017263509Sdim return CommonPtr; 1018263509Sdim} 1019263509Sdim 1020263509SdimVarTemplateSpecializationDecl * 1021263509SdimVarTemplateDecl::findSpecialization(const TemplateArgument *Args, 1022263509Sdim unsigned NumArgs, void *&InsertPos) { 1023263509Sdim return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 1024263509Sdim} 1025263509Sdim 1026263509Sdimvoid VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 1027263509Sdim void *InsertPos) { 1028263509Sdim if (InsertPos) 1029263509Sdim getSpecializations().InsertNode(D, InsertPos); 1030263509Sdim else { 1031263509Sdim VarTemplateSpecializationDecl *Existing = 1032263509Sdim getSpecializations().GetOrInsertNode(D); 1033263509Sdim (void)Existing; 1034263509Sdim assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1035263509Sdim } 1036263509Sdim if (ASTMutationListener *L = getASTMutationListener()) 1037263509Sdim L->AddedCXXTemplateSpecialization(this, D); 1038263509Sdim} 1039263509Sdim 1040263509SdimVarTemplatePartialSpecializationDecl * 1041263509SdimVarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, 1042263509Sdim unsigned NumArgs, void *&InsertPos) { 1043263509Sdim return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs, 1044263509Sdim InsertPos); 1045263509Sdim} 1046263509Sdim 1047263509Sdimvoid VarTemplateDecl::AddPartialSpecialization( 1048263509Sdim VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 1049263509Sdim if (InsertPos) 1050263509Sdim getPartialSpecializations().InsertNode(D, InsertPos); 1051263509Sdim else { 1052263509Sdim VarTemplatePartialSpecializationDecl *Existing = 1053263509Sdim getPartialSpecializations().GetOrInsertNode(D); 1054263509Sdim (void)Existing; 1055263509Sdim assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1056263509Sdim } 1057263509Sdim 1058263509Sdim if (ASTMutationListener *L = getASTMutationListener()) 1059263509Sdim L->AddedCXXTemplateSpecialization(this, D); 1060263509Sdim} 1061263509Sdim 1062263509Sdimvoid VarTemplateDecl::getPartialSpecializations( 1063263509Sdim SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) { 1064263509Sdim llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 1065263509Sdim getPartialSpecializations(); 1066263509Sdim PS.clear(); 1067263509Sdim PS.reserve(PartialSpecs.size()); 1068263509Sdim for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 1069263509Sdim P = PartialSpecs.begin(), 1070263509Sdim PEnd = PartialSpecs.end(); 1071263509Sdim P != PEnd; ++P) 1072263509Sdim PS.push_back(P->getMostRecentDecl()); 1073263509Sdim} 1074263509Sdim 1075263509SdimVarTemplatePartialSpecializationDecl * 1076263509SdimVarTemplateDecl::findPartialSpecInstantiatedFromMember( 1077263509Sdim VarTemplatePartialSpecializationDecl *D) { 1078263509Sdim Decl *DCanon = D->getCanonicalDecl(); 1079263509Sdim for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 1080263509Sdim P = getPartialSpecializations().begin(), 1081263509Sdim PEnd = getPartialSpecializations().end(); 1082263509Sdim P != PEnd; ++P) { 1083263509Sdim if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1084263509Sdim return P->getMostRecentDecl(); 1085263509Sdim } 1086263509Sdim 1087263509Sdim return 0; 1088263509Sdim} 1089263509Sdim 1090263509Sdim//===----------------------------------------------------------------------===// 1091263509Sdim// VarTemplateSpecializationDecl Implementation 1092263509Sdim//===----------------------------------------------------------------------===// 1093263509SdimVarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1094263509Sdim ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc, 1095263509Sdim SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1096263509Sdim TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 1097263509Sdim unsigned NumArgs) 1098263509Sdim : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T, 1099263509Sdim TInfo, S), 1100263509Sdim SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0), 1101263509Sdim TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 1102263509Sdim SpecializationKind(TSK_Undeclared) {} 1103263509Sdim 1104263509SdimVarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK) 1105263509Sdim : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0, 1106263509Sdim SC_None), 1107263509Sdim ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {} 1108263509Sdim 1109263509SdimVarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1110263509Sdim ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1111263509Sdim SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1112263509Sdim TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 1113263509Sdim unsigned NumArgs) { 1114263509Sdim VarTemplateSpecializationDecl *Result = new (Context) 1115263509Sdim VarTemplateSpecializationDecl(Context, VarTemplateSpecialization, DC, 1116263509Sdim StartLoc, IdLoc, SpecializedTemplate, T, 1117263509Sdim TInfo, S, Args, NumArgs); 1118263509Sdim return Result; 1119263509Sdim} 1120263509Sdim 1121263509SdimVarTemplateSpecializationDecl * 1122263509SdimVarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1123263509Sdim void *Mem = 1124263509Sdim AllocateDeserializedDecl(C, ID, sizeof(VarTemplateSpecializationDecl)); 1125263509Sdim VarTemplateSpecializationDecl *Result = 1126263509Sdim new (Mem) VarTemplateSpecializationDecl(VarTemplateSpecialization); 1127263509Sdim return Result; 1128263509Sdim} 1129263509Sdim 1130263509Sdimvoid VarTemplateSpecializationDecl::getNameForDiagnostic( 1131263509Sdim raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1132263509Sdim NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1133263509Sdim 1134263509Sdim const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1135263509Sdim TemplateSpecializationType::PrintTemplateArgumentList( 1136263509Sdim OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 1137263509Sdim} 1138263509Sdim 1139263509SdimVarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1140263509Sdim if (SpecializedPartialSpecialization *PartialSpec = 1141263509Sdim SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1142263509Sdim return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1143263509Sdim return SpecializedTemplate.get<VarTemplateDecl *>(); 1144263509Sdim} 1145263509Sdim 1146263509Sdimvoid VarTemplateSpecializationDecl::setTemplateArgsInfo( 1147263509Sdim const TemplateArgumentListInfo &ArgsInfo) { 1148263509Sdim unsigned N = ArgsInfo.size(); 1149263509Sdim TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc()); 1150263509Sdim TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc()); 1151263509Sdim for (unsigned I = 0; I != N; ++I) 1152263509Sdim TemplateArgsInfo.addArgument(ArgsInfo[I]); 1153263509Sdim} 1154263509Sdim 1155263509Sdim//===----------------------------------------------------------------------===// 1156263509Sdim// VarTemplatePartialSpecializationDecl Implementation 1157263509Sdim//===----------------------------------------------------------------------===// 1158263509Sdimvoid VarTemplatePartialSpecializationDecl::anchor() {} 1159263509Sdim 1160263509SdimVarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1161263509Sdim ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1162263509Sdim SourceLocation IdLoc, TemplateParameterList *Params, 1163263509Sdim VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1164263509Sdim StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 1165263509Sdim const ASTTemplateArgumentListInfo *ArgInfos) 1166263509Sdim : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization, 1167263509Sdim DC, StartLoc, IdLoc, SpecializedTemplate, T, 1168263509Sdim TInfo, S, Args, NumArgs), 1169263509Sdim TemplateParams(Params), ArgsAsWritten(ArgInfos), 1170263509Sdim InstantiatedFromMember(0, false) { 1171263509Sdim // TODO: The template parameters should be in DC by now. Verify. 1172263509Sdim // AdoptTemplateParameterList(Params, DC); 1173263509Sdim} 1174263509Sdim 1175263509SdimVarTemplatePartialSpecializationDecl * 1176263509SdimVarTemplatePartialSpecializationDecl::Create( 1177263509Sdim ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1178263509Sdim SourceLocation IdLoc, TemplateParameterList *Params, 1179263509Sdim VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1180263509Sdim StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 1181263509Sdim const TemplateArgumentListInfo &ArgInfos) { 1182263509Sdim const ASTTemplateArgumentListInfo *ASTArgInfos 1183263509Sdim = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 1184263509Sdim 1185263509Sdim VarTemplatePartialSpecializationDecl *Result = 1186263509Sdim new (Context) VarTemplatePartialSpecializationDecl( 1187263509Sdim Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, 1188263509Sdim S, Args, NumArgs, ASTArgInfos); 1189263509Sdim Result->setSpecializationKind(TSK_ExplicitSpecialization); 1190263509Sdim return Result; 1191263509Sdim} 1192263509Sdim 1193263509SdimVarTemplatePartialSpecializationDecl * 1194263509SdimVarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1195263509Sdim unsigned ID) { 1196263509Sdim void *Mem = AllocateDeserializedDecl( 1197263509Sdim C, ID, sizeof(VarTemplatePartialSpecializationDecl)); 1198263509Sdim VarTemplatePartialSpecializationDecl *Result = 1199263509Sdim new (Mem) VarTemplatePartialSpecializationDecl(); 1200263509Sdim return Result; 1201263509Sdim} 1202