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