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