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