1198893Srdivacky//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file implements the C++ related Decl classes for templates.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14249423Sdim#include "clang/AST/DeclTemplate.h"
15249423Sdim#include "clang/AST/ASTContext.h"
16249423Sdim#include "clang/AST/ASTMutationListener.h"
17193326Sed#include "clang/AST/DeclCXX.h"
18193326Sed#include "clang/AST/Expr.h"
19218893Sdim#include "clang/AST/ExprCXX.h"
20198893Srdivacky#include "clang/AST/TypeLoc.h"
21193326Sed#include "clang/Basic/IdentifierTable.h"
22193326Sed#include "llvm/ADT/STLExtras.h"
23218893Sdim#include <memory>
24193326Sedusing namespace clang;
25193326Sed
26193326Sed//===----------------------------------------------------------------------===//
27193326Sed// TemplateParameterList Implementation
28193326Sed//===----------------------------------------------------------------------===//
29193326Sed
30193326SedTemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
31193326Sed                                             SourceLocation LAngleLoc,
32198092Srdivacky                                             NamedDecl **Params, unsigned NumParams,
33193326Sed                                             SourceLocation RAngleLoc)
34193326Sed  : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
35243830Sdim    NumParams(NumParams), ContainsUnexpandedParameterPack(false) {
36243830Sdim  assert(this->NumParams == NumParams && "Too many template parameters");
37243830Sdim  for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
38243830Sdim    NamedDecl *P = Params[Idx];
39243830Sdim    begin()[Idx] = P;
40243830Sdim
41243830Sdim    if (!P->isTemplateParameterPack()) {
42243830Sdim      if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
43243830Sdim        if (NTTP->getType()->containsUnexpandedParameterPack())
44243830Sdim          ContainsUnexpandedParameterPack = true;
45243830Sdim
46243830Sdim      if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
47243830Sdim        if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
48243830Sdim          ContainsUnexpandedParameterPack = true;
49243830Sdim
50243830Sdim      // FIXME: If a default argument contains an unexpanded parameter pack, the
51243830Sdim      // template parameter list does too.
52243830Sdim    }
53243830Sdim  }
54193326Sed}
55193326Sed
56193326SedTemplateParameterList *
57218893SdimTemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
58198092Srdivacky                              SourceLocation LAngleLoc, NamedDecl **Params,
59193326Sed                              unsigned NumParams, SourceLocation RAngleLoc) {
60198092Srdivacky  unsigned Size = sizeof(TemplateParameterList)
61198092Srdivacky                + sizeof(NamedDecl *) * NumParams;
62239462Sdim  unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
63239462Sdim                            llvm::alignOf<NamedDecl*>());
64193326Sed  void *Mem = C.Allocate(Size, Align);
65198092Srdivacky  return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
66193326Sed                                         NumParams, RAngleLoc);
67193326Sed}
68193326Sed
69193326Sedunsigned TemplateParameterList::getMinRequiredArguments() const {
70218893Sdim  unsigned NumRequiredArgs = 0;
71218893Sdim  for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
72218893Sdim             PEnd = const_cast<TemplateParameterList *>(this)->end();
73218893Sdim       P != PEnd; ++P) {
74218893Sdim    if ((*P)->isTemplateParameterPack()) {
75218893Sdim      if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
76218893Sdim        if (NTTP->isExpandedParameterPack()) {
77218893Sdim          NumRequiredArgs += NTTP->getNumExpansionTypes();
78218893Sdim          continue;
79218893Sdim        }
80218893Sdim
81193326Sed      break;
82218893Sdim    }
83218893Sdim
84218893Sdim    if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
85218893Sdim      if (TTP->hasDefaultArgument())
86218893Sdim        break;
87218893Sdim    } else if (NonTypeTemplateParmDecl *NTTP
88218893Sdim                                    = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
89218893Sdim      if (NTTP->hasDefaultArgument())
90218893Sdim        break;
91218893Sdim    } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
92218893Sdim      break;
93218893Sdim
94218893Sdim    ++NumRequiredArgs;
95193326Sed  }
96218893Sdim
97193326Sed  return NumRequiredArgs;
98193326Sed}
99193326Sed
100198893Srdivackyunsigned TemplateParameterList::getDepth() const {
101198893Srdivacky  if (size() == 0)
102198893Srdivacky    return 0;
103198893Srdivacky
104198893Srdivacky  const NamedDecl *FirstParm = getParam(0);
105198893Srdivacky  if (const TemplateTypeParmDecl *TTP
106198893Srdivacky        = dyn_cast<TemplateTypeParmDecl>(FirstParm))
107198893Srdivacky    return TTP->getDepth();
108198893Srdivacky  else if (const NonTypeTemplateParmDecl *NTTP
109198893Srdivacky             = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
110198893Srdivacky    return NTTP->getDepth();
111198893Srdivacky  else
112198893Srdivacky    return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
113198893Srdivacky}
114198893Srdivacky
115221345Sdimstatic void AdoptTemplateParameterList(TemplateParameterList *Params,
116221345Sdim                                       DeclContext *Owner) {
117221345Sdim  for (TemplateParameterList::iterator P = Params->begin(),
118221345Sdim                                    PEnd = Params->end();
119221345Sdim       P != PEnd; ++P) {
120221345Sdim    (*P)->setDeclContext(Owner);
121221345Sdim
122221345Sdim    if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
123221345Sdim      AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
124221345Sdim  }
125221345Sdim}
126221345Sdim
127193326Sed//===----------------------------------------------------------------------===//
128212904Sdim// RedeclarableTemplateDecl Implementation
129193326Sed//===----------------------------------------------------------------------===//
130193326Sed
131249423SdimRedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
132234353Sdim  if (!Common) {
133234353Sdim    // Walk the previous-declaration chain until we either find a declaration
134234353Sdim    // with a common pointer or we run out of previous declarations.
135249423Sdim    SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
136249423Sdim    for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
137234353Sdim         Prev = Prev->getPreviousDecl()) {
138234353Sdim      if (Prev->Common) {
139234353Sdim        Common = Prev->Common;
140234353Sdim        break;
141234353Sdim      }
142234353Sdim
143234353Sdim      PrevDecls.push_back(Prev);
144234353Sdim    }
145212904Sdim
146234353Sdim    // If we never found a common pointer, allocate one now.
147234353Sdim    if (!Common) {
148234353Sdim      // FIXME: If any of the declarations is from an AST file, we probably
149234353Sdim      // need an update record to add the common data.
150234353Sdim
151234353Sdim      Common = newCommon(getASTContext());
152234353Sdim    }
153234353Sdim
154234353Sdim    // Update any previous declarations we saw with the common pointer.
155234353Sdim    for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I)
156234353Sdim      PrevDecls[I]->Common = Common;
157212904Sdim  }
158193326Sed
159234353Sdim  return Common;
160212904Sdim}
161212904Sdim
162212904Sdimtemplate <class EntryType>
163212904Sdimtypename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
164212904SdimRedeclarableTemplateDecl::findSpecializationImpl(
165239462Sdim                                 llvm::FoldingSetVector<EntryType> &Specs,
166212904Sdim                                 const TemplateArgument *Args, unsigned NumArgs,
167212904Sdim                                 void *&InsertPos) {
168212904Sdim  typedef SpecEntryTraits<EntryType> SETraits;
169212904Sdim  llvm::FoldingSetNodeID ID;
170212904Sdim  EntryType::Profile(ID,Args,NumArgs, getASTContext());
171212904Sdim  EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
172234353Sdim  return Entry ? SETraits::getMostRecentDecl(Entry) : 0;
173212904Sdim}
174212904Sdim
175221345Sdim/// \brief Generate the injected template arguments for the given template
176221345Sdim/// parameter list, e.g., for the injected-class-name of a class template.
177221345Sdimstatic void GenerateInjectedTemplateArgs(ASTContext &Context,
178221345Sdim                                        TemplateParameterList *Params,
179221345Sdim                                         TemplateArgument *Args) {
180221345Sdim  for (TemplateParameterList::iterator Param = Params->begin(),
181221345Sdim                                    ParamEnd = Params->end();
182221345Sdim       Param != ParamEnd; ++Param) {
183221345Sdim    TemplateArgument Arg;
184221345Sdim    if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
185221345Sdim      QualType ArgType = Context.getTypeDeclType(TTP);
186221345Sdim      if (TTP->isParameterPack())
187249423Sdim        ArgType = Context.getPackExpansionType(ArgType, None);
188249423Sdim
189221345Sdim      Arg = TemplateArgument(ArgType);
190221345Sdim    } else if (NonTypeTemplateParmDecl *NTTP =
191221345Sdim               dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
192234353Sdim      Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
193221345Sdim                                  NTTP->getType().getNonLValueExprType(Context),
194221345Sdim                                  Expr::getValueKindForType(NTTP->getType()),
195221345Sdim                                          NTTP->getLocation());
196221345Sdim
197221345Sdim      if (NTTP->isParameterPack())
198221345Sdim        E = new (Context) PackExpansionExpr(Context.DependentTy, E,
199249423Sdim                                            NTTP->getLocation(), None);
200221345Sdim      Arg = TemplateArgument(E);
201221345Sdim    } else {
202221345Sdim      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
203221345Sdim      if (TTP->isParameterPack())
204249423Sdim        Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
205221345Sdim      else
206221345Sdim        Arg = TemplateArgument(TemplateName(TTP));
207221345Sdim    }
208221345Sdim
209221345Sdim    if ((*Param)->isTemplateParameterPack())
210221345Sdim      Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
211221345Sdim
212221345Sdim    *Args++ = Arg;
213221345Sdim  }
214221345Sdim}
215221345Sdim
216193326Sed//===----------------------------------------------------------------------===//
217193326Sed// FunctionTemplateDecl Implementation
218193326Sed//===----------------------------------------------------------------------===//
219193326Sed
220208600Srdivackyvoid FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
221208600Srdivacky  static_cast<Common *>(Ptr)->~Common();
222208600Srdivacky}
223208600Srdivacky
224193326SedFunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
225193326Sed                                                   DeclContext *DC,
226193326Sed                                                   SourceLocation L,
227193326Sed                                                   DeclarationName Name,
228195341Sed                                               TemplateParameterList *Params,
229193326Sed                                                   NamedDecl *Decl) {
230221345Sdim  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
231193326Sed  return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
232193326Sed}
233193326Sed
234234353SdimFunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
235234353Sdim                                                               unsigned ID) {
236234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl));
237234353Sdim  return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
238234353Sdim                                        0, 0);
239221345Sdim}
240221345Sdim
241218893SdimRedeclarableTemplateDecl::CommonBase *
242249423SdimFunctionTemplateDecl::newCommon(ASTContext &C) const {
243218893Sdim  Common *CommonPtr = new (C) Common;
244218893Sdim  C.AddDeallocation(DeallocateCommon, CommonPtr);
245212904Sdim  return CommonPtr;
246195341Sed}
247195341Sed
248212904SdimFunctionDecl *
249212904SdimFunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
250212904Sdim                                         unsigned NumArgs, void *&InsertPos) {
251212904Sdim  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
252198092Srdivacky}
253198092Srdivacky
254221345Sdimvoid FunctionTemplateDecl::addSpecialization(
255221345Sdim      FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
256234353Sdim  if (InsertPos)
257234353Sdim    getSpecializations().InsertNode(Info, InsertPos);
258234353Sdim  else
259234353Sdim    getSpecializations().GetOrInsertNode(Info);
260221345Sdim  if (ASTMutationListener *L = getASTMutationListener())
261221345Sdim    L->AddedCXXTemplateSpecialization(this, Info->Function);
262221345Sdim}
263221345Sdim
264221345Sdimstd::pair<const TemplateArgument *, unsigned>
265221345SdimFunctionTemplateDecl::getInjectedTemplateArgs() {
266221345Sdim  TemplateParameterList *Params = getTemplateParameters();
267221345Sdim  Common *CommonPtr = getCommonPtr();
268221345Sdim  if (!CommonPtr->InjectedArgs) {
269221345Sdim    CommonPtr->InjectedArgs
270221345Sdim      = new (getASTContext()) TemplateArgument [Params->size()];
271221345Sdim    GenerateInjectedTemplateArgs(getASTContext(), Params,
272221345Sdim                                 CommonPtr->InjectedArgs);
273221345Sdim  }
274221345Sdim
275221345Sdim  return std::make_pair(CommonPtr->InjectedArgs, Params->size());
276221345Sdim}
277221345Sdim
278193326Sed//===----------------------------------------------------------------------===//
279193326Sed// ClassTemplateDecl Implementation
280193326Sed//===----------------------------------------------------------------------===//
281193326Sed
282208600Srdivackyvoid ClassTemplateDecl::DeallocateCommon(void *Ptr) {
283208600Srdivacky  static_cast<Common *>(Ptr)->~Common();
284208600Srdivacky}
285208600Srdivacky
286193326SedClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
287193326Sed                                             DeclContext *DC,
288193326Sed                                             SourceLocation L,
289193326Sed                                             DeclarationName Name,
290193326Sed                                             TemplateParameterList *Params,
291193326Sed                                             NamedDecl *Decl,
292193326Sed                                             ClassTemplateDecl *PrevDecl) {
293221345Sdim  AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
294210299Sed  ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
295210299Sed  New->setPreviousDeclaration(PrevDecl);
296210299Sed  return New;
297193326Sed}
298193326Sed
299234353SdimClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
300234353Sdim                                                         unsigned ID) {
301234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
302234353Sdim  return new (Mem) ClassTemplateDecl(EmptyShell());
303221345Sdim}
304221345Sdim
305249423Sdimvoid ClassTemplateDecl::LoadLazySpecializations() const {
306218893Sdim  Common *CommonPtr = getCommonPtr();
307218893Sdim  if (CommonPtr->LazySpecializations) {
308218893Sdim    ASTContext &Context = getASTContext();
309218893Sdim    uint32_t *Specs = CommonPtr->LazySpecializations;
310218893Sdim    CommonPtr->LazySpecializations = 0;
311218893Sdim    for (uint32_t I = 0, N = *Specs++; I != N; ++I)
312218893Sdim      (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
313218893Sdim  }
314218893Sdim}
315218893Sdim
316239462Sdimllvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
317249423SdimClassTemplateDecl::getSpecializations() const {
318218893Sdim  LoadLazySpecializations();
319218893Sdim  return getCommonPtr()->Specializations;
320218893Sdim}
321218893Sdim
322239462Sdimllvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
323218893SdimClassTemplateDecl::getPartialSpecializations() {
324218893Sdim  LoadLazySpecializations();
325218893Sdim  return getCommonPtr()->PartialSpecializations;
326218893Sdim}
327218893Sdim
328218893SdimRedeclarableTemplateDecl::CommonBase *
329249423SdimClassTemplateDecl::newCommon(ASTContext &C) const {
330218893Sdim  Common *CommonPtr = new (C) Common;
331218893Sdim  C.AddDeallocation(DeallocateCommon, CommonPtr);
332212904Sdim  return CommonPtr;
333193326Sed}
334193326Sed
335212904SdimClassTemplateSpecializationDecl *
336212904SdimClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
337212904Sdim                                      unsigned NumArgs, void *&InsertPos) {
338212904Sdim  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
339212904Sdim}
340212904Sdim
341218893Sdimvoid ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
342218893Sdim                                          void *InsertPos) {
343234353Sdim  if (InsertPos)
344234353Sdim    getSpecializations().InsertNode(D, InsertPos);
345234353Sdim  else {
346234353Sdim    ClassTemplateSpecializationDecl *Existing
347234353Sdim      = getSpecializations().GetOrInsertNode(D);
348234353Sdim    (void)Existing;
349234353Sdim    assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
350234353Sdim  }
351218893Sdim  if (ASTMutationListener *L = getASTMutationListener())
352218893Sdim    L->AddedCXXTemplateSpecialization(this, D);
353218893Sdim}
354218893Sdim
355212904SdimClassTemplatePartialSpecializationDecl *
356212904SdimClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
357212904Sdim                                             unsigned NumArgs,
358212904Sdim                                             void *&InsertPos) {
359212904Sdim  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
360212904Sdim                                InsertPos);
361212904Sdim}
362212904Sdim
363218893Sdimvoid ClassTemplateDecl::AddPartialSpecialization(
364218893Sdim                                      ClassTemplatePartialSpecializationDecl *D,
365218893Sdim                                      void *InsertPos) {
366234353Sdim  if (InsertPos)
367234353Sdim    getPartialSpecializations().InsertNode(D, InsertPos);
368234353Sdim  else {
369234353Sdim    ClassTemplatePartialSpecializationDecl *Existing
370234353Sdim      = getPartialSpecializations().GetOrInsertNode(D);
371234353Sdim    (void)Existing;
372234353Sdim    assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
373234353Sdim  }
374234353Sdim
375218893Sdim  if (ASTMutationListener *L = getASTMutationListener())
376218893Sdim    L->AddedCXXTemplateSpecialization(this, D);
377218893Sdim}
378218893Sdim
379207619Srdivackyvoid ClassTemplateDecl::getPartialSpecializations(
380226633Sdim          SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
381239462Sdim  llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
382210299Sed    = getPartialSpecializations();
383207619Srdivacky  PS.clear();
384207619Srdivacky  PS.resize(PartialSpecs.size());
385239462Sdim  for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
386207619Srdivacky       P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
387207619Srdivacky       P != PEnd; ++P) {
388207619Srdivacky    assert(!PS[P->getSequenceNumber()]);
389234353Sdim    PS[P->getSequenceNumber()] = P->getMostRecentDecl();
390207619Srdivacky  }
391207619Srdivacky}
392207619Srdivacky
393198092SrdivackyClassTemplatePartialSpecializationDecl *
394198092SrdivackyClassTemplateDecl::findPartialSpecialization(QualType T) {
395198092Srdivacky  ASTContext &Context = getASTContext();
396239462Sdim  using llvm::FoldingSetVector;
397239462Sdim  typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
398198092Srdivacky    partial_spec_iterator;
399198092Srdivacky  for (partial_spec_iterator P = getPartialSpecializations().begin(),
400198092Srdivacky                          PEnd = getPartialSpecializations().end();
401198092Srdivacky       P != PEnd; ++P) {
402207619Srdivacky    if (Context.hasSameType(P->getInjectedSpecializationType(), T))
403234353Sdim      return P->getMostRecentDecl();
404198092Srdivacky  }
405198092Srdivacky
406198092Srdivacky  return 0;
407198092Srdivacky}
408198092Srdivacky
409212904SdimClassTemplatePartialSpecializationDecl *
410212904SdimClassTemplateDecl::findPartialSpecInstantiatedFromMember(
411212904Sdim                                    ClassTemplatePartialSpecializationDecl *D) {
412212904Sdim  Decl *DCanon = D->getCanonicalDecl();
413239462Sdim  for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
414212904Sdim            P = getPartialSpecializations().begin(),
415212904Sdim         PEnd = getPartialSpecializations().end();
416212904Sdim       P != PEnd; ++P) {
417212904Sdim    if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
418234353Sdim      return P->getMostRecentDecl();
419212904Sdim  }
420212904Sdim
421212904Sdim  return 0;
422212904Sdim}
423212904Sdim
424204962SrdivackyQualType
425210299SedClassTemplateDecl::getInjectedClassNameSpecialization() {
426210299Sed  Common *CommonPtr = getCommonPtr();
427193326Sed  if (!CommonPtr->InjectedClassNameType.isNull())
428193326Sed    return CommonPtr->InjectedClassNameType;
429193326Sed
430218893Sdim  // C++0x [temp.dep.type]p2:
431218893Sdim  //  The template argument list of a primary template is a template argument
432218893Sdim  //  list in which the nth template argument has the value of the nth template
433218893Sdim  //  parameter of the class template. If the nth template parameter is a
434218893Sdim  //  template parameter pack (14.5.3), the nth template argument is a pack
435218893Sdim  //  expansion (14.5.3) whose pattern is the name of the template parameter
436218893Sdim  //  pack.
437210299Sed  ASTContext &Context = getASTContext();
438193326Sed  TemplateParameterList *Params = getTemplateParameters();
439226633Sdim  SmallVector<TemplateArgument, 16> TemplateArgs;
440221345Sdim  TemplateArgs.resize(Params->size());
441221345Sdim  GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
442193326Sed  CommonPtr->InjectedClassNameType
443198092Srdivacky    = Context.getTemplateSpecializationType(TemplateName(this),
444193326Sed                                            &TemplateArgs[0],
445198092Srdivacky                                            TemplateArgs.size());
446193326Sed  return CommonPtr->InjectedClassNameType;
447193326Sed}
448193326Sed
449193326Sed//===----------------------------------------------------------------------===//
450193326Sed// TemplateTypeParm Allocation/Deallocation Method Implementations
451193326Sed//===----------------------------------------------------------------------===//
452193326Sed
453193326SedTemplateTypeParmDecl *
454218893SdimTemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
455221345Sdim                             SourceLocation KeyLoc, SourceLocation NameLoc,
456221345Sdim                             unsigned D, unsigned P, IdentifierInfo *Id,
457221345Sdim                             bool Typename, bool ParameterPack) {
458221345Sdim  TemplateTypeParmDecl *TTPDecl =
459221345Sdim    new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
460221345Sdim  QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
461221345Sdim  TTPDecl->TypeForDecl = TTPType.getTypePtr();
462221345Sdim  return TTPDecl;
463193326Sed}
464193326Sed
465210299SedTemplateTypeParmDecl *
466234353SdimTemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
467234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
468234353Sdim  return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
469234353Sdim                                        0, false);
470210299Sed}
471210299Sed
472198893SrdivackySourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
473221345Sdim  return hasDefaultArgument()
474221345Sdim    ? DefaultArgument->getTypeLoc().getBeginLoc()
475221345Sdim    : SourceLocation();
476198893Srdivacky}
477198893Srdivacky
478221345SdimSourceRange TemplateTypeParmDecl::getSourceRange() const {
479221345Sdim  if (hasDefaultArgument() && !defaultArgumentWasInherited())
480221345Sdim    return SourceRange(getLocStart(),
481221345Sdim                       DefaultArgument->getTypeLoc().getEndLoc());
482221345Sdim  else
483221345Sdim    return TypeDecl::getSourceRange();
484221345Sdim}
485221345Sdim
486198893Srdivackyunsigned TemplateTypeParmDecl::getDepth() const {
487198893Srdivacky  return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
488198893Srdivacky}
489198893Srdivacky
490198893Srdivackyunsigned TemplateTypeParmDecl::getIndex() const {
491198893Srdivacky  return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
492198893Srdivacky}
493198893Srdivacky
494221345Sdimbool TemplateTypeParmDecl::isParameterPack() const {
495221345Sdim  return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
496221345Sdim}
497221345Sdim
498193326Sed//===----------------------------------------------------------------------===//
499193326Sed// NonTypeTemplateParmDecl Method Implementations
500193326Sed//===----------------------------------------------------------------------===//
501193326Sed
502218893SdimNonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
503221345Sdim                                                 SourceLocation StartLoc,
504221345Sdim                                                 SourceLocation IdLoc,
505221345Sdim                                                 unsigned D, unsigned P,
506221345Sdim                                                 IdentifierInfo *Id,
507218893Sdim                                                 QualType T,
508218893Sdim                                                 TypeSourceInfo *TInfo,
509218893Sdim                                                 const QualType *ExpandedTypes,
510218893Sdim                                                 unsigned NumExpandedTypes,
511218893Sdim                                                TypeSourceInfo **ExpandedTInfos)
512221345Sdim  : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
513218893Sdim    TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
514218893Sdim    ParameterPack(true), ExpandedParameterPack(true),
515218893Sdim    NumExpandedTypes(NumExpandedTypes)
516218893Sdim{
517218893Sdim  if (ExpandedTypes && ExpandedTInfos) {
518218893Sdim    void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
519218893Sdim    for (unsigned I = 0; I != NumExpandedTypes; ++I) {
520218893Sdim      TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
521218893Sdim      TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
522218893Sdim    }
523218893Sdim  }
524218893Sdim}
525218893Sdim
526193326SedNonTypeTemplateParmDecl *
527218893SdimNonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
528221345Sdim                                SourceLocation StartLoc, SourceLocation IdLoc,
529221345Sdim                                unsigned D, unsigned P, IdentifierInfo *Id,
530221345Sdim                                QualType T, bool ParameterPack,
531221345Sdim                                TypeSourceInfo *TInfo) {
532221345Sdim  return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
533221345Sdim                                         T, ParameterPack, TInfo);
534193326Sed}
535193326Sed
536218893SdimNonTypeTemplateParmDecl *
537218893SdimNonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
538221345Sdim                                SourceLocation StartLoc, SourceLocation IdLoc,
539221345Sdim                                unsigned D, unsigned P,
540218893Sdim                                IdentifierInfo *Id, QualType T,
541218893Sdim                                TypeSourceInfo *TInfo,
542218893Sdim                                const QualType *ExpandedTypes,
543218893Sdim                                unsigned NumExpandedTypes,
544218893Sdim                                TypeSourceInfo **ExpandedTInfos) {
545218893Sdim  unsigned Size = sizeof(NonTypeTemplateParmDecl)
546218893Sdim                + NumExpandedTypes * 2 * sizeof(void*);
547218893Sdim  void *Mem = C.Allocate(Size);
548221345Sdim  return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
549221345Sdim                                           D, P, Id, T, TInfo,
550218893Sdim                                           ExpandedTypes, NumExpandedTypes,
551218893Sdim                                           ExpandedTInfos);
552218893Sdim}
553218893Sdim
554234353SdimNonTypeTemplateParmDecl *
555234353SdimNonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
556234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
557234353Sdim  return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
558234353Sdim                                           SourceLocation(), 0, 0, 0,
559234353Sdim                                           QualType(), false, 0);
560234353Sdim}
561234353Sdim
562234353SdimNonTypeTemplateParmDecl *
563234353SdimNonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
564234353Sdim                                            unsigned NumExpandedTypes) {
565234353Sdim  unsigned Size = sizeof(NonTypeTemplateParmDecl)
566234353Sdim                + NumExpandedTypes * 2 * sizeof(void*);
567234353Sdim
568234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID, Size);
569234353Sdim  return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(),
570234353Sdim                                           SourceLocation(), 0, 0, 0,
571234353Sdim                                           QualType(), 0, 0, NumExpandedTypes,
572234353Sdim                                           0);
573234353Sdim}
574234353Sdim
575218893SdimSourceRange NonTypeTemplateParmDecl::getSourceRange() const {
576221345Sdim  if (hasDefaultArgument() && !defaultArgumentWasInherited())
577221345Sdim    return SourceRange(getOuterLocStart(),
578221345Sdim                       getDefaultArgument()->getSourceRange().getEnd());
579221345Sdim  return DeclaratorDecl::getSourceRange();
580218893Sdim}
581218893Sdim
582193326SedSourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
583210299Sed  return hasDefaultArgument()
584210299Sed    ? getDefaultArgument()->getSourceRange().getBegin()
585210299Sed    : SourceLocation();
586193326Sed}
587193326Sed
588193326Sed//===----------------------------------------------------------------------===//
589193326Sed// TemplateTemplateParmDecl Method Implementations
590193326Sed//===----------------------------------------------------------------------===//
591193326Sed
592234353Sdimvoid TemplateTemplateParmDecl::anchor() { }
593234353Sdim
594243830SdimTemplateTemplateParmDecl::TemplateTemplateParmDecl(
595243830Sdim    DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
596243830Sdim    IdentifierInfo *Id, TemplateParameterList *Params,
597243830Sdim    unsigned NumExpansions, TemplateParameterList * const *Expansions)
598243830Sdim  : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
599243830Sdim    TemplateParmPosition(D, P), DefaultArgument(),
600243830Sdim    DefaultArgumentWasInherited(false), ParameterPack(true),
601243830Sdim    ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
602243830Sdim  if (Expansions)
603243830Sdim    std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
604243830Sdim                sizeof(TemplateParameterList*) * NumExpandedParams);
605243830Sdim}
606243830Sdim
607193326SedTemplateTemplateParmDecl *
608218893SdimTemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
609193326Sed                                 SourceLocation L, unsigned D, unsigned P,
610218893Sdim                                 bool ParameterPack, IdentifierInfo *Id,
611193326Sed                                 TemplateParameterList *Params) {
612218893Sdim  return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
613218893Sdim                                          Params);
614193326Sed}
615193326Sed
616234353SdimTemplateTemplateParmDecl *
617243830SdimTemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
618243830Sdim                                 SourceLocation L, unsigned D, unsigned P,
619243830Sdim                                 IdentifierInfo *Id,
620243830Sdim                                 TemplateParameterList *Params,
621249423Sdim                                 ArrayRef<TemplateParameterList *> Expansions) {
622243830Sdim  void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
623243830Sdim                         sizeof(TemplateParameterList*) * Expansions.size());
624243830Sdim  return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
625243830Sdim                                            Expansions.size(),
626243830Sdim                                            Expansions.data());
627243830Sdim}
628243830Sdim
629243830SdimTemplateTemplateParmDecl *
630234353SdimTemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
631234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
632234353Sdim  return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
633234353Sdim                                            0, 0);
634234353Sdim}
635234353Sdim
636243830SdimTemplateTemplateParmDecl *
637243830SdimTemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
638243830Sdim                                             unsigned NumExpansions) {
639243830Sdim  unsigned Size = sizeof(TemplateTemplateParmDecl) +
640243830Sdim                  sizeof(TemplateParameterList*) * NumExpansions;
641243830Sdim  void *Mem = AllocateDeserializedDecl(C, ID, Size);
642243830Sdim  return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
643243830Sdim                                            NumExpansions, 0);
644243830Sdim}
645243830Sdim
646193326Sed//===----------------------------------------------------------------------===//
647193326Sed// TemplateArgumentList Implementation
648193326Sed//===----------------------------------------------------------------------===//
649218893SdimTemplateArgumentList *
650218893SdimTemplateArgumentList::CreateCopy(ASTContext &Context,
651218893Sdim                                 const TemplateArgument *Args,
652218893Sdim                                 unsigned NumArgs) {
653218893Sdim  std::size_t Size = sizeof(TemplateArgumentList)
654218893Sdim                   + NumArgs * sizeof(TemplateArgument);
655218893Sdim  void *Mem = Context.Allocate(Size);
656218893Sdim  TemplateArgument *StoredArgs
657218893Sdim    = reinterpret_cast<TemplateArgument *>(
658218893Sdim                                static_cast<TemplateArgumentList *>(Mem) + 1);
659218893Sdim  std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
660218893Sdim  return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
661193326Sed}
662193326Sed
663226633SdimFunctionTemplateSpecializationInfo *
664226633SdimFunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
665226633Sdim                                           FunctionTemplateDecl *Template,
666226633Sdim                                           TemplateSpecializationKind TSK,
667226633Sdim                                       const TemplateArgumentList *TemplateArgs,
668226633Sdim                          const TemplateArgumentListInfo *TemplateArgsAsWritten,
669226633Sdim                                           SourceLocation POI) {
670226633Sdim  const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
671226633Sdim  if (TemplateArgsAsWritten)
672226633Sdim    ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
673226633Sdim                                                        *TemplateArgsAsWritten);
674226633Sdim
675226633Sdim  return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
676226633Sdim                                                    TemplateArgs,
677226633Sdim                                                    ArgsAsWritten,
678226633Sdim                                                    POI);
679226633Sdim}
680226633Sdim
681193326Sed//===----------------------------------------------------------------------===//
682234353Sdim// TemplateDecl Implementation
683234353Sdim//===----------------------------------------------------------------------===//
684234353Sdim
685234353Sdimvoid TemplateDecl::anchor() { }
686234353Sdim
687234353Sdim//===----------------------------------------------------------------------===//
688193326Sed// ClassTemplateSpecializationDecl Implementation
689193326Sed//===----------------------------------------------------------------------===//
690193326SedClassTemplateSpecializationDecl::
691208600SrdivackyClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
692221345Sdim                                DeclContext *DC, SourceLocation StartLoc,
693221345Sdim                                SourceLocation IdLoc,
694193326Sed                                ClassTemplateDecl *SpecializedTemplate,
695218893Sdim                                const TemplateArgument *Args,
696218893Sdim                                unsigned NumArgs,
697198092Srdivacky                                ClassTemplateSpecializationDecl *PrevDecl)
698221345Sdim  : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
699198092Srdivacky                  SpecializedTemplate->getIdentifier(),
700198092Srdivacky                  PrevDecl),
701193326Sed    SpecializedTemplate(SpecializedTemplate),
702210299Sed    ExplicitInfo(0),
703218893Sdim    TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
704193326Sed    SpecializationKind(TSK_Undeclared) {
705193326Sed}
706198092Srdivacky
707210299SedClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
708221345Sdim  : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
709210299Sed    ExplicitInfo(0),
710210299Sed    SpecializationKind(TSK_Undeclared) {
711210299Sed}
712210299Sed
713193326SedClassTemplateSpecializationDecl *
714208600SrdivackyClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
715221345Sdim                                        DeclContext *DC,
716221345Sdim                                        SourceLocation StartLoc,
717221345Sdim                                        SourceLocation IdLoc,
718193326Sed                                        ClassTemplateDecl *SpecializedTemplate,
719218893Sdim                                        const TemplateArgument *Args,
720218893Sdim                                        unsigned NumArgs,
721193326Sed                                   ClassTemplateSpecializationDecl *PrevDecl) {
722193326Sed  ClassTemplateSpecializationDecl *Result
723198092Srdivacky    = new (Context)ClassTemplateSpecializationDecl(Context,
724193326Sed                                                   ClassTemplateSpecialization,
725221345Sdim                                                   TK, DC, StartLoc, IdLoc,
726193326Sed                                                   SpecializedTemplate,
727218893Sdim                                                   Args, NumArgs,
728198092Srdivacky                                                   PrevDecl);
729249423Sdim  Result->MayHaveOutOfDateDef = false;
730249423Sdim
731193326Sed  Context.getTypeDeclType(Result, PrevDecl);
732193326Sed  return Result;
733193326Sed}
734193326Sed
735210299SedClassTemplateSpecializationDecl *
736234353SdimClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
737234353Sdim                                                    unsigned ID) {
738234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID,
739234353Sdim                                       sizeof(ClassTemplateSpecializationDecl));
740249423Sdim  ClassTemplateSpecializationDecl *Result =
741249423Sdim    new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
742249423Sdim  Result->MayHaveOutOfDateDef = false;
743249423Sdim  return Result;
744210299Sed}
745210299Sed
746249423Sdimvoid ClassTemplateSpecializationDecl::getNameForDiagnostic(
747249423Sdim    raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
748249423Sdim  NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
749198092Srdivacky
750198092Srdivacky  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
751249423Sdim  TemplateSpecializationType::PrintTemplateArgumentList(
752249423Sdim      OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
753198092Srdivacky}
754198092Srdivacky
755198092SrdivackyClassTemplateDecl *
756198092SrdivackyClassTemplateSpecializationDecl::getSpecializedTemplate() const {
757198092Srdivacky  if (SpecializedPartialSpecialization *PartialSpec
758198092Srdivacky      = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
759198092Srdivacky    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
760198092Srdivacky  return SpecializedTemplate.get<ClassTemplateDecl*>();
761198092Srdivacky}
762198092Srdivacky
763221345SdimSourceRange
764221345SdimClassTemplateSpecializationDecl::getSourceRange() const {
765226633Sdim  if (ExplicitInfo) {
766243830Sdim    SourceLocation Begin = getTemplateKeywordLoc();
767243830Sdim    if (Begin.isValid()) {
768243830Sdim      // Here we have an explicit (partial) specialization or instantiation.
769243830Sdim      assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
770243830Sdim             getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
771243830Sdim             getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
772243830Sdim      if (getExternLoc().isValid())
773243830Sdim        Begin = getExternLoc();
774243830Sdim      SourceLocation End = getRBraceLoc();
775243830Sdim      if (End.isInvalid())
776243830Sdim        End = getTypeAsWritten()->getTypeLoc().getEndLoc();
777243830Sdim      return SourceRange(Begin, End);
778243830Sdim    }
779243830Sdim    // An implicit instantiation of a class template partial specialization
780243830Sdim    // uses ExplicitInfo to record the TypeAsWritten, but the source
781243830Sdim    // locations should be retrieved from the instantiation pattern.
782243830Sdim    typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
783243830Sdim    CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
784243830Sdim    CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
785243830Sdim    assert(inst_from != 0);
786243830Sdim    return inst_from->getSourceRange();
787226633Sdim  }
788226633Sdim  else {
789226633Sdim    // No explicit info available.
790226633Sdim    llvm::PointerUnion<ClassTemplateDecl *,
791226633Sdim                       ClassTemplatePartialSpecializationDecl *>
792226633Sdim      inst_from = getInstantiatedFrom();
793226633Sdim    if (inst_from.isNull())
794226633Sdim      return getSpecializedTemplate()->getSourceRange();
795226633Sdim    if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
796226633Sdim      return ctd->getSourceRange();
797226633Sdim    return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
798226633Sdim      ->getSourceRange();
799226633Sdim  }
800221345Sdim}
801221345Sdim
802193326Sed//===----------------------------------------------------------------------===//
803193326Sed// ClassTemplatePartialSpecializationDecl Implementation
804193326Sed//===----------------------------------------------------------------------===//
805234353Sdimvoid ClassTemplatePartialSpecializationDecl::anchor() { }
806234353Sdim
807221345SdimClassTemplatePartialSpecializationDecl::
808221345SdimClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
809221345Sdim                                       DeclContext *DC,
810221345Sdim                                       SourceLocation StartLoc,
811221345Sdim                                       SourceLocation IdLoc,
812221345Sdim                                       TemplateParameterList *Params,
813221345Sdim                                       ClassTemplateDecl *SpecializedTemplate,
814221345Sdim                                       const TemplateArgument *Args,
815221345Sdim                                       unsigned NumArgs,
816221345Sdim                                       TemplateArgumentLoc *ArgInfos,
817221345Sdim                                       unsigned NumArgInfos,
818221345Sdim                               ClassTemplatePartialSpecializationDecl *PrevDecl,
819221345Sdim                                       unsigned SequenceNumber)
820221345Sdim  : ClassTemplateSpecializationDecl(Context,
821221345Sdim                                    ClassTemplatePartialSpecialization,
822221345Sdim                                    TK, DC, StartLoc, IdLoc,
823221345Sdim                                    SpecializedTemplate,
824221345Sdim                                    Args, NumArgs, PrevDecl),
825221345Sdim    TemplateParams(Params), ArgsAsWritten(ArgInfos),
826221345Sdim    NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
827221345Sdim    InstantiatedFromMember(0, false)
828221345Sdim{
829221345Sdim  AdoptTemplateParameterList(Params, this);
830221345Sdim}
831221345Sdim
832193326SedClassTemplatePartialSpecializationDecl *
833193326SedClassTemplatePartialSpecializationDecl::
834221345SdimCreate(ASTContext &Context, TagKind TK,DeclContext *DC,
835221345Sdim       SourceLocation StartLoc, SourceLocation IdLoc,
836193326Sed       TemplateParameterList *Params,
837193326Sed       ClassTemplateDecl *SpecializedTemplate,
838218893Sdim       const TemplateArgument *Args,
839218893Sdim       unsigned NumArgs,
840199990Srdivacky       const TemplateArgumentListInfo &ArgInfos,
841204962Srdivacky       QualType CanonInjectedType,
842207619Srdivacky       ClassTemplatePartialSpecializationDecl *PrevDecl,
843207619Srdivacky       unsigned SequenceNumber) {
844199990Srdivacky  unsigned N = ArgInfos.size();
845198893Srdivacky  TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
846198893Srdivacky  for (unsigned I = 0; I != N; ++I)
847198893Srdivacky    ClonedArgs[I] = ArgInfos[I];
848198893Srdivacky
849193326Sed  ClassTemplatePartialSpecializationDecl *Result
850221345Sdim    = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
851221345Sdim                                                          StartLoc, IdLoc,
852221345Sdim                                                          Params,
853193326Sed                                                          SpecializedTemplate,
854218893Sdim                                                          Args, NumArgs,
855198893Srdivacky                                                          ClonedArgs, N,
856207619Srdivacky                                                          PrevDecl,
857207619Srdivacky                                                          SequenceNumber);
858193326Sed  Result->setSpecializationKind(TSK_ExplicitSpecialization);
859249423Sdim  Result->MayHaveOutOfDateDef = false;
860204962Srdivacky
861204962Srdivacky  Context.getInjectedClassNameType(Result, CanonInjectedType);
862193326Sed  return Result;
863193326Sed}
864198092Srdivacky
865210299SedClassTemplatePartialSpecializationDecl *
866234353SdimClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
867234353Sdim                                                           unsigned ID) {
868234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID,
869234353Sdim                sizeof(ClassTemplatePartialSpecializationDecl));
870249423Sdim  ClassTemplatePartialSpecializationDecl *Result
871249423Sdim    = new (Mem) ClassTemplatePartialSpecializationDecl();
872249423Sdim  Result->MayHaveOutOfDateDef = false;
873249423Sdim  return Result;
874210299Sed}
875210299Sed
876198092Srdivacky//===----------------------------------------------------------------------===//
877198092Srdivacky// FriendTemplateDecl Implementation
878198092Srdivacky//===----------------------------------------------------------------------===//
879198092Srdivacky
880234353Sdimvoid FriendTemplateDecl::anchor() { }
881234353Sdim
882198092SrdivackyFriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
883198092Srdivacky                                               DeclContext *DC,
884198092Srdivacky                                               SourceLocation L,
885198092Srdivacky                                               unsigned NParams,
886198092Srdivacky                                               TemplateParameterList **Params,
887198092Srdivacky                                               FriendUnion Friend,
888198092Srdivacky                                               SourceLocation FLoc) {
889198092Srdivacky  FriendTemplateDecl *Result
890198092Srdivacky    = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
891198092Srdivacky  return Result;
892198092Srdivacky}
893212904Sdim
894234353SdimFriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
895234353Sdim                                                           unsigned ID) {
896234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
897234353Sdim  return new (Mem) FriendTemplateDecl(EmptyShell());
898212904Sdim}
899223017Sdim
900223017Sdim//===----------------------------------------------------------------------===//
901223017Sdim// TypeAliasTemplateDecl Implementation
902223017Sdim//===----------------------------------------------------------------------===//
903223017Sdim
904223017SdimTypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
905223017Sdim                                                     DeclContext *DC,
906223017Sdim                                                     SourceLocation L,
907223017Sdim                                                     DeclarationName Name,
908223017Sdim                                                  TemplateParameterList *Params,
909223017Sdim                                                     NamedDecl *Decl) {
910223017Sdim  AdoptTemplateParameterList(Params, DC);
911223017Sdim  return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
912223017Sdim}
913223017Sdim
914234353SdimTypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
915234353Sdim                                                                 unsigned ID) {
916234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
917234353Sdim  return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
918234353Sdim                                         0, 0);
919223017Sdim}
920223017Sdim
921223017Sdimvoid TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
922223017Sdim  static_cast<Common *>(Ptr)->~Common();
923223017Sdim}
924223017SdimRedeclarableTemplateDecl::CommonBase *
925249423SdimTypeAliasTemplateDecl::newCommon(ASTContext &C) const {
926223017Sdim  Common *CommonPtr = new (C) Common;
927223017Sdim  C.AddDeallocation(DeallocateCommon, CommonPtr);
928223017Sdim  return CommonPtr;
929223017Sdim}
930223017Sdim
931234353Sdim//===----------------------------------------------------------------------===//
932234353Sdim// ClassScopeFunctionSpecializationDecl Implementation
933234353Sdim//===----------------------------------------------------------------------===//
934234353Sdim
935234353Sdimvoid ClassScopeFunctionSpecializationDecl::anchor() { }
936234353Sdim
937234353SdimClassScopeFunctionSpecializationDecl *
938234353SdimClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
939234353Sdim                                                         unsigned ID) {
940234353Sdim  void *Mem = AllocateDeserializedDecl(C, ID,
941234353Sdim                sizeof(ClassScopeFunctionSpecializationDecl));
942239462Sdim  return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
943239462Sdim                                             false, TemplateArgumentListInfo());
944234353Sdim}
945