xref: /aosp_15_r20/external/clang/lib/AST/DeclTemplate.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements the C++ related Decl classes for templates.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li 
14*67e74705SXin Li #include "clang/AST/DeclTemplate.h"
15*67e74705SXin Li #include "clang/AST/ASTContext.h"
16*67e74705SXin Li #include "clang/AST/ASTMutationListener.h"
17*67e74705SXin Li #include "clang/AST/DeclCXX.h"
18*67e74705SXin Li #include "clang/AST/Expr.h"
19*67e74705SXin Li #include "clang/AST/ExprCXX.h"
20*67e74705SXin Li #include "clang/AST/TypeLoc.h"
21*67e74705SXin Li #include "clang/Basic/Builtins.h"
22*67e74705SXin Li #include "clang/Basic/IdentifierTable.h"
23*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
24*67e74705SXin Li #include <memory>
25*67e74705SXin Li using namespace clang;
26*67e74705SXin Li 
27*67e74705SXin Li //===----------------------------------------------------------------------===//
28*67e74705SXin Li // TemplateParameterList Implementation
29*67e74705SXin Li //===----------------------------------------------------------------------===//
30*67e74705SXin Li 
TemplateParameterList(SourceLocation TemplateLoc,SourceLocation LAngleLoc,ArrayRef<NamedDecl * > Params,SourceLocation RAngleLoc)31*67e74705SXin Li TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
32*67e74705SXin Li                                              SourceLocation LAngleLoc,
33*67e74705SXin Li                                              ArrayRef<NamedDecl *> Params,
34*67e74705SXin Li                                              SourceLocation RAngleLoc)
35*67e74705SXin Li   : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
36*67e74705SXin Li     NumParams(Params.size()), ContainsUnexpandedParameterPack(false) {
37*67e74705SXin Li   assert(this->NumParams == NumParams && "Too many template parameters");
38*67e74705SXin Li   for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
39*67e74705SXin Li     NamedDecl *P = Params[Idx];
40*67e74705SXin Li     begin()[Idx] = P;
41*67e74705SXin Li 
42*67e74705SXin Li     if (!P->isTemplateParameterPack()) {
43*67e74705SXin Li       if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
44*67e74705SXin Li         if (NTTP->getType()->containsUnexpandedParameterPack())
45*67e74705SXin Li           ContainsUnexpandedParameterPack = true;
46*67e74705SXin Li 
47*67e74705SXin Li       if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
48*67e74705SXin Li         if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
49*67e74705SXin Li           ContainsUnexpandedParameterPack = true;
50*67e74705SXin Li 
51*67e74705SXin Li       // FIXME: If a default argument contains an unexpanded parameter pack, the
52*67e74705SXin Li       // template parameter list does too.
53*67e74705SXin Li     }
54*67e74705SXin Li   }
55*67e74705SXin Li }
56*67e74705SXin Li 
Create(const ASTContext & C,SourceLocation TemplateLoc,SourceLocation LAngleLoc,ArrayRef<NamedDecl * > Params,SourceLocation RAngleLoc)57*67e74705SXin Li TemplateParameterList *TemplateParameterList::Create(
58*67e74705SXin Li     const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc,
59*67e74705SXin Li     ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc) {
60*67e74705SXin Li   void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *>(Params.size()),
61*67e74705SXin Li                          llvm::alignOf<TemplateParameterList>());
62*67e74705SXin Li   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
63*67e74705SXin Li                                          RAngleLoc);
64*67e74705SXin Li }
65*67e74705SXin Li 
getMinRequiredArguments() const66*67e74705SXin Li unsigned TemplateParameterList::getMinRequiredArguments() const {
67*67e74705SXin Li   unsigned NumRequiredArgs = 0;
68*67e74705SXin Li   for (const NamedDecl *P : asArray()) {
69*67e74705SXin Li     if (P->isTemplateParameterPack()) {
70*67e74705SXin Li       if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
71*67e74705SXin Li         if (NTTP->isExpandedParameterPack()) {
72*67e74705SXin Li           NumRequiredArgs += NTTP->getNumExpansionTypes();
73*67e74705SXin Li           continue;
74*67e74705SXin Li         }
75*67e74705SXin Li 
76*67e74705SXin Li       break;
77*67e74705SXin Li     }
78*67e74705SXin Li 
79*67e74705SXin Li     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
80*67e74705SXin Li       if (TTP->hasDefaultArgument())
81*67e74705SXin Li         break;
82*67e74705SXin Li     } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
83*67e74705SXin Li       if (NTTP->hasDefaultArgument())
84*67e74705SXin Li         break;
85*67e74705SXin Li     } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
86*67e74705SXin Li       break;
87*67e74705SXin Li 
88*67e74705SXin Li     ++NumRequiredArgs;
89*67e74705SXin Li   }
90*67e74705SXin Li 
91*67e74705SXin Li   return NumRequiredArgs;
92*67e74705SXin Li }
93*67e74705SXin Li 
getDepth() const94*67e74705SXin Li unsigned TemplateParameterList::getDepth() const {
95*67e74705SXin Li   if (size() == 0)
96*67e74705SXin Li     return 0;
97*67e74705SXin Li 
98*67e74705SXin Li   const NamedDecl *FirstParm = getParam(0);
99*67e74705SXin Li   if (const TemplateTypeParmDecl *TTP
100*67e74705SXin Li         = dyn_cast<TemplateTypeParmDecl>(FirstParm))
101*67e74705SXin Li     return TTP->getDepth();
102*67e74705SXin Li   else if (const NonTypeTemplateParmDecl *NTTP
103*67e74705SXin Li              = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
104*67e74705SXin Li     return NTTP->getDepth();
105*67e74705SXin Li   else
106*67e74705SXin Li     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
107*67e74705SXin Li }
108*67e74705SXin Li 
AdoptTemplateParameterList(TemplateParameterList * Params,DeclContext * Owner)109*67e74705SXin Li static void AdoptTemplateParameterList(TemplateParameterList *Params,
110*67e74705SXin Li                                        DeclContext *Owner) {
111*67e74705SXin Li   for (NamedDecl *P : *Params) {
112*67e74705SXin Li     P->setDeclContext(Owner);
113*67e74705SXin Li 
114*67e74705SXin Li     if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
115*67e74705SXin Li       AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
116*67e74705SXin Li   }
117*67e74705SXin Li }
118*67e74705SXin Li 
119*67e74705SXin Li namespace clang {
allocateDefaultArgStorageChain(const ASTContext & C)120*67e74705SXin Li void *allocateDefaultArgStorageChain(const ASTContext &C) {
121*67e74705SXin Li   return new (C) char[sizeof(void*) * 2];
122*67e74705SXin Li }
123*67e74705SXin Li }
124*67e74705SXin Li 
125*67e74705SXin Li //===----------------------------------------------------------------------===//
126*67e74705SXin Li // RedeclarableTemplateDecl Implementation
127*67e74705SXin Li //===----------------------------------------------------------------------===//
128*67e74705SXin Li 
getCommonPtr() const129*67e74705SXin Li RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
130*67e74705SXin Li   if (Common)
131*67e74705SXin Li     return Common;
132*67e74705SXin Li 
133*67e74705SXin Li   // Walk the previous-declaration chain until we either find a declaration
134*67e74705SXin Li   // with a common pointer or we run out of previous declarations.
135*67e74705SXin Li   SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
136*67e74705SXin Li   for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
137*67e74705SXin Li        Prev = Prev->getPreviousDecl()) {
138*67e74705SXin Li     if (Prev->Common) {
139*67e74705SXin Li       Common = Prev->Common;
140*67e74705SXin Li       break;
141*67e74705SXin Li     }
142*67e74705SXin Li 
143*67e74705SXin Li     PrevDecls.push_back(Prev);
144*67e74705SXin Li   }
145*67e74705SXin Li 
146*67e74705SXin Li   // If we never found a common pointer, allocate one now.
147*67e74705SXin Li   if (!Common) {
148*67e74705SXin Li     // FIXME: If any of the declarations is from an AST file, we probably
149*67e74705SXin Li     // need an update record to add the common data.
150*67e74705SXin Li 
151*67e74705SXin Li     Common = newCommon(getASTContext());
152*67e74705SXin Li   }
153*67e74705SXin Li 
154*67e74705SXin Li   // Update any previous declarations we saw with the common pointer.
155*67e74705SXin Li   for (const RedeclarableTemplateDecl *Prev : PrevDecls)
156*67e74705SXin Li     Prev->Common = Common;
157*67e74705SXin Li 
158*67e74705SXin Li   return Common;
159*67e74705SXin Li }
160*67e74705SXin Li 
161*67e74705SXin Li template<class EntryType>
162*67e74705SXin Li typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
findSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specs,ArrayRef<TemplateArgument> Args,void * & InsertPos)163*67e74705SXin Li RedeclarableTemplateDecl::findSpecializationImpl(
164*67e74705SXin Li     llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
165*67e74705SXin Li     void *&InsertPos) {
166*67e74705SXin Li   typedef SpecEntryTraits<EntryType> SETraits;
167*67e74705SXin Li   llvm::FoldingSetNodeID ID;
168*67e74705SXin Li   EntryType::Profile(ID,Args, getASTContext());
169*67e74705SXin Li   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
170*67e74705SXin Li   return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
171*67e74705SXin Li }
172*67e74705SXin Li 
173*67e74705SXin Li template<class Derived, class EntryType>
addSpecializationImpl(llvm::FoldingSetVector<EntryType> & Specializations,EntryType * Entry,void * InsertPos)174*67e74705SXin Li void RedeclarableTemplateDecl::addSpecializationImpl(
175*67e74705SXin Li     llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
176*67e74705SXin Li     void *InsertPos) {
177*67e74705SXin Li   typedef SpecEntryTraits<EntryType> SETraits;
178*67e74705SXin Li   if (InsertPos) {
179*67e74705SXin Li #ifndef NDEBUG
180*67e74705SXin Li     void *CorrectInsertPos;
181*67e74705SXin Li     assert(!findSpecializationImpl(Specializations,
182*67e74705SXin Li                                    SETraits::getTemplateArgs(Entry),
183*67e74705SXin Li                                    CorrectInsertPos) &&
184*67e74705SXin Li            InsertPos == CorrectInsertPos &&
185*67e74705SXin Li            "given incorrect InsertPos for specialization");
186*67e74705SXin Li #endif
187*67e74705SXin Li     Specializations.InsertNode(Entry, InsertPos);
188*67e74705SXin Li   } else {
189*67e74705SXin Li     EntryType *Existing = Specializations.GetOrInsertNode(Entry);
190*67e74705SXin Li     (void)Existing;
191*67e74705SXin Li     assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
192*67e74705SXin Li            "non-canonical specialization?");
193*67e74705SXin Li   }
194*67e74705SXin Li 
195*67e74705SXin Li   if (ASTMutationListener *L = getASTMutationListener())
196*67e74705SXin Li     L->AddedCXXTemplateSpecialization(cast<Derived>(this),
197*67e74705SXin Li                                       SETraits::getDecl(Entry));
198*67e74705SXin Li }
199*67e74705SXin Li 
200*67e74705SXin Li /// \brief Generate the injected template arguments for the given template
201*67e74705SXin Li /// parameter list, e.g., for the injected-class-name of a class template.
GenerateInjectedTemplateArgs(ASTContext & Context,TemplateParameterList * Params,TemplateArgument * Args)202*67e74705SXin Li static void GenerateInjectedTemplateArgs(ASTContext &Context,
203*67e74705SXin Li                                          TemplateParameterList *Params,
204*67e74705SXin Li                                          TemplateArgument *Args) {
205*67e74705SXin Li   for (NamedDecl *Param : *Params) {
206*67e74705SXin Li     TemplateArgument Arg;
207*67e74705SXin Li     if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
208*67e74705SXin Li       QualType ArgType = Context.getTypeDeclType(TTP);
209*67e74705SXin Li       if (TTP->isParameterPack())
210*67e74705SXin Li         ArgType = Context.getPackExpansionType(ArgType, None);
211*67e74705SXin Li 
212*67e74705SXin Li       Arg = TemplateArgument(ArgType);
213*67e74705SXin Li     } else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
214*67e74705SXin Li       Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
215*67e74705SXin Li                                   NTTP->getType().getNonLValueExprType(Context),
216*67e74705SXin Li                                   Expr::getValueKindForType(NTTP->getType()),
217*67e74705SXin Li                                           NTTP->getLocation());
218*67e74705SXin Li 
219*67e74705SXin Li       if (NTTP->isParameterPack())
220*67e74705SXin Li         E = new (Context) PackExpansionExpr(Context.DependentTy, E,
221*67e74705SXin Li                                             NTTP->getLocation(), None);
222*67e74705SXin Li       Arg = TemplateArgument(E);
223*67e74705SXin Li     } else {
224*67e74705SXin Li       auto *TTP = cast<TemplateTemplateParmDecl>(Param);
225*67e74705SXin Li       if (TTP->isParameterPack())
226*67e74705SXin Li         Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
227*67e74705SXin Li       else
228*67e74705SXin Li         Arg = TemplateArgument(TemplateName(TTP));
229*67e74705SXin Li     }
230*67e74705SXin Li 
231*67e74705SXin Li     if (Param->isTemplateParameterPack())
232*67e74705SXin Li       Arg = TemplateArgument::CreatePackCopy(Context, Arg);
233*67e74705SXin Li 
234*67e74705SXin Li     *Args++ = Arg;
235*67e74705SXin Li   }
236*67e74705SXin Li }
237*67e74705SXin Li 
238*67e74705SXin Li //===----------------------------------------------------------------------===//
239*67e74705SXin Li // FunctionTemplateDecl Implementation
240*67e74705SXin Li //===----------------------------------------------------------------------===//
241*67e74705SXin Li 
DeallocateCommon(void * Ptr)242*67e74705SXin Li void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
243*67e74705SXin Li   static_cast<Common *>(Ptr)->~Common();
244*67e74705SXin Li }
245*67e74705SXin Li 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)246*67e74705SXin Li FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
247*67e74705SXin Li                                                    DeclContext *DC,
248*67e74705SXin Li                                                    SourceLocation L,
249*67e74705SXin Li                                                    DeclarationName Name,
250*67e74705SXin Li                                                TemplateParameterList *Params,
251*67e74705SXin Li                                                    NamedDecl *Decl) {
252*67e74705SXin Li   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
253*67e74705SXin Li   return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
254*67e74705SXin Li }
255*67e74705SXin Li 
CreateDeserialized(ASTContext & C,unsigned ID)256*67e74705SXin Li FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
257*67e74705SXin Li                                                                unsigned ID) {
258*67e74705SXin Li   return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
259*67e74705SXin Li                                           DeclarationName(), nullptr, nullptr);
260*67e74705SXin Li }
261*67e74705SXin Li 
262*67e74705SXin Li RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const263*67e74705SXin Li FunctionTemplateDecl::newCommon(ASTContext &C) const {
264*67e74705SXin Li   Common *CommonPtr = new (C) Common;
265*67e74705SXin Li   C.AddDeallocation(DeallocateCommon, CommonPtr);
266*67e74705SXin Li   return CommonPtr;
267*67e74705SXin Li }
268*67e74705SXin Li 
LoadLazySpecializations() const269*67e74705SXin Li void FunctionTemplateDecl::LoadLazySpecializations() const {
270*67e74705SXin Li   // Grab the most recent declaration to ensure we've loaded any lazy
271*67e74705SXin Li   // redeclarations of this template.
272*67e74705SXin Li   //
273*67e74705SXin Li   // FIXME: Avoid walking the entire redeclaration chain here.
274*67e74705SXin Li   Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
275*67e74705SXin Li   if (CommonPtr->LazySpecializations) {
276*67e74705SXin Li     ASTContext &Context = getASTContext();
277*67e74705SXin Li     uint32_t *Specs = CommonPtr->LazySpecializations;
278*67e74705SXin Li     CommonPtr->LazySpecializations = nullptr;
279*67e74705SXin Li     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
280*67e74705SXin Li       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
281*67e74705SXin Li   }
282*67e74705SXin Li }
283*67e74705SXin Li 
284*67e74705SXin Li llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
getSpecializations() const285*67e74705SXin Li FunctionTemplateDecl::getSpecializations() const {
286*67e74705SXin Li   LoadLazySpecializations();
287*67e74705SXin Li   return getCommonPtr()->Specializations;
288*67e74705SXin Li }
289*67e74705SXin Li 
290*67e74705SXin Li FunctionDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)291*67e74705SXin Li FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
292*67e74705SXin Li                                          void *&InsertPos) {
293*67e74705SXin Li   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
294*67e74705SXin Li }
295*67e74705SXin Li 
addSpecialization(FunctionTemplateSpecializationInfo * Info,void * InsertPos)296*67e74705SXin Li void FunctionTemplateDecl::addSpecialization(
297*67e74705SXin Li       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
298*67e74705SXin Li   addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
299*67e74705SXin Li                                               InsertPos);
300*67e74705SXin Li }
301*67e74705SXin Li 
getInjectedTemplateArgs()302*67e74705SXin Li ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
303*67e74705SXin Li   TemplateParameterList *Params = getTemplateParameters();
304*67e74705SXin Li   Common *CommonPtr = getCommonPtr();
305*67e74705SXin Li   if (!CommonPtr->InjectedArgs) {
306*67e74705SXin Li     CommonPtr->InjectedArgs
307*67e74705SXin Li       = new (getASTContext()) TemplateArgument[Params->size()];
308*67e74705SXin Li     GenerateInjectedTemplateArgs(getASTContext(), Params,
309*67e74705SXin Li                                  CommonPtr->InjectedArgs);
310*67e74705SXin Li   }
311*67e74705SXin Li 
312*67e74705SXin Li   return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
313*67e74705SXin Li }
314*67e74705SXin Li 
315*67e74705SXin Li //===----------------------------------------------------------------------===//
316*67e74705SXin Li // ClassTemplateDecl Implementation
317*67e74705SXin Li //===----------------------------------------------------------------------===//
318*67e74705SXin Li 
DeallocateCommon(void * Ptr)319*67e74705SXin Li void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
320*67e74705SXin Li   static_cast<Common *>(Ptr)->~Common();
321*67e74705SXin Li }
322*67e74705SXin Li 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl,ClassTemplateDecl * PrevDecl)323*67e74705SXin Li ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
324*67e74705SXin Li                                              DeclContext *DC,
325*67e74705SXin Li                                              SourceLocation L,
326*67e74705SXin Li                                              DeclarationName Name,
327*67e74705SXin Li                                              TemplateParameterList *Params,
328*67e74705SXin Li                                              NamedDecl *Decl,
329*67e74705SXin Li                                              ClassTemplateDecl *PrevDecl) {
330*67e74705SXin Li   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
331*67e74705SXin Li   ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
332*67e74705SXin Li                                                          Params, Decl);
333*67e74705SXin Li   New->setPreviousDecl(PrevDecl);
334*67e74705SXin Li   return New;
335*67e74705SXin Li }
336*67e74705SXin Li 
CreateDeserialized(ASTContext & C,unsigned ID)337*67e74705SXin Li ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
338*67e74705SXin Li                                                          unsigned ID) {
339*67e74705SXin Li   return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
340*67e74705SXin Li                                        DeclarationName(), nullptr, nullptr);
341*67e74705SXin Li }
342*67e74705SXin Li 
LoadLazySpecializations() const343*67e74705SXin Li void ClassTemplateDecl::LoadLazySpecializations() const {
344*67e74705SXin Li   // Grab the most recent declaration to ensure we've loaded any lazy
345*67e74705SXin Li   // redeclarations of this template.
346*67e74705SXin Li   //
347*67e74705SXin Li   // FIXME: Avoid walking the entire redeclaration chain here.
348*67e74705SXin Li   Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
349*67e74705SXin Li   if (CommonPtr->LazySpecializations) {
350*67e74705SXin Li     ASTContext &Context = getASTContext();
351*67e74705SXin Li     uint32_t *Specs = CommonPtr->LazySpecializations;
352*67e74705SXin Li     CommonPtr->LazySpecializations = nullptr;
353*67e74705SXin Li     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
354*67e74705SXin Li       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
355*67e74705SXin Li   }
356*67e74705SXin Li }
357*67e74705SXin Li 
358*67e74705SXin Li llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
getSpecializations() const359*67e74705SXin Li ClassTemplateDecl::getSpecializations() const {
360*67e74705SXin Li   LoadLazySpecializations();
361*67e74705SXin Li   return getCommonPtr()->Specializations;
362*67e74705SXin Li }
363*67e74705SXin Li 
364*67e74705SXin Li llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations()365*67e74705SXin Li ClassTemplateDecl::getPartialSpecializations() {
366*67e74705SXin Li   LoadLazySpecializations();
367*67e74705SXin Li   return getCommonPtr()->PartialSpecializations;
368*67e74705SXin Li }
369*67e74705SXin Li 
370*67e74705SXin Li RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const371*67e74705SXin Li ClassTemplateDecl::newCommon(ASTContext &C) const {
372*67e74705SXin Li   Common *CommonPtr = new (C) Common;
373*67e74705SXin Li   C.AddDeallocation(DeallocateCommon, CommonPtr);
374*67e74705SXin Li   return CommonPtr;
375*67e74705SXin Li }
376*67e74705SXin Li 
377*67e74705SXin Li ClassTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)378*67e74705SXin Li ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
379*67e74705SXin Li                                       void *&InsertPos) {
380*67e74705SXin Li   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
381*67e74705SXin Li }
382*67e74705SXin Li 
AddSpecialization(ClassTemplateSpecializationDecl * D,void * InsertPos)383*67e74705SXin Li void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
384*67e74705SXin Li                                           void *InsertPos) {
385*67e74705SXin Li   addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
386*67e74705SXin Li }
387*67e74705SXin Li 
388*67e74705SXin Li ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)389*67e74705SXin Li ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
390*67e74705SXin Li                                              void *&InsertPos) {
391*67e74705SXin Li   return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
392*67e74705SXin Li }
393*67e74705SXin Li 
AddPartialSpecialization(ClassTemplatePartialSpecializationDecl * D,void * InsertPos)394*67e74705SXin Li void ClassTemplateDecl::AddPartialSpecialization(
395*67e74705SXin Li                                       ClassTemplatePartialSpecializationDecl *D,
396*67e74705SXin Li                                       void *InsertPos) {
397*67e74705SXin Li   if (InsertPos)
398*67e74705SXin Li     getPartialSpecializations().InsertNode(D, InsertPos);
399*67e74705SXin Li   else {
400*67e74705SXin Li     ClassTemplatePartialSpecializationDecl *Existing
401*67e74705SXin Li       = getPartialSpecializations().GetOrInsertNode(D);
402*67e74705SXin Li     (void)Existing;
403*67e74705SXin Li     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
404*67e74705SXin Li   }
405*67e74705SXin Li 
406*67e74705SXin Li   if (ASTMutationListener *L = getASTMutationListener())
407*67e74705SXin Li     L->AddedCXXTemplateSpecialization(this, D);
408*67e74705SXin Li }
409*67e74705SXin Li 
getPartialSpecializations(SmallVectorImpl<ClassTemplatePartialSpecializationDecl * > & PS)410*67e74705SXin Li void ClassTemplateDecl::getPartialSpecializations(
411*67e74705SXin Li           SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
412*67e74705SXin Li   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
413*67e74705SXin Li     = getPartialSpecializations();
414*67e74705SXin Li   PS.clear();
415*67e74705SXin Li   PS.reserve(PartialSpecs.size());
416*67e74705SXin Li   for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
417*67e74705SXin Li     PS.push_back(P.getMostRecentDecl());
418*67e74705SXin Li }
419*67e74705SXin Li 
420*67e74705SXin Li ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(QualType T)421*67e74705SXin Li ClassTemplateDecl::findPartialSpecialization(QualType T) {
422*67e74705SXin Li   ASTContext &Context = getASTContext();
423*67e74705SXin Li   for (ClassTemplatePartialSpecializationDecl &P :
424*67e74705SXin Li        getPartialSpecializations()) {
425*67e74705SXin Li     if (Context.hasSameType(P.getInjectedSpecializationType(), T))
426*67e74705SXin Li       return P.getMostRecentDecl();
427*67e74705SXin Li   }
428*67e74705SXin Li 
429*67e74705SXin Li   return nullptr;
430*67e74705SXin Li }
431*67e74705SXin Li 
432*67e74705SXin Li ClassTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl * D)433*67e74705SXin Li ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
434*67e74705SXin Li                                     ClassTemplatePartialSpecializationDecl *D) {
435*67e74705SXin Li   Decl *DCanon = D->getCanonicalDecl();
436*67e74705SXin Li   for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
437*67e74705SXin Li     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
438*67e74705SXin Li       return P.getMostRecentDecl();
439*67e74705SXin Li   }
440*67e74705SXin Li 
441*67e74705SXin Li   return nullptr;
442*67e74705SXin Li }
443*67e74705SXin Li 
444*67e74705SXin Li QualType
getInjectedClassNameSpecialization()445*67e74705SXin Li ClassTemplateDecl::getInjectedClassNameSpecialization() {
446*67e74705SXin Li   Common *CommonPtr = getCommonPtr();
447*67e74705SXin Li   if (!CommonPtr->InjectedClassNameType.isNull())
448*67e74705SXin Li     return CommonPtr->InjectedClassNameType;
449*67e74705SXin Li 
450*67e74705SXin Li   // C++0x [temp.dep.type]p2:
451*67e74705SXin Li   //  The template argument list of a primary template is a template argument
452*67e74705SXin Li   //  list in which the nth template argument has the value of the nth template
453*67e74705SXin Li   //  parameter of the class template. If the nth template parameter is a
454*67e74705SXin Li   //  template parameter pack (14.5.3), the nth template argument is a pack
455*67e74705SXin Li   //  expansion (14.5.3) whose pattern is the name of the template parameter
456*67e74705SXin Li   //  pack.
457*67e74705SXin Li   ASTContext &Context = getASTContext();
458*67e74705SXin Li   TemplateParameterList *Params = getTemplateParameters();
459*67e74705SXin Li   SmallVector<TemplateArgument, 16> TemplateArgs;
460*67e74705SXin Li   TemplateArgs.resize(Params->size());
461*67e74705SXin Li   GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
462*67e74705SXin Li   CommonPtr->InjectedClassNameType
463*67e74705SXin Li     = Context.getTemplateSpecializationType(TemplateName(this),
464*67e74705SXin Li                                             TemplateArgs);
465*67e74705SXin Li   return CommonPtr->InjectedClassNameType;
466*67e74705SXin Li }
467*67e74705SXin Li 
468*67e74705SXin Li //===----------------------------------------------------------------------===//
469*67e74705SXin Li // TemplateTypeParm Allocation/Deallocation Method Implementations
470*67e74705SXin Li //===----------------------------------------------------------------------===//
471*67e74705SXin Li 
472*67e74705SXin Li TemplateTypeParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation KeyLoc,SourceLocation NameLoc,unsigned D,unsigned P,IdentifierInfo * Id,bool Typename,bool ParameterPack)473*67e74705SXin Li TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
474*67e74705SXin Li                              SourceLocation KeyLoc, SourceLocation NameLoc,
475*67e74705SXin Li                              unsigned D, unsigned P, IdentifierInfo *Id,
476*67e74705SXin Li                              bool Typename, bool ParameterPack) {
477*67e74705SXin Li   TemplateTypeParmDecl *TTPDecl =
478*67e74705SXin Li     new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
479*67e74705SXin Li   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
480*67e74705SXin Li   TTPDecl->setTypeForDecl(TTPType.getTypePtr());
481*67e74705SXin Li   return TTPDecl;
482*67e74705SXin Li }
483*67e74705SXin Li 
484*67e74705SXin Li TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,unsigned ID)485*67e74705SXin Li TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
486*67e74705SXin Li   return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
487*67e74705SXin Li                                           SourceLocation(), nullptr, false);
488*67e74705SXin Li }
489*67e74705SXin Li 
getDefaultArgumentLoc() const490*67e74705SXin Li SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
491*67e74705SXin Li   return hasDefaultArgument()
492*67e74705SXin Li              ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
493*67e74705SXin Li              : SourceLocation();
494*67e74705SXin Li }
495*67e74705SXin Li 
getSourceRange() const496*67e74705SXin Li SourceRange TemplateTypeParmDecl::getSourceRange() const {
497*67e74705SXin Li   if (hasDefaultArgument() && !defaultArgumentWasInherited())
498*67e74705SXin Li     return SourceRange(getLocStart(),
499*67e74705SXin Li                        getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
500*67e74705SXin Li   else
501*67e74705SXin Li     return TypeDecl::getSourceRange();
502*67e74705SXin Li }
503*67e74705SXin Li 
getDepth() const504*67e74705SXin Li unsigned TemplateTypeParmDecl::getDepth() const {
505*67e74705SXin Li   return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
506*67e74705SXin Li }
507*67e74705SXin Li 
getIndex() const508*67e74705SXin Li unsigned TemplateTypeParmDecl::getIndex() const {
509*67e74705SXin Li   return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
510*67e74705SXin Li }
511*67e74705SXin Li 
isParameterPack() const512*67e74705SXin Li bool TemplateTypeParmDecl::isParameterPack() const {
513*67e74705SXin Li   return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
514*67e74705SXin Li }
515*67e74705SXin Li 
516*67e74705SXin Li //===----------------------------------------------------------------------===//
517*67e74705SXin Li // NonTypeTemplateParmDecl Method Implementations
518*67e74705SXin Li //===----------------------------------------------------------------------===//
519*67e74705SXin Li 
NonTypeTemplateParmDecl(DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,ArrayRef<QualType> ExpandedTypes,ArrayRef<TypeSourceInfo * > ExpandedTInfos)520*67e74705SXin Li NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
521*67e74705SXin Li     DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
522*67e74705SXin Li     unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
523*67e74705SXin Li     ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
524*67e74705SXin Li     : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
525*67e74705SXin Li       TemplateParmPosition(D, P), ParameterPack(true),
526*67e74705SXin Li       ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
527*67e74705SXin Li   if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
528*67e74705SXin Li     auto TypesAndInfos =
529*67e74705SXin Li         getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
530*67e74705SXin Li     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
531*67e74705SXin Li       new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
532*67e74705SXin Li       TypesAndInfos[I].second = ExpandedTInfos[I];
533*67e74705SXin Li     }
534*67e74705SXin Li   }
535*67e74705SXin Li }
536*67e74705SXin Li 
537*67e74705SXin Li NonTypeTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,bool ParameterPack,TypeSourceInfo * TInfo)538*67e74705SXin Li NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
539*67e74705SXin Li                                 SourceLocation StartLoc, SourceLocation IdLoc,
540*67e74705SXin Li                                 unsigned D, unsigned P, IdentifierInfo *Id,
541*67e74705SXin Li                                 QualType T, bool ParameterPack,
542*67e74705SXin Li                                 TypeSourceInfo *TInfo) {
543*67e74705SXin Li   return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
544*67e74705SXin Li                                              T, ParameterPack, TInfo);
545*67e74705SXin Li }
546*67e74705SXin Li 
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,ArrayRef<QualType> ExpandedTypes,ArrayRef<TypeSourceInfo * > ExpandedTInfos)547*67e74705SXin Li NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
548*67e74705SXin Li     const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
549*67e74705SXin Li     SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
550*67e74705SXin Li     QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
551*67e74705SXin Li     ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
552*67e74705SXin Li   return new (C, DC,
553*67e74705SXin Li               additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
554*67e74705SXin Li                   ExpandedTypes.size()))
555*67e74705SXin Li       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
556*67e74705SXin Li                               ExpandedTypes, ExpandedTInfos);
557*67e74705SXin Li }
558*67e74705SXin Li 
559*67e74705SXin Li NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)560*67e74705SXin Li NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
561*67e74705SXin Li   return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
562*67e74705SXin Li                                              SourceLocation(), 0, 0, nullptr,
563*67e74705SXin Li                                              QualType(), false, nullptr);
564*67e74705SXin Li }
565*67e74705SXin Li 
566*67e74705SXin Li NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpandedTypes)567*67e74705SXin Li NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
568*67e74705SXin Li                                             unsigned NumExpandedTypes) {
569*67e74705SXin Li   auto *NTTP =
570*67e74705SXin Li       new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
571*67e74705SXin Li                       NumExpandedTypes))
572*67e74705SXin Li           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
573*67e74705SXin Li                                   0, 0, nullptr, QualType(), nullptr, None,
574*67e74705SXin Li                                   None);
575*67e74705SXin Li   NTTP->NumExpandedTypes = NumExpandedTypes;
576*67e74705SXin Li   return NTTP;
577*67e74705SXin Li }
578*67e74705SXin Li 
getSourceRange() const579*67e74705SXin Li SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
580*67e74705SXin Li   if (hasDefaultArgument() && !defaultArgumentWasInherited())
581*67e74705SXin Li     return SourceRange(getOuterLocStart(),
582*67e74705SXin Li                        getDefaultArgument()->getSourceRange().getEnd());
583*67e74705SXin Li   return DeclaratorDecl::getSourceRange();
584*67e74705SXin Li }
585*67e74705SXin Li 
getDefaultArgumentLoc() const586*67e74705SXin Li SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
587*67e74705SXin Li   return hasDefaultArgument()
588*67e74705SXin Li     ? getDefaultArgument()->getSourceRange().getBegin()
589*67e74705SXin Li     : SourceLocation();
590*67e74705SXin Li }
591*67e74705SXin Li 
592*67e74705SXin Li //===----------------------------------------------------------------------===//
593*67e74705SXin Li // TemplateTemplateParmDecl Method Implementations
594*67e74705SXin Li //===----------------------------------------------------------------------===//
595*67e74705SXin Li 
anchor()596*67e74705SXin Li void TemplateTemplateParmDecl::anchor() { }
597*67e74705SXin Li 
TemplateTemplateParmDecl(DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)598*67e74705SXin Li TemplateTemplateParmDecl::TemplateTemplateParmDecl(
599*67e74705SXin Li     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
600*67e74705SXin Li     IdentifierInfo *Id, TemplateParameterList *Params,
601*67e74705SXin Li     ArrayRef<TemplateParameterList *> Expansions)
602*67e74705SXin Li     : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
603*67e74705SXin Li       TemplateParmPosition(D, P), ParameterPack(true),
604*67e74705SXin Li       ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
605*67e74705SXin Li   if (!Expansions.empty())
606*67e74705SXin Li     std::uninitialized_copy(Expansions.begin(), Expansions.end(),
607*67e74705SXin Li                             getTrailingObjects<TemplateParameterList *>());
608*67e74705SXin Li }
609*67e74705SXin Li 
610*67e74705SXin Li TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,bool ParameterPack,IdentifierInfo * Id,TemplateParameterList * Params)611*67e74705SXin Li TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
612*67e74705SXin Li                                  SourceLocation L, unsigned D, unsigned P,
613*67e74705SXin Li                                  bool ParameterPack, IdentifierInfo *Id,
614*67e74705SXin Li                                  TemplateParameterList *Params) {
615*67e74705SXin Li   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
616*67e74705SXin Li                                               Params);
617*67e74705SXin Li }
618*67e74705SXin Li 
619*67e74705SXin Li TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)620*67e74705SXin Li TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
621*67e74705SXin Li                                  SourceLocation L, unsigned D, unsigned P,
622*67e74705SXin Li                                  IdentifierInfo *Id,
623*67e74705SXin Li                                  TemplateParameterList *Params,
624*67e74705SXin Li                                  ArrayRef<TemplateParameterList *> Expansions) {
625*67e74705SXin Li   return new (C, DC,
626*67e74705SXin Li               additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
627*67e74705SXin Li       TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
628*67e74705SXin Li }
629*67e74705SXin Li 
630*67e74705SXin Li TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)631*67e74705SXin Li TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
632*67e74705SXin Li   return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
633*67e74705SXin Li                                               false, nullptr, nullptr);
634*67e74705SXin Li }
635*67e74705SXin Li 
636*67e74705SXin Li TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpansions)637*67e74705SXin Li TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
638*67e74705SXin Li                                              unsigned NumExpansions) {
639*67e74705SXin Li   auto *TTP =
640*67e74705SXin Li       new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
641*67e74705SXin Li           TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
642*67e74705SXin Li                                    nullptr, None);
643*67e74705SXin Li   TTP->NumExpandedParams = NumExpansions;
644*67e74705SXin Li   return TTP;
645*67e74705SXin Li }
646*67e74705SXin Li 
getDefaultArgumentLoc() const647*67e74705SXin Li SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
648*67e74705SXin Li   return hasDefaultArgument() ? getDefaultArgument().getLocation()
649*67e74705SXin Li                               : SourceLocation();
650*67e74705SXin Li }
651*67e74705SXin Li 
setDefaultArgument(const ASTContext & C,const TemplateArgumentLoc & DefArg)652*67e74705SXin Li void TemplateTemplateParmDecl::setDefaultArgument(
653*67e74705SXin Li     const ASTContext &C, const TemplateArgumentLoc &DefArg) {
654*67e74705SXin Li   if (DefArg.getArgument().isNull())
655*67e74705SXin Li     DefaultArgument.set(nullptr);
656*67e74705SXin Li   else
657*67e74705SXin Li     DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
658*67e74705SXin Li }
659*67e74705SXin Li 
660*67e74705SXin Li //===----------------------------------------------------------------------===//
661*67e74705SXin Li // TemplateArgumentList Implementation
662*67e74705SXin Li //===----------------------------------------------------------------------===//
TemplateArgumentList(ArrayRef<TemplateArgument> Args)663*67e74705SXin Li TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
664*67e74705SXin Li     : Arguments(getTrailingObjects<TemplateArgument>()),
665*67e74705SXin Li       NumArguments(Args.size()) {
666*67e74705SXin Li   std::uninitialized_copy(Args.begin(), Args.end(),
667*67e74705SXin Li                           getTrailingObjects<TemplateArgument>());
668*67e74705SXin Li }
669*67e74705SXin Li 
670*67e74705SXin Li TemplateArgumentList *
CreateCopy(ASTContext & Context,ArrayRef<TemplateArgument> Args)671*67e74705SXin Li TemplateArgumentList::CreateCopy(ASTContext &Context,
672*67e74705SXin Li                                  ArrayRef<TemplateArgument> Args) {
673*67e74705SXin Li   void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
674*67e74705SXin Li   return new (Mem) TemplateArgumentList(Args);
675*67e74705SXin Li }
676*67e74705SXin Li 
677*67e74705SXin Li FunctionTemplateSpecializationInfo *
Create(ASTContext & C,FunctionDecl * FD,FunctionTemplateDecl * Template,TemplateSpecializationKind TSK,const TemplateArgumentList * TemplateArgs,const TemplateArgumentListInfo * TemplateArgsAsWritten,SourceLocation POI)678*67e74705SXin Li FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
679*67e74705SXin Li                                            FunctionTemplateDecl *Template,
680*67e74705SXin Li                                            TemplateSpecializationKind TSK,
681*67e74705SXin Li                                        const TemplateArgumentList *TemplateArgs,
682*67e74705SXin Li                           const TemplateArgumentListInfo *TemplateArgsAsWritten,
683*67e74705SXin Li                                            SourceLocation POI) {
684*67e74705SXin Li   const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
685*67e74705SXin Li   if (TemplateArgsAsWritten)
686*67e74705SXin Li     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
687*67e74705SXin Li                                                         *TemplateArgsAsWritten);
688*67e74705SXin Li 
689*67e74705SXin Li   return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
690*67e74705SXin Li                                                     TemplateArgs,
691*67e74705SXin Li                                                     ArgsAsWritten,
692*67e74705SXin Li                                                     POI);
693*67e74705SXin Li }
694*67e74705SXin Li 
695*67e74705SXin Li //===----------------------------------------------------------------------===//
696*67e74705SXin Li // TemplateDecl Implementation
697*67e74705SXin Li //===----------------------------------------------------------------------===//
698*67e74705SXin Li 
anchor()699*67e74705SXin Li void TemplateDecl::anchor() { }
700*67e74705SXin Li 
701*67e74705SXin Li //===----------------------------------------------------------------------===//
702*67e74705SXin Li // ClassTemplateSpecializationDecl Implementation
703*67e74705SXin Li //===----------------------------------------------------------------------===//
704*67e74705SXin Li ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext & Context,Kind DK,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)705*67e74705SXin Li ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
706*67e74705SXin Li                                 DeclContext *DC, SourceLocation StartLoc,
707*67e74705SXin Li                                 SourceLocation IdLoc,
708*67e74705SXin Li                                 ClassTemplateDecl *SpecializedTemplate,
709*67e74705SXin Li                                 ArrayRef<TemplateArgument> Args,
710*67e74705SXin Li                                 ClassTemplateSpecializationDecl *PrevDecl)
711*67e74705SXin Li   : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
712*67e74705SXin Li                   SpecializedTemplate->getIdentifier(),
713*67e74705SXin Li                   PrevDecl),
714*67e74705SXin Li     SpecializedTemplate(SpecializedTemplate),
715*67e74705SXin Li     ExplicitInfo(nullptr),
716*67e74705SXin Li     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
717*67e74705SXin Li     SpecializationKind(TSK_Undeclared) {
718*67e74705SXin Li }
719*67e74705SXin Li 
ClassTemplateSpecializationDecl(ASTContext & C,Kind DK)720*67e74705SXin Li ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
721*67e74705SXin Li                                                                  Kind DK)
722*67e74705SXin Li     : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
723*67e74705SXin Li                     SourceLocation(), nullptr, nullptr),
724*67e74705SXin Li       ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
725*67e74705SXin Li 
726*67e74705SXin Li ClassTemplateSpecializationDecl *
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,ClassTemplateSpecializationDecl * PrevDecl)727*67e74705SXin Li ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
728*67e74705SXin Li                                         DeclContext *DC,
729*67e74705SXin Li                                         SourceLocation StartLoc,
730*67e74705SXin Li                                         SourceLocation IdLoc,
731*67e74705SXin Li                                         ClassTemplateDecl *SpecializedTemplate,
732*67e74705SXin Li                                         ArrayRef<TemplateArgument> Args,
733*67e74705SXin Li                                    ClassTemplateSpecializationDecl *PrevDecl) {
734*67e74705SXin Li   ClassTemplateSpecializationDecl *Result =
735*67e74705SXin Li       new (Context, DC) ClassTemplateSpecializationDecl(
736*67e74705SXin Li           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
737*67e74705SXin Li           SpecializedTemplate, Args, PrevDecl);
738*67e74705SXin Li   Result->MayHaveOutOfDateDef = false;
739*67e74705SXin Li 
740*67e74705SXin Li   Context.getTypeDeclType(Result, PrevDecl);
741*67e74705SXin Li   return Result;
742*67e74705SXin Li }
743*67e74705SXin Li 
744*67e74705SXin Li ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)745*67e74705SXin Li ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
746*67e74705SXin Li                                                     unsigned ID) {
747*67e74705SXin Li   ClassTemplateSpecializationDecl *Result =
748*67e74705SXin Li     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
749*67e74705SXin Li   Result->MayHaveOutOfDateDef = false;
750*67e74705SXin Li   return Result;
751*67e74705SXin Li }
752*67e74705SXin Li 
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const753*67e74705SXin Li void ClassTemplateSpecializationDecl::getNameForDiagnostic(
754*67e74705SXin Li     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
755*67e74705SXin Li   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
756*67e74705SXin Li 
757*67e74705SXin Li   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
758*67e74705SXin Li   TemplateSpecializationType::PrintTemplateArgumentList(
759*67e74705SXin Li       OS, TemplateArgs.asArray(), Policy);
760*67e74705SXin Li }
761*67e74705SXin Li 
762*67e74705SXin Li ClassTemplateDecl *
getSpecializedTemplate() const763*67e74705SXin Li ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
764*67e74705SXin Li   if (SpecializedPartialSpecialization *PartialSpec
765*67e74705SXin Li       = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
766*67e74705SXin Li     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
767*67e74705SXin Li   return SpecializedTemplate.get<ClassTemplateDecl*>();
768*67e74705SXin Li }
769*67e74705SXin Li 
770*67e74705SXin Li SourceRange
getSourceRange() const771*67e74705SXin Li ClassTemplateSpecializationDecl::getSourceRange() const {
772*67e74705SXin Li   if (ExplicitInfo) {
773*67e74705SXin Li     SourceLocation Begin = getTemplateKeywordLoc();
774*67e74705SXin Li     if (Begin.isValid()) {
775*67e74705SXin Li       // Here we have an explicit (partial) specialization or instantiation.
776*67e74705SXin Li       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
777*67e74705SXin Li              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
778*67e74705SXin Li              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
779*67e74705SXin Li       if (getExternLoc().isValid())
780*67e74705SXin Li         Begin = getExternLoc();
781*67e74705SXin Li       SourceLocation End = getRBraceLoc();
782*67e74705SXin Li       if (End.isInvalid())
783*67e74705SXin Li         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
784*67e74705SXin Li       return SourceRange(Begin, End);
785*67e74705SXin Li     }
786*67e74705SXin Li     // An implicit instantiation of a class template partial specialization
787*67e74705SXin Li     // uses ExplicitInfo to record the TypeAsWritten, but the source
788*67e74705SXin Li     // locations should be retrieved from the instantiation pattern.
789*67e74705SXin Li     typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
790*67e74705SXin Li     CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
791*67e74705SXin Li     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
792*67e74705SXin Li     assert(inst_from != nullptr);
793*67e74705SXin Li     return inst_from->getSourceRange();
794*67e74705SXin Li   }
795*67e74705SXin Li   else {
796*67e74705SXin Li     // No explicit info available.
797*67e74705SXin Li     llvm::PointerUnion<ClassTemplateDecl *,
798*67e74705SXin Li                        ClassTemplatePartialSpecializationDecl *>
799*67e74705SXin Li       inst_from = getInstantiatedFrom();
800*67e74705SXin Li     if (inst_from.isNull())
801*67e74705SXin Li       return getSpecializedTemplate()->getSourceRange();
802*67e74705SXin Li     if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
803*67e74705SXin Li       return ctd->getSourceRange();
804*67e74705SXin Li     return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
805*67e74705SXin Li       ->getSourceRange();
806*67e74705SXin Li   }
807*67e74705SXin Li }
808*67e74705SXin Li 
809*67e74705SXin Li //===----------------------------------------------------------------------===//
810*67e74705SXin Li // ClassTemplatePartialSpecializationDecl Implementation
811*67e74705SXin Li //===----------------------------------------------------------------------===//
anchor()812*67e74705SXin Li void ClassTemplatePartialSpecializationDecl::anchor() { }
813*67e74705SXin Li 
814*67e74705SXin Li ClassTemplatePartialSpecializationDecl::
ClassTemplatePartialSpecializationDecl(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,const ASTTemplateArgumentListInfo * ArgInfos,ClassTemplatePartialSpecializationDecl * PrevDecl)815*67e74705SXin Li ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
816*67e74705SXin Li                                        DeclContext *DC,
817*67e74705SXin Li                                        SourceLocation StartLoc,
818*67e74705SXin Li                                        SourceLocation IdLoc,
819*67e74705SXin Li                                        TemplateParameterList *Params,
820*67e74705SXin Li                                        ClassTemplateDecl *SpecializedTemplate,
821*67e74705SXin Li                                        ArrayRef<TemplateArgument> Args,
822*67e74705SXin Li                                const ASTTemplateArgumentListInfo *ArgInfos,
823*67e74705SXin Li                                ClassTemplatePartialSpecializationDecl *PrevDecl)
824*67e74705SXin Li   : ClassTemplateSpecializationDecl(Context,
825*67e74705SXin Li                                     ClassTemplatePartialSpecialization,
826*67e74705SXin Li                                     TK, DC, StartLoc, IdLoc,
827*67e74705SXin Li                                     SpecializedTemplate,
828*67e74705SXin Li                                     Args, PrevDecl),
829*67e74705SXin Li     TemplateParams(Params), ArgsAsWritten(ArgInfos),
830*67e74705SXin Li     InstantiatedFromMember(nullptr, false)
831*67e74705SXin Li {
832*67e74705SXin Li   AdoptTemplateParameterList(Params, this);
833*67e74705SXin Li }
834*67e74705SXin Li 
835*67e74705SXin Li ClassTemplatePartialSpecializationDecl *
836*67e74705SXin Li ClassTemplatePartialSpecializationDecl::
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,ArrayRef<TemplateArgument> Args,const TemplateArgumentListInfo & ArgInfos,QualType CanonInjectedType,ClassTemplatePartialSpecializationDecl * PrevDecl)837*67e74705SXin Li Create(ASTContext &Context, TagKind TK,DeclContext *DC,
838*67e74705SXin Li        SourceLocation StartLoc, SourceLocation IdLoc,
839*67e74705SXin Li        TemplateParameterList *Params,
840*67e74705SXin Li        ClassTemplateDecl *SpecializedTemplate,
841*67e74705SXin Li        ArrayRef<TemplateArgument> Args,
842*67e74705SXin Li        const TemplateArgumentListInfo &ArgInfos,
843*67e74705SXin Li        QualType CanonInjectedType,
844*67e74705SXin Li        ClassTemplatePartialSpecializationDecl *PrevDecl) {
845*67e74705SXin Li   const ASTTemplateArgumentListInfo *ASTArgInfos =
846*67e74705SXin Li     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
847*67e74705SXin Li 
848*67e74705SXin Li   ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
849*67e74705SXin Li       ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
850*67e74705SXin Li                                              Params, SpecializedTemplate, Args,
851*67e74705SXin Li                                              ASTArgInfos, PrevDecl);
852*67e74705SXin Li   Result->setSpecializationKind(TSK_ExplicitSpecialization);
853*67e74705SXin Li   Result->MayHaveOutOfDateDef = false;
854*67e74705SXin Li 
855*67e74705SXin Li   Context.getInjectedClassNameType(Result, CanonInjectedType);
856*67e74705SXin Li   return Result;
857*67e74705SXin Li }
858*67e74705SXin Li 
859*67e74705SXin Li ClassTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)860*67e74705SXin Li ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
861*67e74705SXin Li                                                            unsigned ID) {
862*67e74705SXin Li   ClassTemplatePartialSpecializationDecl *Result =
863*67e74705SXin Li       new (C, ID) ClassTemplatePartialSpecializationDecl(C);
864*67e74705SXin Li   Result->MayHaveOutOfDateDef = false;
865*67e74705SXin Li   return Result;
866*67e74705SXin Li }
867*67e74705SXin Li 
868*67e74705SXin Li //===----------------------------------------------------------------------===//
869*67e74705SXin Li // FriendTemplateDecl Implementation
870*67e74705SXin Li //===----------------------------------------------------------------------===//
871*67e74705SXin Li 
anchor()872*67e74705SXin Li void FriendTemplateDecl::anchor() { }
873*67e74705SXin Li 
874*67e74705SXin Li FriendTemplateDecl *
Create(ASTContext & Context,DeclContext * DC,SourceLocation L,MutableArrayRef<TemplateParameterList * > Params,FriendUnion Friend,SourceLocation FLoc)875*67e74705SXin Li FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
876*67e74705SXin Li                            SourceLocation L,
877*67e74705SXin Li                            MutableArrayRef<TemplateParameterList *> Params,
878*67e74705SXin Li                            FriendUnion Friend, SourceLocation FLoc) {
879*67e74705SXin Li   return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
880*67e74705SXin Li }
881*67e74705SXin Li 
CreateDeserialized(ASTContext & C,unsigned ID)882*67e74705SXin Li FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
883*67e74705SXin Li                                                            unsigned ID) {
884*67e74705SXin Li   return new (C, ID) FriendTemplateDecl(EmptyShell());
885*67e74705SXin Li }
886*67e74705SXin Li 
887*67e74705SXin Li //===----------------------------------------------------------------------===//
888*67e74705SXin Li // TypeAliasTemplateDecl Implementation
889*67e74705SXin Li //===----------------------------------------------------------------------===//
890*67e74705SXin Li 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)891*67e74705SXin Li TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
892*67e74705SXin Li                                                      DeclContext *DC,
893*67e74705SXin Li                                                      SourceLocation L,
894*67e74705SXin Li                                                      DeclarationName Name,
895*67e74705SXin Li                                                   TemplateParameterList *Params,
896*67e74705SXin Li                                                      NamedDecl *Decl) {
897*67e74705SXin Li   AdoptTemplateParameterList(Params, DC);
898*67e74705SXin Li   return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
899*67e74705SXin Li }
900*67e74705SXin Li 
CreateDeserialized(ASTContext & C,unsigned ID)901*67e74705SXin Li TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
902*67e74705SXin Li                                                                  unsigned ID) {
903*67e74705SXin Li   return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
904*67e74705SXin Li                                            DeclarationName(), nullptr, nullptr);
905*67e74705SXin Li }
906*67e74705SXin Li 
DeallocateCommon(void * Ptr)907*67e74705SXin Li void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
908*67e74705SXin Li   static_cast<Common *>(Ptr)->~Common();
909*67e74705SXin Li }
910*67e74705SXin Li RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const911*67e74705SXin Li TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
912*67e74705SXin Li   Common *CommonPtr = new (C) Common;
913*67e74705SXin Li   C.AddDeallocation(DeallocateCommon, CommonPtr);
914*67e74705SXin Li   return CommonPtr;
915*67e74705SXin Li }
916*67e74705SXin Li 
917*67e74705SXin Li //===----------------------------------------------------------------------===//
918*67e74705SXin Li // ClassScopeFunctionSpecializationDecl Implementation
919*67e74705SXin Li //===----------------------------------------------------------------------===//
920*67e74705SXin Li 
anchor()921*67e74705SXin Li void ClassScopeFunctionSpecializationDecl::anchor() { }
922*67e74705SXin Li 
923*67e74705SXin Li ClassScopeFunctionSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)924*67e74705SXin Li ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
925*67e74705SXin Li                                                          unsigned ID) {
926*67e74705SXin Li   return new (C, ID) ClassScopeFunctionSpecializationDecl(
927*67e74705SXin Li       nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
928*67e74705SXin Li }
929*67e74705SXin Li 
930*67e74705SXin Li //===----------------------------------------------------------------------===//
931*67e74705SXin Li // VarTemplateDecl Implementation
932*67e74705SXin Li //===----------------------------------------------------------------------===//
933*67e74705SXin Li 
DeallocateCommon(void * Ptr)934*67e74705SXin Li void VarTemplateDecl::DeallocateCommon(void *Ptr) {
935*67e74705SXin Li   static_cast<Common *>(Ptr)->~Common();
936*67e74705SXin Li }
937*67e74705SXin Li 
getDefinition()938*67e74705SXin Li VarTemplateDecl *VarTemplateDecl::getDefinition() {
939*67e74705SXin Li   VarTemplateDecl *CurD = this;
940*67e74705SXin Li   while (CurD) {
941*67e74705SXin Li     if (CurD->isThisDeclarationADefinition())
942*67e74705SXin Li       return CurD;
943*67e74705SXin Li     CurD = CurD->getPreviousDecl();
944*67e74705SXin Li   }
945*67e74705SXin Li   return nullptr;
946*67e74705SXin Li }
947*67e74705SXin Li 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,VarDecl * Decl)948*67e74705SXin Li VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
949*67e74705SXin Li                                          SourceLocation L, DeclarationName Name,
950*67e74705SXin Li                                          TemplateParameterList *Params,
951*67e74705SXin Li                                          VarDecl *Decl) {
952*67e74705SXin Li   return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
953*67e74705SXin Li }
954*67e74705SXin Li 
CreateDeserialized(ASTContext & C,unsigned ID)955*67e74705SXin Li VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
956*67e74705SXin Li                                                      unsigned ID) {
957*67e74705SXin Li   return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
958*67e74705SXin Li                                      DeclarationName(), nullptr, nullptr);
959*67e74705SXin Li }
960*67e74705SXin Li 
961*67e74705SXin Li // TODO: Unify across class, function and variable templates?
962*67e74705SXin Li //       May require moving this and Common to RedeclarableTemplateDecl.
LoadLazySpecializations() const963*67e74705SXin Li void VarTemplateDecl::LoadLazySpecializations() const {
964*67e74705SXin Li   // Grab the most recent declaration to ensure we've loaded any lazy
965*67e74705SXin Li   // redeclarations of this template.
966*67e74705SXin Li   //
967*67e74705SXin Li   // FIXME: Avoid walking the entire redeclaration chain here.
968*67e74705SXin Li   Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
969*67e74705SXin Li   if (CommonPtr->LazySpecializations) {
970*67e74705SXin Li     ASTContext &Context = getASTContext();
971*67e74705SXin Li     uint32_t *Specs = CommonPtr->LazySpecializations;
972*67e74705SXin Li     CommonPtr->LazySpecializations = nullptr;
973*67e74705SXin Li     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
974*67e74705SXin Li       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
975*67e74705SXin Li   }
976*67e74705SXin Li }
977*67e74705SXin Li 
978*67e74705SXin Li llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
getSpecializations() const979*67e74705SXin Li VarTemplateDecl::getSpecializations() const {
980*67e74705SXin Li   LoadLazySpecializations();
981*67e74705SXin Li   return getCommonPtr()->Specializations;
982*67e74705SXin Li }
983*67e74705SXin Li 
984*67e74705SXin Li llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations()985*67e74705SXin Li VarTemplateDecl::getPartialSpecializations() {
986*67e74705SXin Li   LoadLazySpecializations();
987*67e74705SXin Li   return getCommonPtr()->PartialSpecializations;
988*67e74705SXin Li }
989*67e74705SXin Li 
990*67e74705SXin Li RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const991*67e74705SXin Li VarTemplateDecl::newCommon(ASTContext &C) const {
992*67e74705SXin Li   Common *CommonPtr = new (C) Common;
993*67e74705SXin Li   C.AddDeallocation(DeallocateCommon, CommonPtr);
994*67e74705SXin Li   return CommonPtr;
995*67e74705SXin Li }
996*67e74705SXin Li 
997*67e74705SXin Li VarTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)998*67e74705SXin Li VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
999*67e74705SXin Li                                     void *&InsertPos) {
1000*67e74705SXin Li   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
1001*67e74705SXin Li }
1002*67e74705SXin Li 
AddSpecialization(VarTemplateSpecializationDecl * D,void * InsertPos)1003*67e74705SXin Li void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1004*67e74705SXin Li                                         void *InsertPos) {
1005*67e74705SXin Li   addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1006*67e74705SXin Li }
1007*67e74705SXin Li 
1008*67e74705SXin Li VarTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)1009*67e74705SXin Li VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1010*67e74705SXin Li                                            void *&InsertPos) {
1011*67e74705SXin Li   return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1012*67e74705SXin Li }
1013*67e74705SXin Li 
AddPartialSpecialization(VarTemplatePartialSpecializationDecl * D,void * InsertPos)1014*67e74705SXin Li void VarTemplateDecl::AddPartialSpecialization(
1015*67e74705SXin Li     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1016*67e74705SXin Li   if (InsertPos)
1017*67e74705SXin Li     getPartialSpecializations().InsertNode(D, InsertPos);
1018*67e74705SXin Li   else {
1019*67e74705SXin Li     VarTemplatePartialSpecializationDecl *Existing =
1020*67e74705SXin Li         getPartialSpecializations().GetOrInsertNode(D);
1021*67e74705SXin Li     (void)Existing;
1022*67e74705SXin Li     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1023*67e74705SXin Li   }
1024*67e74705SXin Li 
1025*67e74705SXin Li   if (ASTMutationListener *L = getASTMutationListener())
1026*67e74705SXin Li     L->AddedCXXTemplateSpecialization(this, D);
1027*67e74705SXin Li }
1028*67e74705SXin Li 
getPartialSpecializations(SmallVectorImpl<VarTemplatePartialSpecializationDecl * > & PS)1029*67e74705SXin Li void VarTemplateDecl::getPartialSpecializations(
1030*67e74705SXin Li     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1031*67e74705SXin Li   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1032*67e74705SXin Li       getPartialSpecializations();
1033*67e74705SXin Li   PS.clear();
1034*67e74705SXin Li   PS.reserve(PartialSpecs.size());
1035*67e74705SXin Li   for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1036*67e74705SXin Li     PS.push_back(P.getMostRecentDecl());
1037*67e74705SXin Li }
1038*67e74705SXin Li 
1039*67e74705SXin Li VarTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl * D)1040*67e74705SXin Li VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1041*67e74705SXin Li     VarTemplatePartialSpecializationDecl *D) {
1042*67e74705SXin Li   Decl *DCanon = D->getCanonicalDecl();
1043*67e74705SXin Li   for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1044*67e74705SXin Li     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1045*67e74705SXin Li       return P.getMostRecentDecl();
1046*67e74705SXin Li   }
1047*67e74705SXin Li 
1048*67e74705SXin Li   return nullptr;
1049*67e74705SXin Li }
1050*67e74705SXin Li 
1051*67e74705SXin Li //===----------------------------------------------------------------------===//
1052*67e74705SXin Li // VarTemplateSpecializationDecl Implementation
1053*67e74705SXin Li //===----------------------------------------------------------------------===//
VarTemplateSpecializationDecl(Kind DK,ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1054*67e74705SXin Li VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1055*67e74705SXin Li     Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1056*67e74705SXin Li     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1057*67e74705SXin Li     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1058*67e74705SXin Li     : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1059*67e74705SXin Li               SpecializedTemplate->getIdentifier(), T, TInfo, S),
1060*67e74705SXin Li       SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
1061*67e74705SXin Li       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1062*67e74705SXin Li       SpecializationKind(TSK_Undeclared) {}
1063*67e74705SXin Li 
VarTemplateSpecializationDecl(Kind DK,ASTContext & C)1064*67e74705SXin Li VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1065*67e74705SXin Li                                                              ASTContext &C)
1066*67e74705SXin Li     : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1067*67e74705SXin Li               QualType(), nullptr, SC_None),
1068*67e74705SXin Li       ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
1069*67e74705SXin Li 
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args)1070*67e74705SXin Li VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1071*67e74705SXin Li     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1072*67e74705SXin Li     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1073*67e74705SXin Li     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1074*67e74705SXin Li   return new (Context, DC) VarTemplateSpecializationDecl(
1075*67e74705SXin Li       VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1076*67e74705SXin Li       SpecializedTemplate, T, TInfo, S, Args);
1077*67e74705SXin Li }
1078*67e74705SXin Li 
1079*67e74705SXin Li VarTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1080*67e74705SXin Li VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1081*67e74705SXin Li   return new (C, ID)
1082*67e74705SXin Li       VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1083*67e74705SXin Li }
1084*67e74705SXin Li 
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const1085*67e74705SXin Li void VarTemplateSpecializationDecl::getNameForDiagnostic(
1086*67e74705SXin Li     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1087*67e74705SXin Li   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1088*67e74705SXin Li 
1089*67e74705SXin Li   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1090*67e74705SXin Li   TemplateSpecializationType::PrintTemplateArgumentList(
1091*67e74705SXin Li       OS, TemplateArgs.asArray(), Policy);
1092*67e74705SXin Li }
1093*67e74705SXin Li 
getSpecializedTemplate() const1094*67e74705SXin Li VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1095*67e74705SXin Li   if (SpecializedPartialSpecialization *PartialSpec =
1096*67e74705SXin Li           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1097*67e74705SXin Li     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1098*67e74705SXin Li   return SpecializedTemplate.get<VarTemplateDecl *>();
1099*67e74705SXin Li }
1100*67e74705SXin Li 
setTemplateArgsInfo(const TemplateArgumentListInfo & ArgsInfo)1101*67e74705SXin Li void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1102*67e74705SXin Li     const TemplateArgumentListInfo &ArgsInfo) {
1103*67e74705SXin Li   TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1104*67e74705SXin Li   TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1105*67e74705SXin Li   for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1106*67e74705SXin Li     TemplateArgsInfo.addArgument(Loc);
1107*67e74705SXin Li }
1108*67e74705SXin Li 
1109*67e74705SXin Li //===----------------------------------------------------------------------===//
1110*67e74705SXin Li // VarTemplatePartialSpecializationDecl Implementation
1111*67e74705SXin Li //===----------------------------------------------------------------------===//
anchor()1112*67e74705SXin Li void VarTemplatePartialSpecializationDecl::anchor() {}
1113*67e74705SXin Li 
VarTemplatePartialSpecializationDecl(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args,const ASTTemplateArgumentListInfo * ArgInfos)1114*67e74705SXin Li VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1115*67e74705SXin Li     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1116*67e74705SXin Li     SourceLocation IdLoc, TemplateParameterList *Params,
1117*67e74705SXin Li     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1118*67e74705SXin Li     StorageClass S, ArrayRef<TemplateArgument> Args,
1119*67e74705SXin Li     const ASTTemplateArgumentListInfo *ArgInfos)
1120*67e74705SXin Li     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1121*67e74705SXin Li                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
1122*67e74705SXin Li                                     TInfo, S, Args),
1123*67e74705SXin Li       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1124*67e74705SXin Li       InstantiatedFromMember(nullptr, false) {
1125*67e74705SXin Li   // TODO: The template parameters should be in DC by now. Verify.
1126*67e74705SXin Li   // AdoptTemplateParameterList(Params, DC);
1127*67e74705SXin Li }
1128*67e74705SXin Li 
1129*67e74705SXin Li VarTemplatePartialSpecializationDecl *
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,ArrayRef<TemplateArgument> Args,const TemplateArgumentListInfo & ArgInfos)1130*67e74705SXin Li VarTemplatePartialSpecializationDecl::Create(
1131*67e74705SXin Li     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1132*67e74705SXin Li     SourceLocation IdLoc, TemplateParameterList *Params,
1133*67e74705SXin Li     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1134*67e74705SXin Li     StorageClass S, ArrayRef<TemplateArgument> Args,
1135*67e74705SXin Li     const TemplateArgumentListInfo &ArgInfos) {
1136*67e74705SXin Li   const ASTTemplateArgumentListInfo *ASTArgInfos
1137*67e74705SXin Li     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1138*67e74705SXin Li 
1139*67e74705SXin Li   VarTemplatePartialSpecializationDecl *Result =
1140*67e74705SXin Li       new (Context, DC) VarTemplatePartialSpecializationDecl(
1141*67e74705SXin Li           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1142*67e74705SXin Li           S, Args, ASTArgInfos);
1143*67e74705SXin Li   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1144*67e74705SXin Li   return Result;
1145*67e74705SXin Li }
1146*67e74705SXin Li 
1147*67e74705SXin Li VarTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1148*67e74705SXin Li VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1149*67e74705SXin Li                                                          unsigned ID) {
1150*67e74705SXin Li   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1151*67e74705SXin Li }
1152*67e74705SXin Li 
1153*67e74705SXin Li static TemplateParameterList *
createMakeIntegerSeqParameterList(const ASTContext & C,DeclContext * DC)1154*67e74705SXin Li createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1155*67e74705SXin Li   // typename T
1156*67e74705SXin Li   auto *T = TemplateTypeParmDecl::Create(
1157*67e74705SXin Li       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1158*67e74705SXin Li       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1159*67e74705SXin Li   T->setImplicit(true);
1160*67e74705SXin Li 
1161*67e74705SXin Li   // T ...Ints
1162*67e74705SXin Li   TypeSourceInfo *TI =
1163*67e74705SXin Li       C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1164*67e74705SXin Li   auto *N = NonTypeTemplateParmDecl::Create(
1165*67e74705SXin Li       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1166*67e74705SXin Li       /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1167*67e74705SXin Li   N->setImplicit(true);
1168*67e74705SXin Li 
1169*67e74705SXin Li   // <typename T, T ...Ints>
1170*67e74705SXin Li   NamedDecl *P[2] = {T, N};
1171*67e74705SXin Li   auto *TPL = TemplateParameterList::Create(
1172*67e74705SXin Li       C, SourceLocation(), SourceLocation(), P, SourceLocation());
1173*67e74705SXin Li 
1174*67e74705SXin Li   // template <typename T, ...Ints> class IntSeq
1175*67e74705SXin Li   auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1176*67e74705SXin Li       C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1177*67e74705SXin Li       /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1178*67e74705SXin Li   TemplateTemplateParm->setImplicit(true);
1179*67e74705SXin Li 
1180*67e74705SXin Li   // typename T
1181*67e74705SXin Li   auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1182*67e74705SXin Li       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1183*67e74705SXin Li       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1184*67e74705SXin Li   TemplateTypeParm->setImplicit(true);
1185*67e74705SXin Li 
1186*67e74705SXin Li   // T N
1187*67e74705SXin Li   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1188*67e74705SXin Li       QualType(TemplateTypeParm->getTypeForDecl(), 0));
1189*67e74705SXin Li   auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1190*67e74705SXin Li       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1191*67e74705SXin Li       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1192*67e74705SXin Li   NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1193*67e74705SXin Li                          NonTypeTemplateParm};
1194*67e74705SXin Li 
1195*67e74705SXin Li   // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1196*67e74705SXin Li   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1197*67e74705SXin Li                                        Params, SourceLocation());
1198*67e74705SXin Li }
1199*67e74705SXin Li 
1200*67e74705SXin Li static TemplateParameterList *
createTypePackElementParameterList(const ASTContext & C,DeclContext * DC)1201*67e74705SXin Li createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1202*67e74705SXin Li   // std::size_t Index
1203*67e74705SXin Li   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1204*67e74705SXin Li   auto *Index = NonTypeTemplateParmDecl::Create(
1205*67e74705SXin Li       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1206*67e74705SXin Li       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1207*67e74705SXin Li 
1208*67e74705SXin Li   // typename ...T
1209*67e74705SXin Li   auto *Ts = TemplateTypeParmDecl::Create(
1210*67e74705SXin Li       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1211*67e74705SXin Li       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1212*67e74705SXin Li   Ts->setImplicit(true);
1213*67e74705SXin Li 
1214*67e74705SXin Li   // template <std::size_t Index, typename ...T>
1215*67e74705SXin Li   NamedDecl *Params[] = {Index, Ts};
1216*67e74705SXin Li   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1217*67e74705SXin Li                                        llvm::makeArrayRef(Params),
1218*67e74705SXin Li                                        SourceLocation());
1219*67e74705SXin Li }
1220*67e74705SXin Li 
createBuiltinTemplateParameterList(const ASTContext & C,DeclContext * DC,BuiltinTemplateKind BTK)1221*67e74705SXin Li static TemplateParameterList *createBuiltinTemplateParameterList(
1222*67e74705SXin Li     const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1223*67e74705SXin Li   switch (BTK) {
1224*67e74705SXin Li   case BTK__make_integer_seq:
1225*67e74705SXin Li     return createMakeIntegerSeqParameterList(C, DC);
1226*67e74705SXin Li   case BTK__type_pack_element:
1227*67e74705SXin Li     return createTypePackElementParameterList(C, DC);
1228*67e74705SXin Li   }
1229*67e74705SXin Li 
1230*67e74705SXin Li   llvm_unreachable("unhandled BuiltinTemplateKind!");
1231*67e74705SXin Li }
1232*67e74705SXin Li 
anchor()1233*67e74705SXin Li void BuiltinTemplateDecl::anchor() {}
1234*67e74705SXin Li 
BuiltinTemplateDecl(const ASTContext & C,DeclContext * DC,DeclarationName Name,BuiltinTemplateKind BTK)1235*67e74705SXin Li BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1236*67e74705SXin Li                                          DeclarationName Name,
1237*67e74705SXin Li                                          BuiltinTemplateKind BTK)
1238*67e74705SXin Li     : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1239*67e74705SXin Li                    createBuiltinTemplateParameterList(C, DC, BTK)),
1240*67e74705SXin Li       BTK(BTK) {}
1241