clang API Documentation

DeclTemplate.cpp
Go to the documentation of this file.
00001 //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the C++ related Decl classes for templates.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/AST/DeclTemplate.h"
00015 #include "clang/AST/ASTContext.h"
00016 #include "clang/AST/ASTMutationListener.h"
00017 #include "clang/AST/DeclCXX.h"
00018 #include "clang/AST/Expr.h"
00019 #include "clang/AST/ExprCXX.h"
00020 #include "clang/AST/TypeLoc.h"
00021 #include "clang/Basic/IdentifierTable.h"
00022 #include "llvm/ADT/STLExtras.h"
00023 #include <memory>
00024 using namespace clang;
00025 
00026 //===----------------------------------------------------------------------===//
00027 // TemplateParameterList Implementation
00028 //===----------------------------------------------------------------------===//
00029 
00030 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
00031                                              SourceLocation LAngleLoc,
00032                                              NamedDecl **Params, unsigned NumParams,
00033                                              SourceLocation RAngleLoc)
00034   : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
00035     NumParams(NumParams), ContainsUnexpandedParameterPack(false) {
00036   assert(this->NumParams == NumParams && "Too many template parameters");
00037   for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
00038     NamedDecl *P = Params[Idx];
00039     begin()[Idx] = P;
00040 
00041     if (!P->isTemplateParameterPack()) {
00042       if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
00043         if (NTTP->getType()->containsUnexpandedParameterPack())
00044           ContainsUnexpandedParameterPack = true;
00045 
00046       if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
00047         if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
00048           ContainsUnexpandedParameterPack = true;
00049 
00050       // FIXME: If a default argument contains an unexpanded parameter pack, the
00051       // template parameter list does too.
00052     }
00053   }
00054 }
00055 
00056 TemplateParameterList *
00057 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
00058                               SourceLocation LAngleLoc, NamedDecl **Params,
00059                               unsigned NumParams, SourceLocation RAngleLoc) {
00060   unsigned Size = sizeof(TemplateParameterList) 
00061                 + sizeof(NamedDecl *) * NumParams;
00062   unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
00063                             llvm::alignOf<NamedDecl*>());
00064   void *Mem = C.Allocate(Size, Align);
00065   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
00066                                          NumParams, RAngleLoc);
00067 }
00068 
00069 unsigned TemplateParameterList::getMinRequiredArguments() const {
00070   unsigned NumRequiredArgs = 0;
00071   for (iterator P = const_cast<TemplateParameterList *>(this)->begin(), 
00072              PEnd = const_cast<TemplateParameterList *>(this)->end(); 
00073        P != PEnd; ++P) {
00074     if ((*P)->isTemplateParameterPack()) {
00075       if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
00076         if (NTTP->isExpandedParameterPack()) {
00077           NumRequiredArgs += NTTP->getNumExpansionTypes();
00078           continue;
00079         }
00080       
00081       break;
00082     }
00083   
00084     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
00085       if (TTP->hasDefaultArgument())
00086         break;
00087     } else if (NonTypeTemplateParmDecl *NTTP 
00088                                     = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
00089       if (NTTP->hasDefaultArgument())
00090         break;
00091     } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
00092       break;
00093     
00094     ++NumRequiredArgs;
00095   }
00096   
00097   return NumRequiredArgs;
00098 }
00099 
00100 unsigned TemplateParameterList::getDepth() const {
00101   if (size() == 0)
00102     return 0;
00103   
00104   const NamedDecl *FirstParm = getParam(0);
00105   if (const TemplateTypeParmDecl *TTP
00106         = dyn_cast<TemplateTypeParmDecl>(FirstParm))
00107     return TTP->getDepth();
00108   else if (const NonTypeTemplateParmDecl *NTTP 
00109              = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
00110     return NTTP->getDepth();
00111   else
00112     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
00113 }
00114 
00115 static void AdoptTemplateParameterList(TemplateParameterList *Params,
00116                                        DeclContext *Owner) {
00117   for (TemplateParameterList::iterator P = Params->begin(), 
00118                                     PEnd = Params->end();
00119        P != PEnd; ++P) {
00120     (*P)->setDeclContext(Owner);
00121     
00122     if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
00123       AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
00124   }
00125 }
00126 
00127 //===----------------------------------------------------------------------===//
00128 // RedeclarableTemplateDecl Implementation
00129 //===----------------------------------------------------------------------===//
00130 
00131 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
00132   if (Common)
00133     return Common;
00134 
00135   // Walk the previous-declaration chain until we either find a declaration
00136   // with a common pointer or we run out of previous declarations.
00137   SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
00138   for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
00139        Prev = Prev->getPreviousDecl()) {
00140     if (Prev->Common) {
00141       Common = Prev->Common;
00142       break;
00143     }
00144 
00145     PrevDecls.push_back(Prev);
00146   }
00147 
00148   // If we never found a common pointer, allocate one now.
00149   if (!Common) {
00150     // FIXME: If any of the declarations is from an AST file, we probably
00151     // need an update record to add the common data.
00152 
00153     Common = newCommon(getASTContext());
00154   }
00155 
00156   // Update any previous declarations we saw with the common pointer.
00157   for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
00158     PrevDecls[I]->Common = Common;
00159 
00160   return Common;
00161 }
00162 
00163 template <class EntryType>
00164 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
00165 RedeclarableTemplateDecl::findSpecializationImpl(
00166                                  llvm::FoldingSetVector<EntryType> &Specs,
00167                                  ArrayRef<TemplateArgument> Args,
00168                                  void *&InsertPos) {
00169   typedef SpecEntryTraits<EntryType> SETraits;
00170   llvm::FoldingSetNodeID ID;
00171   EntryType::Profile(ID,Args, getASTContext());
00172   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
00173   return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr;
00174 }
00175 
00176 /// \brief Generate the injected template arguments for the given template
00177 /// parameter list, e.g., for the injected-class-name of a class template.
00178 static void GenerateInjectedTemplateArgs(ASTContext &Context,
00179                                         TemplateParameterList *Params,
00180                                          TemplateArgument *Args) {
00181   for (TemplateParameterList::iterator Param = Params->begin(),
00182                                     ParamEnd = Params->end();
00183        Param != ParamEnd; ++Param) {
00184     TemplateArgument Arg;
00185     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
00186       QualType ArgType = Context.getTypeDeclType(TTP);
00187       if (TTP->isParameterPack())
00188         ArgType = Context.getPackExpansionType(ArgType, None);
00189 
00190       Arg = TemplateArgument(ArgType);
00191     } else if (NonTypeTemplateParmDecl *NTTP =
00192                dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
00193       Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
00194                                   NTTP->getType().getNonLValueExprType(Context),
00195                                   Expr::getValueKindForType(NTTP->getType()),
00196                                           NTTP->getLocation());
00197       
00198       if (NTTP->isParameterPack())
00199         E = new (Context) PackExpansionExpr(Context.DependentTy, E,
00200                                             NTTP->getLocation(), None);
00201       Arg = TemplateArgument(E);
00202     } else {
00203       TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
00204       if (TTP->isParameterPack())
00205         Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
00206       else
00207         Arg = TemplateArgument(TemplateName(TTP));
00208     }
00209     
00210     if ((*Param)->isTemplateParameterPack())
00211       Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
00212     
00213     *Args++ = Arg;
00214   }
00215 }
00216                                       
00217 //===----------------------------------------------------------------------===//
00218 // FunctionTemplateDecl Implementation
00219 //===----------------------------------------------------------------------===//
00220 
00221 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
00222   static_cast<Common *>(Ptr)->~Common();
00223 }
00224 
00225 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
00226                                                    DeclContext *DC,
00227                                                    SourceLocation L,
00228                                                    DeclarationName Name,
00229                                                TemplateParameterList *Params,
00230                                                    NamedDecl *Decl) {
00231   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
00232   return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
00233 }
00234 
00235 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
00236                                                                unsigned ID) {
00237   return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
00238                                           DeclarationName(), nullptr, nullptr);
00239 }
00240 
00241 RedeclarableTemplateDecl::CommonBase *
00242 FunctionTemplateDecl::newCommon(ASTContext &C) const {
00243   Common *CommonPtr = new (C) Common;
00244   C.AddDeallocation(DeallocateCommon, CommonPtr);
00245   return CommonPtr;
00246 }
00247 
00248 void FunctionTemplateDecl::LoadLazySpecializations() const {
00249   Common *CommonPtr = getCommonPtr();
00250   if (CommonPtr->LazySpecializations) {
00251     ASTContext &Context = getASTContext();
00252     uint32_t *Specs = CommonPtr->LazySpecializations;
00253     CommonPtr->LazySpecializations = nullptr;
00254     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
00255       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
00256   }
00257 }
00258 
00259 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
00260 FunctionTemplateDecl::getSpecializations() const {
00261   LoadLazySpecializations();
00262   return getCommonPtr()->Specializations;
00263 }
00264 
00265 FunctionDecl *
00266 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
00267                                          void *&InsertPos) {
00268   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
00269 }
00270 
00271 void FunctionTemplateDecl::addSpecialization(
00272       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
00273   if (InsertPos)
00274     getSpecializations().InsertNode(Info, InsertPos);
00275   else
00276     getSpecializations().GetOrInsertNode(Info);
00277   if (ASTMutationListener *L = getASTMutationListener())
00278     L->AddedCXXTemplateSpecialization(this, Info->Function);
00279 }
00280 
00281 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
00282   TemplateParameterList *Params = getTemplateParameters();
00283   Common *CommonPtr = getCommonPtr();
00284   if (!CommonPtr->InjectedArgs) {
00285     CommonPtr->InjectedArgs
00286       = new (getASTContext()) TemplateArgument[Params->size()];
00287     GenerateInjectedTemplateArgs(getASTContext(), Params,
00288                                  CommonPtr->InjectedArgs);
00289   }
00290 
00291   return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
00292 }
00293 
00294 //===----------------------------------------------------------------------===//
00295 // ClassTemplateDecl Implementation
00296 //===----------------------------------------------------------------------===//
00297 
00298 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
00299   static_cast<Common *>(Ptr)->~Common();
00300 }
00301 
00302 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
00303                                              DeclContext *DC,
00304                                              SourceLocation L,
00305                                              DeclarationName Name,
00306                                              TemplateParameterList *Params,
00307                                              NamedDecl *Decl,
00308                                              ClassTemplateDecl *PrevDecl) {
00309   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
00310   ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
00311                                                          Params, Decl);
00312   New->setPreviousDecl(PrevDecl);
00313   return New;
00314 }
00315 
00316 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
00317                                                          unsigned ID) {
00318   return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
00319                                        DeclarationName(), nullptr, nullptr);
00320 }
00321 
00322 void ClassTemplateDecl::LoadLazySpecializations() const {
00323   Common *CommonPtr = getCommonPtr();
00324   if (CommonPtr->LazySpecializations) {
00325     ASTContext &Context = getASTContext();
00326     uint32_t *Specs = CommonPtr->LazySpecializations;
00327     CommonPtr->LazySpecializations = nullptr;
00328     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
00329       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
00330   }
00331 }
00332 
00333 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
00334 ClassTemplateDecl::getSpecializations() const {
00335   LoadLazySpecializations();
00336   return getCommonPtr()->Specializations;
00337 }  
00338 
00339 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
00340 ClassTemplateDecl::getPartialSpecializations() {
00341   LoadLazySpecializations();
00342   return getCommonPtr()->PartialSpecializations;
00343 }  
00344 
00345 RedeclarableTemplateDecl::CommonBase *
00346 ClassTemplateDecl::newCommon(ASTContext &C) const {
00347   Common *CommonPtr = new (C) Common;
00348   C.AddDeallocation(DeallocateCommon, CommonPtr);
00349   return CommonPtr;
00350 }
00351 
00352 ClassTemplateSpecializationDecl *
00353 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
00354                                       void *&InsertPos) {
00355   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
00356 }
00357 
00358 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
00359                                           void *InsertPos) {
00360   if (InsertPos)
00361     getSpecializations().InsertNode(D, InsertPos);
00362   else {
00363     ClassTemplateSpecializationDecl *Existing 
00364       = getSpecializations().GetOrInsertNode(D);
00365     (void)Existing;
00366     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
00367   }
00368   if (ASTMutationListener *L = getASTMutationListener())
00369     L->AddedCXXTemplateSpecialization(this, D);
00370 }
00371 
00372 ClassTemplatePartialSpecializationDecl *
00373 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
00374                                              void *&InsertPos) {
00375   return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
00376 }
00377 
00378 void ClassTemplateDecl::AddPartialSpecialization(
00379                                       ClassTemplatePartialSpecializationDecl *D,
00380                                       void *InsertPos) {
00381   if (InsertPos)
00382     getPartialSpecializations().InsertNode(D, InsertPos);
00383   else {
00384     ClassTemplatePartialSpecializationDecl *Existing
00385       = getPartialSpecializations().GetOrInsertNode(D);
00386     (void)Existing;
00387     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
00388   }
00389 
00390   if (ASTMutationListener *L = getASTMutationListener())
00391     L->AddedCXXTemplateSpecialization(this, D);
00392 }
00393 
00394 void ClassTemplateDecl::getPartialSpecializations(
00395           SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
00396   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
00397     = getPartialSpecializations();
00398   PS.clear();
00399   PS.reserve(PartialSpecs.size());
00400   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
00401        P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
00402        P != PEnd; ++P)
00403     PS.push_back(P->getMostRecentDecl());
00404 }
00405 
00406 ClassTemplatePartialSpecializationDecl *
00407 ClassTemplateDecl::findPartialSpecialization(QualType T) {
00408   ASTContext &Context = getASTContext();
00409   using llvm::FoldingSetVector;
00410   typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
00411     partial_spec_iterator;
00412   for (partial_spec_iterator P = getPartialSpecializations().begin(),
00413                           PEnd = getPartialSpecializations().end();
00414        P != PEnd; ++P) {
00415     if (Context.hasSameType(P->getInjectedSpecializationType(), T))
00416       return P->getMostRecentDecl();
00417   }
00418 
00419   return nullptr;
00420 }
00421 
00422 ClassTemplatePartialSpecializationDecl *
00423 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
00424                                     ClassTemplatePartialSpecializationDecl *D) {
00425   Decl *DCanon = D->getCanonicalDecl();
00426   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
00427             P = getPartialSpecializations().begin(),
00428          PEnd = getPartialSpecializations().end();
00429        P != PEnd; ++P) {
00430     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
00431       return P->getMostRecentDecl();
00432   }
00433 
00434   return nullptr;
00435 }
00436 
00437 QualType
00438 ClassTemplateDecl::getInjectedClassNameSpecialization() {
00439   Common *CommonPtr = getCommonPtr();
00440   if (!CommonPtr->InjectedClassNameType.isNull())
00441     return CommonPtr->InjectedClassNameType;
00442 
00443   // C++0x [temp.dep.type]p2:
00444   //  The template argument list of a primary template is a template argument 
00445   //  list in which the nth template argument has the value of the nth template
00446   //  parameter of the class template. If the nth template parameter is a 
00447   //  template parameter pack (14.5.3), the nth template argument is a pack 
00448   //  expansion (14.5.3) whose pattern is the name of the template parameter 
00449   //  pack.
00450   ASTContext &Context = getASTContext();
00451   TemplateParameterList *Params = getTemplateParameters();
00452   SmallVector<TemplateArgument, 16> TemplateArgs;
00453   TemplateArgs.resize(Params->size());
00454   GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
00455   CommonPtr->InjectedClassNameType
00456     = Context.getTemplateSpecializationType(TemplateName(this),
00457                                             &TemplateArgs[0],
00458                                             TemplateArgs.size());
00459   return CommonPtr->InjectedClassNameType;
00460 }
00461 
00462 //===----------------------------------------------------------------------===//
00463 // TemplateTypeParm Allocation/Deallocation Method Implementations
00464 //===----------------------------------------------------------------------===//
00465 
00466 TemplateTypeParmDecl *
00467 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
00468                              SourceLocation KeyLoc, SourceLocation NameLoc,
00469                              unsigned D, unsigned P, IdentifierInfo *Id,
00470                              bool Typename, bool ParameterPack) {
00471   TemplateTypeParmDecl *TTPDecl =
00472     new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
00473   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
00474   TTPDecl->setTypeForDecl(TTPType.getTypePtr());
00475   return TTPDecl;
00476 }
00477 
00478 TemplateTypeParmDecl *
00479 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
00480   return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
00481                                           SourceLocation(), nullptr, false);
00482 }
00483 
00484 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
00485   return hasDefaultArgument()
00486     ? DefaultArgument->getTypeLoc().getBeginLoc()
00487     : SourceLocation();
00488 }
00489 
00490 SourceRange TemplateTypeParmDecl::getSourceRange() const {
00491   if (hasDefaultArgument() && !defaultArgumentWasInherited())
00492     return SourceRange(getLocStart(),
00493                        DefaultArgument->getTypeLoc().getEndLoc());
00494   else
00495     return TypeDecl::getSourceRange();
00496 }
00497 
00498 unsigned TemplateTypeParmDecl::getDepth() const {
00499   return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
00500 }
00501 
00502 unsigned TemplateTypeParmDecl::getIndex() const {
00503   return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
00504 }
00505 
00506 bool TemplateTypeParmDecl::isParameterPack() const {
00507   return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
00508 }
00509 
00510 //===----------------------------------------------------------------------===//
00511 // NonTypeTemplateParmDecl Method Implementations
00512 //===----------------------------------------------------------------------===//
00513 
00514 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 
00515                                                  SourceLocation StartLoc,
00516                                                  SourceLocation IdLoc,
00517                                                  unsigned D, unsigned P,
00518                                                  IdentifierInfo *Id, 
00519                                                  QualType T, 
00520                                                  TypeSourceInfo *TInfo,
00521                                                  const QualType *ExpandedTypes,
00522                                                  unsigned NumExpandedTypes,
00523                                                 TypeSourceInfo **ExpandedTInfos)
00524   : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
00525     TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
00526     ParameterPack(true), ExpandedParameterPack(true),
00527     NumExpandedTypes(NumExpandedTypes)
00528 {
00529   if (ExpandedTypes && ExpandedTInfos) {
00530     void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
00531     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
00532       TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
00533       TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
00534     }
00535   }
00536 }
00537 
00538 NonTypeTemplateParmDecl *
00539 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
00540                                 SourceLocation StartLoc, SourceLocation IdLoc,
00541                                 unsigned D, unsigned P, IdentifierInfo *Id,
00542                                 QualType T, bool ParameterPack,
00543                                 TypeSourceInfo *TInfo) {
00544   return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
00545                                              T, ParameterPack, TInfo);
00546 }
00547 
00548 NonTypeTemplateParmDecl *
00549 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 
00550                                 SourceLocation StartLoc, SourceLocation IdLoc,
00551                                 unsigned D, unsigned P, 
00552                                 IdentifierInfo *Id, QualType T, 
00553                                 TypeSourceInfo *TInfo,
00554                                 const QualType *ExpandedTypes, 
00555                                 unsigned NumExpandedTypes,
00556                                 TypeSourceInfo **ExpandedTInfos) {
00557   unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
00558   return new (C, DC, Extra) NonTypeTemplateParmDecl(
00559       DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
00560       ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
00561 }
00562 
00563 NonTypeTemplateParmDecl *
00564 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
00565   return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
00566                                              SourceLocation(), 0, 0, nullptr,
00567                                              QualType(), false, nullptr);
00568 }
00569 
00570 NonTypeTemplateParmDecl *
00571 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
00572                                             unsigned NumExpandedTypes) {
00573   unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
00574   return new (C, ID, Extra) NonTypeTemplateParmDecl(
00575       nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
00576       nullptr, nullptr, NumExpandedTypes, nullptr);
00577 }
00578 
00579 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
00580   if (hasDefaultArgument() && !defaultArgumentWasInherited())
00581     return SourceRange(getOuterLocStart(),
00582                        getDefaultArgument()->getSourceRange().getEnd());
00583   return DeclaratorDecl::getSourceRange();
00584 }
00585 
00586 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
00587   return hasDefaultArgument()
00588     ? getDefaultArgument()->getSourceRange().getBegin()
00589     : SourceLocation();
00590 }
00591 
00592 //===----------------------------------------------------------------------===//
00593 // TemplateTemplateParmDecl Method Implementations
00594 //===----------------------------------------------------------------------===//
00595 
00596 void TemplateTemplateParmDecl::anchor() { }
00597 
00598 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
00599     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
00600     IdentifierInfo *Id, TemplateParameterList *Params,
00601     unsigned NumExpansions, TemplateParameterList * const *Expansions)
00602   : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
00603     TemplateParmPosition(D, P), DefaultArgument(),
00604     DefaultArgumentWasInherited(false), ParameterPack(true),
00605     ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
00606   if (Expansions)
00607     std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
00608                 sizeof(TemplateParameterList*) * NumExpandedParams);
00609 }
00610 
00611 TemplateTemplateParmDecl *
00612 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
00613                                  SourceLocation L, unsigned D, unsigned P,
00614                                  bool ParameterPack, IdentifierInfo *Id,
00615                                  TemplateParameterList *Params) {
00616   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
00617                                               Params);
00618 }
00619 
00620 TemplateTemplateParmDecl *
00621 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
00622                                  SourceLocation L, unsigned D, unsigned P,
00623                                  IdentifierInfo *Id,
00624                                  TemplateParameterList *Params,
00625                                  ArrayRef<TemplateParameterList *> Expansions) {
00626   return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
00627       TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
00628                                Expansions.size(), Expansions.data());
00629 }
00630 
00631 TemplateTemplateParmDecl *
00632 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
00633   return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
00634                                               false, nullptr, nullptr);
00635 }
00636 
00637 TemplateTemplateParmDecl *
00638 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
00639                                              unsigned NumExpansions) {
00640   return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
00641       TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
00642                                nullptr, NumExpansions, nullptr);
00643 }
00644 
00645 //===----------------------------------------------------------------------===//
00646 // TemplateArgumentList Implementation
00647 //===----------------------------------------------------------------------===//
00648 TemplateArgumentList *
00649 TemplateArgumentList::CreateCopy(ASTContext &Context,
00650                                  const TemplateArgument *Args,
00651                                  unsigned NumArgs) {
00652   std::size_t Size = sizeof(TemplateArgumentList)
00653                    + NumArgs * sizeof(TemplateArgument);
00654   void *Mem = Context.Allocate(Size);
00655   TemplateArgument *StoredArgs 
00656     = reinterpret_cast<TemplateArgument *>(
00657                                 static_cast<TemplateArgumentList *>(Mem) + 1);
00658   std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
00659   return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
00660 }
00661 
00662 FunctionTemplateSpecializationInfo *
00663 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
00664                                            FunctionTemplateDecl *Template,
00665                                            TemplateSpecializationKind TSK,
00666                                        const TemplateArgumentList *TemplateArgs,
00667                           const TemplateArgumentListInfo *TemplateArgsAsWritten,
00668                                            SourceLocation POI) {
00669   const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
00670   if (TemplateArgsAsWritten)
00671     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
00672                                                         *TemplateArgsAsWritten);
00673 
00674   return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
00675                                                     TemplateArgs,
00676                                                     ArgsAsWritten,
00677                                                     POI);
00678 }
00679 
00680 //===----------------------------------------------------------------------===//
00681 // TemplateDecl Implementation
00682 //===----------------------------------------------------------------------===//
00683 
00684 void TemplateDecl::anchor() { }
00685 
00686 //===----------------------------------------------------------------------===//
00687 // ClassTemplateSpecializationDecl Implementation
00688 //===----------------------------------------------------------------------===//
00689 ClassTemplateSpecializationDecl::
00690 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
00691                                 DeclContext *DC, SourceLocation StartLoc,
00692                                 SourceLocation IdLoc,
00693                                 ClassTemplateDecl *SpecializedTemplate,
00694                                 const TemplateArgument *Args,
00695                                 unsigned NumArgs,
00696                                 ClassTemplateSpecializationDecl *PrevDecl)
00697   : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
00698                   SpecializedTemplate->getIdentifier(),
00699                   PrevDecl),
00700     SpecializedTemplate(SpecializedTemplate),
00701     ExplicitInfo(nullptr),
00702     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
00703     SpecializationKind(TSK_Undeclared) {
00704 }
00705 
00706 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
00707                                                                  Kind DK)
00708     : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
00709                     SourceLocation(), nullptr, nullptr),
00710       ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
00711 
00712 ClassTemplateSpecializationDecl *
00713 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
00714                                         DeclContext *DC,
00715                                         SourceLocation StartLoc,
00716                                         SourceLocation IdLoc,
00717                                         ClassTemplateDecl *SpecializedTemplate,
00718                                         const TemplateArgument *Args,
00719                                         unsigned NumArgs,
00720                                    ClassTemplateSpecializationDecl *PrevDecl) {
00721   ClassTemplateSpecializationDecl *Result =
00722       new (Context, DC) ClassTemplateSpecializationDecl(
00723           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
00724           SpecializedTemplate, Args, NumArgs, PrevDecl);
00725   Result->MayHaveOutOfDateDef = false;
00726 
00727   Context.getTypeDeclType(Result, PrevDecl);
00728   return Result;
00729 }
00730 
00731 ClassTemplateSpecializationDecl *
00732 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
00733                                                     unsigned ID) {
00734   ClassTemplateSpecializationDecl *Result =
00735     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
00736   Result->MayHaveOutOfDateDef = false;
00737   return Result;
00738 }
00739 
00740 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
00741     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
00742   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
00743 
00744   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
00745   TemplateSpecializationType::PrintTemplateArgumentList(
00746       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
00747 }
00748 
00749 ClassTemplateDecl *
00750 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
00751   if (SpecializedPartialSpecialization *PartialSpec
00752       = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
00753     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
00754   return SpecializedTemplate.get<ClassTemplateDecl*>();
00755 }
00756 
00757 SourceRange
00758 ClassTemplateSpecializationDecl::getSourceRange() const {
00759   if (ExplicitInfo) {
00760     SourceLocation Begin = getTemplateKeywordLoc();
00761     if (Begin.isValid()) {
00762       // Here we have an explicit (partial) specialization or instantiation.
00763       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
00764              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
00765              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
00766       if (getExternLoc().isValid())
00767         Begin = getExternLoc();
00768       SourceLocation End = getRBraceLoc();
00769       if (End.isInvalid())
00770         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
00771       return SourceRange(Begin, End);
00772     }
00773     // An implicit instantiation of a class template partial specialization
00774     // uses ExplicitInfo to record the TypeAsWritten, but the source
00775     // locations should be retrieved from the instantiation pattern.
00776     typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
00777     CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
00778     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
00779     assert(inst_from != nullptr);
00780     return inst_from->getSourceRange();
00781   }
00782   else {
00783     // No explicit info available.
00784     llvm::PointerUnion<ClassTemplateDecl *,
00785                        ClassTemplatePartialSpecializationDecl *>
00786       inst_from = getInstantiatedFrom();
00787     if (inst_from.isNull())
00788       return getSpecializedTemplate()->getSourceRange();
00789     if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
00790       return ctd->getSourceRange();
00791     return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
00792       ->getSourceRange();
00793   }
00794 }
00795 
00796 //===----------------------------------------------------------------------===//
00797 // ClassTemplatePartialSpecializationDecl Implementation
00798 //===----------------------------------------------------------------------===//
00799 void ClassTemplatePartialSpecializationDecl::anchor() { }
00800 
00801 ClassTemplatePartialSpecializationDecl::
00802 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
00803                                        DeclContext *DC,
00804                                        SourceLocation StartLoc,
00805                                        SourceLocation IdLoc,
00806                                        TemplateParameterList *Params,
00807                                        ClassTemplateDecl *SpecializedTemplate,
00808                                        const TemplateArgument *Args,
00809                                        unsigned NumArgs,
00810                                const ASTTemplateArgumentListInfo *ArgInfos,
00811                                ClassTemplatePartialSpecializationDecl *PrevDecl)
00812   : ClassTemplateSpecializationDecl(Context,
00813                                     ClassTemplatePartialSpecialization,
00814                                     TK, DC, StartLoc, IdLoc,
00815                                     SpecializedTemplate,
00816                                     Args, NumArgs, PrevDecl),
00817     TemplateParams(Params), ArgsAsWritten(ArgInfos),
00818     InstantiatedFromMember(nullptr, false)
00819 {
00820   AdoptTemplateParameterList(Params, this);
00821 }
00822 
00823 ClassTemplatePartialSpecializationDecl *
00824 ClassTemplatePartialSpecializationDecl::
00825 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
00826        SourceLocation StartLoc, SourceLocation IdLoc,
00827        TemplateParameterList *Params,
00828        ClassTemplateDecl *SpecializedTemplate,
00829        const TemplateArgument *Args,
00830        unsigned NumArgs,
00831        const TemplateArgumentListInfo &ArgInfos,
00832        QualType CanonInjectedType,
00833        ClassTemplatePartialSpecializationDecl *PrevDecl) {
00834   const ASTTemplateArgumentListInfo *ASTArgInfos =
00835     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
00836 
00837   ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
00838       ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
00839                                              Params, SpecializedTemplate, Args,
00840                                              NumArgs, ASTArgInfos, PrevDecl);
00841   Result->setSpecializationKind(TSK_ExplicitSpecialization);
00842   Result->MayHaveOutOfDateDef = false;
00843 
00844   Context.getInjectedClassNameType(Result, CanonInjectedType);
00845   return Result;
00846 }
00847 
00848 ClassTemplatePartialSpecializationDecl *
00849 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
00850                                                            unsigned ID) {
00851   ClassTemplatePartialSpecializationDecl *Result =
00852       new (C, ID) ClassTemplatePartialSpecializationDecl(C);
00853   Result->MayHaveOutOfDateDef = false;
00854   return Result;
00855 }
00856 
00857 //===----------------------------------------------------------------------===//
00858 // FriendTemplateDecl Implementation
00859 //===----------------------------------------------------------------------===//
00860 
00861 void FriendTemplateDecl::anchor() { }
00862 
00863 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
00864                                                DeclContext *DC,
00865                                                SourceLocation L,
00866                                                unsigned NParams,
00867                                                TemplateParameterList **Params,
00868                                                FriendUnion Friend,
00869                                                SourceLocation FLoc) {
00870   return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
00871                                               Friend, FLoc);
00872 }
00873 
00874 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
00875                                                            unsigned ID) {
00876   return new (C, ID) FriendTemplateDecl(EmptyShell());
00877 }
00878 
00879 //===----------------------------------------------------------------------===//
00880 // TypeAliasTemplateDecl Implementation
00881 //===----------------------------------------------------------------------===//
00882 
00883 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
00884                                                      DeclContext *DC,
00885                                                      SourceLocation L,
00886                                                      DeclarationName Name,
00887                                                   TemplateParameterList *Params,
00888                                                      NamedDecl *Decl) {
00889   AdoptTemplateParameterList(Params, DC);
00890   return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
00891 }
00892 
00893 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
00894                                                                  unsigned ID) {
00895   return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
00896                                            DeclarationName(), nullptr, nullptr);
00897 }
00898 
00899 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
00900   static_cast<Common *>(Ptr)->~Common();
00901 }
00902 RedeclarableTemplateDecl::CommonBase *
00903 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
00904   Common *CommonPtr = new (C) Common;
00905   C.AddDeallocation(DeallocateCommon, CommonPtr);
00906   return CommonPtr;
00907 }
00908 
00909 //===----------------------------------------------------------------------===//
00910 // ClassScopeFunctionSpecializationDecl Implementation
00911 //===----------------------------------------------------------------------===//
00912 
00913 void ClassScopeFunctionSpecializationDecl::anchor() { }
00914 
00915 ClassScopeFunctionSpecializationDecl *
00916 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
00917                                                          unsigned ID) {
00918   return new (C, ID) ClassScopeFunctionSpecializationDecl(
00919       nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
00920 }
00921 
00922 //===----------------------------------------------------------------------===//
00923 // VarTemplateDecl Implementation
00924 //===----------------------------------------------------------------------===//
00925 
00926 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
00927   static_cast<Common *>(Ptr)->~Common();
00928 }
00929 
00930 VarTemplateDecl *VarTemplateDecl::getDefinition() {
00931   VarTemplateDecl *CurD = this;
00932   while (CurD) {
00933     if (CurD->isThisDeclarationADefinition())
00934       return CurD;
00935     CurD = CurD->getPreviousDecl();
00936   }
00937   return nullptr;
00938 }
00939 
00940 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
00941                                          SourceLocation L, DeclarationName Name,
00942                                          TemplateParameterList *Params,
00943                                          VarDecl *Decl) {
00944   return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
00945 }
00946 
00947 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
00948                                                      unsigned ID) {
00949   return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
00950                                      DeclarationName(), nullptr, nullptr);
00951 }
00952 
00953 // TODO: Unify across class, function and variable templates?
00954 //       May require moving this and Common to RedeclarableTemplateDecl.
00955 void VarTemplateDecl::LoadLazySpecializations() const {
00956   Common *CommonPtr = getCommonPtr();
00957   if (CommonPtr->LazySpecializations) {
00958     ASTContext &Context = getASTContext();
00959     uint32_t *Specs = CommonPtr->LazySpecializations;
00960     CommonPtr->LazySpecializations = nullptr;
00961     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
00962       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
00963   }
00964 }
00965 
00966 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
00967 VarTemplateDecl::getSpecializations() const {
00968   LoadLazySpecializations();
00969   return getCommonPtr()->Specializations;
00970 }
00971 
00972 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
00973 VarTemplateDecl::getPartialSpecializations() {
00974   LoadLazySpecializations();
00975   return getCommonPtr()->PartialSpecializations;
00976 }
00977 
00978 RedeclarableTemplateDecl::CommonBase *
00979 VarTemplateDecl::newCommon(ASTContext &C) const {
00980   Common *CommonPtr = new (C) Common;
00981   C.AddDeallocation(DeallocateCommon, CommonPtr);
00982   return CommonPtr;
00983 }
00984 
00985 VarTemplateSpecializationDecl *
00986 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
00987                                     void *&InsertPos) {
00988   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
00989 }
00990 
00991 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
00992                                         void *InsertPos) {
00993   if (InsertPos)
00994     getSpecializations().InsertNode(D, InsertPos);
00995   else {
00996     VarTemplateSpecializationDecl *Existing =
00997         getSpecializations().GetOrInsertNode(D);
00998     (void)Existing;
00999     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
01000   }
01001   if (ASTMutationListener *L = getASTMutationListener())
01002     L->AddedCXXTemplateSpecialization(this, D);
01003 }
01004 
01005 VarTemplatePartialSpecializationDecl *
01006 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
01007                                            void *&InsertPos) {
01008   return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
01009 }
01010 
01011 void VarTemplateDecl::AddPartialSpecialization(
01012     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
01013   if (InsertPos)
01014     getPartialSpecializations().InsertNode(D, InsertPos);
01015   else {
01016     VarTemplatePartialSpecializationDecl *Existing =
01017         getPartialSpecializations().GetOrInsertNode(D);
01018     (void)Existing;
01019     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
01020   }
01021 
01022   if (ASTMutationListener *L = getASTMutationListener())
01023     L->AddedCXXTemplateSpecialization(this, D);
01024 }
01025 
01026 void VarTemplateDecl::getPartialSpecializations(
01027     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
01028   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
01029       getPartialSpecializations();
01030   PS.clear();
01031   PS.reserve(PartialSpecs.size());
01032   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
01033            P = PartialSpecs.begin(),
01034            PEnd = PartialSpecs.end();
01035        P != PEnd; ++P)
01036     PS.push_back(P->getMostRecentDecl());
01037 }
01038 
01039 VarTemplatePartialSpecializationDecl *
01040 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
01041     VarTemplatePartialSpecializationDecl *D) {
01042   Decl *DCanon = D->getCanonicalDecl();
01043   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
01044            P = getPartialSpecializations().begin(),
01045            PEnd = getPartialSpecializations().end();
01046        P != PEnd; ++P) {
01047     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
01048       return P->getMostRecentDecl();
01049   }
01050 
01051   return nullptr;
01052 }
01053 
01054 //===----------------------------------------------------------------------===//
01055 // VarTemplateSpecializationDecl Implementation
01056 //===----------------------------------------------------------------------===//
01057 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
01058     Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
01059     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
01060     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
01061     unsigned NumArgs)
01062     : VarDecl(DK, Context, DC, StartLoc, IdLoc,
01063               SpecializedTemplate->getIdentifier(), T, TInfo, S),
01064       SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
01065       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
01066       SpecializationKind(TSK_Undeclared) {}
01067 
01068 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
01069                                                              ASTContext &C)
01070     : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
01071               QualType(), nullptr, SC_None),
01072       ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
01073 
01074 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
01075     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
01076     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
01077     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
01078     unsigned NumArgs) {
01079   return new (Context, DC) VarTemplateSpecializationDecl(
01080       VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
01081       SpecializedTemplate, T, TInfo, S, Args, NumArgs);
01082 }
01083 
01084 VarTemplateSpecializationDecl *
01085 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
01086   return new (C, ID)
01087       VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
01088 }
01089 
01090 void VarTemplateSpecializationDecl::getNameForDiagnostic(
01091     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
01092   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
01093 
01094   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
01095   TemplateSpecializationType::PrintTemplateArgumentList(
01096       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
01097 }
01098 
01099 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
01100   if (SpecializedPartialSpecialization *PartialSpec =
01101           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
01102     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
01103   return SpecializedTemplate.get<VarTemplateDecl *>();
01104 }
01105 
01106 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
01107     const TemplateArgumentListInfo &ArgsInfo) {
01108   unsigned N = ArgsInfo.size();
01109   TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
01110   TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
01111   for (unsigned I = 0; I != N; ++I)
01112     TemplateArgsInfo.addArgument(ArgsInfo[I]);
01113 }
01114 
01115 //===----------------------------------------------------------------------===//
01116 // VarTemplatePartialSpecializationDecl Implementation
01117 //===----------------------------------------------------------------------===//
01118 void VarTemplatePartialSpecializationDecl::anchor() {}
01119 
01120 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
01121     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
01122     SourceLocation IdLoc, TemplateParameterList *Params,
01123     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
01124     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
01125     const ASTTemplateArgumentListInfo *ArgInfos)
01126     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
01127                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
01128                                     TInfo, S, Args, NumArgs),
01129       TemplateParams(Params), ArgsAsWritten(ArgInfos),
01130       InstantiatedFromMember(nullptr, false) {
01131   // TODO: The template parameters should be in DC by now. Verify.
01132   // AdoptTemplateParameterList(Params, DC);
01133 }
01134 
01135 VarTemplatePartialSpecializationDecl *
01136 VarTemplatePartialSpecializationDecl::Create(
01137     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
01138     SourceLocation IdLoc, TemplateParameterList *Params,
01139     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
01140     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
01141     const TemplateArgumentListInfo &ArgInfos) {
01142   const ASTTemplateArgumentListInfo *ASTArgInfos
01143     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
01144 
01145   VarTemplatePartialSpecializationDecl *Result =
01146       new (Context, DC) VarTemplatePartialSpecializationDecl(
01147           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
01148           S, Args, NumArgs, ASTArgInfos);
01149   Result->setSpecializationKind(TSK_ExplicitSpecialization);
01150   return Result;
01151 }
01152 
01153 VarTemplatePartialSpecializationDecl *
01154 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
01155                                                          unsigned ID) {
01156   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
01157 }