]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/AST/DeclTemplate.cpp
Update clang to r89205.
[FreeBSD/FreeBSD.git] / 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/DeclCXX.h"
15 #include "clang/AST/DeclTemplate.h"
16 #include "clang/AST/Expr.h"
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/TypeLoc.h"
19 #include "clang/Basic/IdentifierTable.h"
20 #include "llvm/ADT/STLExtras.h"
21 using namespace clang;
22
23 //===----------------------------------------------------------------------===//
24 // TemplateParameterList Implementation
25 //===----------------------------------------------------------------------===//
26
27 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
28                                              SourceLocation LAngleLoc,
29                                              NamedDecl **Params, unsigned NumParams,
30                                              SourceLocation RAngleLoc)
31   : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
32     NumParams(NumParams) {
33   for (unsigned Idx = 0; Idx < NumParams; ++Idx)
34     begin()[Idx] = Params[Idx];
35 }
36
37 TemplateParameterList *
38 TemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc,
39                               SourceLocation LAngleLoc, NamedDecl **Params,
40                               unsigned NumParams, SourceLocation RAngleLoc) {
41   unsigned Size = sizeof(TemplateParameterList) 
42                 + sizeof(NamedDecl *) * NumParams;
43   unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
44   void *Mem = C.Allocate(Size, Align);
45   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
46                                          NumParams, RAngleLoc);
47 }
48
49 unsigned TemplateParameterList::getMinRequiredArguments() const {
50   unsigned NumRequiredArgs = size();
51   iterator Param = const_cast<TemplateParameterList *>(this)->end(),
52       ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
53   while (Param != ParamBegin) {
54     --Param;
55
56     if (!(*Param)->isTemplateParameterPack() &&
57         !(isa<TemplateTypeParmDecl>(*Param) &&
58           cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
59         !(isa<NonTypeTemplateParmDecl>(*Param) &&
60           cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&
61         !(isa<TemplateTemplateParmDecl>(*Param) &&
62           cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument()))
63       break;
64
65     --NumRequiredArgs;
66   }
67
68   return NumRequiredArgs;
69 }
70
71 unsigned TemplateParameterList::getDepth() const {
72   if (size() == 0)
73     return 0;
74   
75   const NamedDecl *FirstParm = getParam(0);
76   if (const TemplateTypeParmDecl *TTP
77         = dyn_cast<TemplateTypeParmDecl>(FirstParm))
78     return TTP->getDepth();
79   else if (const NonTypeTemplateParmDecl *NTTP 
80              = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
81     return NTTP->getDepth();
82   else
83     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
84 }
85
86 //===----------------------------------------------------------------------===//
87 // TemplateDecl Implementation
88 //===----------------------------------------------------------------------===//
89
90 TemplateDecl::~TemplateDecl() {
91 }
92
93 //===----------------------------------------------------------------------===//
94 // FunctionTemplateDecl Implementation
95 //===----------------------------------------------------------------------===//
96
97 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
98                                                    DeclContext *DC,
99                                                    SourceLocation L,
100                                                    DeclarationName Name,
101                                                TemplateParameterList *Params,
102                                                    NamedDecl *Decl) {
103   return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
104 }
105
106 void FunctionTemplateDecl::Destroy(ASTContext &C) {
107   if (Common *CommonPtr = CommonOrPrev.dyn_cast<Common*>()) {
108     for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
109               Spec = CommonPtr->Specializations.begin(),
110            SpecEnd = CommonPtr->Specializations.end();
111          Spec != SpecEnd; ++Spec)
112       C.Deallocate(&*Spec);
113   }
114
115   Decl::Destroy(C);
116 }
117
118 FunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() {
119   FunctionTemplateDecl *FunTmpl = this;
120   while (FunTmpl->getPreviousDeclaration())
121     FunTmpl = FunTmpl->getPreviousDeclaration();
122   return FunTmpl;
123 }
124
125 FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
126   // Find the first declaration of this function template.
127   FunctionTemplateDecl *First = this;
128   while (First->getPreviousDeclaration())
129     First = First->getPreviousDeclaration();
130
131   if (First->CommonOrPrev.isNull()) {
132     // FIXME: Allocate with the ASTContext
133     First->CommonOrPrev = new Common;
134   }
135   return First->CommonOrPrev.get<Common*>();
136 }
137
138 //===----------------------------------------------------------------------===//
139 // ClassTemplateDecl Implementation
140 //===----------------------------------------------------------------------===//
141
142 ClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
143   ClassTemplateDecl *Template = this;
144   while (Template->getPreviousDeclaration())
145     Template = Template->getPreviousDeclaration();
146   return Template;
147 }
148
149 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
150                                              DeclContext *DC,
151                                              SourceLocation L,
152                                              DeclarationName Name,
153                                              TemplateParameterList *Params,
154                                              NamedDecl *Decl,
155                                              ClassTemplateDecl *PrevDecl) {
156   Common *CommonPtr;
157   if (PrevDecl)
158     CommonPtr = PrevDecl->CommonPtr;
159   else
160     CommonPtr = new (C) Common;
161
162   return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
163                                    CommonPtr);
164 }
165
166 ClassTemplateDecl::~ClassTemplateDecl() {
167   assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed");
168 }
169
170 void ClassTemplateDecl::Destroy(ASTContext& C) {
171   if (!PreviousDeclaration) {
172     CommonPtr->~Common();
173     C.Deallocate((void*)CommonPtr);
174   }
175   CommonPtr = 0;
176
177   this->~ClassTemplateDecl();
178   C.Deallocate((void*)this);
179 }
180
181 ClassTemplatePartialSpecializationDecl *
182 ClassTemplateDecl::findPartialSpecialization(QualType T) {
183   ASTContext &Context = getASTContext();
184   typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
185     partial_spec_iterator;
186   for (partial_spec_iterator P = getPartialSpecializations().begin(),
187                           PEnd = getPartialSpecializations().end();
188        P != PEnd; ++P) {
189     if (Context.hasSameType(Context.getTypeDeclType(&*P), T))
190       return &*P;
191   }
192
193   return 0;
194 }
195
196 QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
197   if (!CommonPtr->InjectedClassNameType.isNull())
198     return CommonPtr->InjectedClassNameType;
199
200   // FIXME: n2800 14.6.1p1 should say how the template arguments
201   // corresponding to template parameter packs should be pack
202   // expansions. We already say that in 14.6.2.1p2, so it would be
203   // better to fix that redundancy.
204
205   TemplateParameterList *Params = getTemplateParameters();
206   llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
207   TemplateArgs.reserve(Params->size());
208   for (TemplateParameterList::iterator Param = Params->begin(),
209                                     ParamEnd = Params->end();
210        Param != ParamEnd; ++Param) {
211     if (isa<TemplateTypeParmDecl>(*Param)) {
212       QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
213       TemplateArgs.push_back(TemplateArgument(ParamType));
214     } else if (NonTypeTemplateParmDecl *NTTP =
215                  dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
216       Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
217                                           NTTP->getLocation(),
218                                           NTTP->getType()->isDependentType(),
219                                           /*Value-dependent=*/true);
220       TemplateArgs.push_back(TemplateArgument(E));
221     } else {
222       TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
223       TemplateArgs.push_back(TemplateArgument(TemplateName(TTP)));
224     }
225   }
226
227   CommonPtr->InjectedClassNameType
228     = Context.getTemplateSpecializationType(TemplateName(this),
229                                             &TemplateArgs[0],
230                                             TemplateArgs.size());
231   return CommonPtr->InjectedClassNameType;
232 }
233
234 //===----------------------------------------------------------------------===//
235 // TemplateTypeParm Allocation/Deallocation Method Implementations
236 //===----------------------------------------------------------------------===//
237
238 TemplateTypeParmDecl *
239 TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
240                              SourceLocation L, unsigned D, unsigned P,
241                              IdentifierInfo *Id, bool Typename,
242                              bool ParameterPack) {
243   QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id);
244   return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
245 }
246
247 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
248   return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin();
249 }
250
251 unsigned TemplateTypeParmDecl::getDepth() const {
252   return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
253 }
254
255 unsigned TemplateTypeParmDecl::getIndex() const {
256   return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
257 }
258
259 //===----------------------------------------------------------------------===//
260 // NonTypeTemplateParmDecl Method Implementations
261 //===----------------------------------------------------------------------===//
262
263 NonTypeTemplateParmDecl *
264 NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
265                                 SourceLocation L, unsigned D, unsigned P,
266                                 IdentifierInfo *Id, QualType T,
267                                 DeclaratorInfo *DInfo) {
268   return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, DInfo);
269 }
270
271 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
272   return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
273                         : SourceLocation();
274 }
275
276 //===----------------------------------------------------------------------===//
277 // TemplateTemplateParmDecl Method Implementations
278 //===----------------------------------------------------------------------===//
279
280 TemplateTemplateParmDecl *
281 TemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
282                                  SourceLocation L, unsigned D, unsigned P,
283                                  IdentifierInfo *Id,
284                                  TemplateParameterList *Params) {
285   return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
286 }
287
288 //===----------------------------------------------------------------------===//
289 // TemplateArgumentListBuilder Implementation
290 //===----------------------------------------------------------------------===//
291
292 void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
293   switch (Arg.getKind()) {
294     default: break;
295     case TemplateArgument::Type:
296       assert(Arg.getAsType().isCanonical() && "Type must be canonical!");
297       break;
298   }
299
300   assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
301   assert(!StructuredArgs &&
302          "Can't append arguments when an argument pack has been added!");
303
304   if (!FlatArgs)
305     FlatArgs = new TemplateArgument[MaxFlatArgs];
306
307   FlatArgs[NumFlatArgs++] = Arg;
308 }
309
310 void TemplateArgumentListBuilder::BeginPack() {
311   assert(!AddingToPack && "Already adding to pack!");
312   assert(!StructuredArgs && "Argument list already contains a pack!");
313
314   AddingToPack = true;
315   PackBeginIndex = NumFlatArgs;
316 }
317
318 void TemplateArgumentListBuilder::EndPack() {
319   assert(AddingToPack && "Not adding to pack!");
320   assert(!StructuredArgs && "Argument list already contains a pack!");
321
322   AddingToPack = false;
323
324   StructuredArgs = new TemplateArgument[MaxStructuredArgs];
325
326   // First copy the flat entries over to the list  (if any)
327   for (unsigned I = 0; I != PackBeginIndex; ++I) {
328     NumStructuredArgs++;
329     StructuredArgs[I] = FlatArgs[I];
330   }
331
332   // Next, set the pack.
333   TemplateArgument *PackArgs = 0;
334   unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
335   if (NumPackArgs)
336     PackArgs = &FlatArgs[PackBeginIndex];
337
338   StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
339                                                       /*CopyArgs=*/false);
340 }
341
342 void TemplateArgumentListBuilder::ReleaseArgs() {
343   FlatArgs = 0;
344   NumFlatArgs = 0;
345   MaxFlatArgs = 0;
346   StructuredArgs = 0;
347   NumStructuredArgs = 0;
348   MaxStructuredArgs = 0;
349 }
350
351 //===----------------------------------------------------------------------===//
352 // TemplateArgumentList Implementation
353 //===----------------------------------------------------------------------===//
354 TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
355                                            TemplateArgumentListBuilder &Builder,
356                                            bool TakeArgs)
357   : FlatArguments(Builder.getFlatArguments(), TakeArgs),
358     NumFlatArguments(Builder.flatSize()),
359     StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
360     NumStructuredArguments(Builder.structuredSize()) {
361
362   if (!TakeArgs)
363     return;
364
365   if (Builder.getStructuredArguments() == Builder.getFlatArguments())
366     StructuredArguments.setInt(0);
367   Builder.ReleaseArgs();
368 }
369
370 TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other)
371   : FlatArguments(Other.FlatArguments.getPointer(), 1),
372     NumFlatArguments(Other.flat_size()),
373     StructuredArguments(Other.StructuredArguments.getPointer(), 1),
374     NumStructuredArguments(Other.NumStructuredArguments) { }
375
376 TemplateArgumentList::~TemplateArgumentList() {
377   // FIXME: Deallocate template arguments
378 }
379
380 //===----------------------------------------------------------------------===//
381 // ClassTemplateSpecializationDecl Implementation
382 //===----------------------------------------------------------------------===//
383 ClassTemplateSpecializationDecl::
384 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
385                                 DeclContext *DC, SourceLocation L,
386                                 ClassTemplateDecl *SpecializedTemplate,
387                                 TemplateArgumentListBuilder &Builder,
388                                 ClassTemplateSpecializationDecl *PrevDecl)
389   : CXXRecordDecl(DK,
390                   SpecializedTemplate->getTemplatedDecl()->getTagKind(),
391                   DC, L,
392                   // FIXME: Should we use DeclarationName for the name of
393                   // class template specializations?
394                   SpecializedTemplate->getIdentifier(),
395                   PrevDecl),
396     SpecializedTemplate(SpecializedTemplate),
397     TemplateArgs(Context, Builder, /*TakeArgs=*/true),
398     SpecializationKind(TSK_Undeclared) {
399 }
400
401 ClassTemplateSpecializationDecl *
402 ClassTemplateSpecializationDecl::Create(ASTContext &Context,
403                                         DeclContext *DC, SourceLocation L,
404                                         ClassTemplateDecl *SpecializedTemplate,
405                                         TemplateArgumentListBuilder &Builder,
406                                    ClassTemplateSpecializationDecl *PrevDecl) {
407   ClassTemplateSpecializationDecl *Result
408     = new (Context)ClassTemplateSpecializationDecl(Context,
409                                                    ClassTemplateSpecialization,
410                                                    DC, L,
411                                                    SpecializedTemplate,
412                                                    Builder,
413                                                    PrevDecl);
414   Context.getTypeDeclType(Result, PrevDecl);
415   return Result;
416 }
417
418 void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) {
419   if (SpecializedPartialSpecialization *PartialSpec
420         = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
421     C.Deallocate(PartialSpec);
422
423   CXXRecordDecl::Destroy(C);
424 }
425
426 void
427 ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
428                                                   const PrintingPolicy &Policy,
429                                                       bool Qualified) const {
430   NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
431
432   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
433   S += TemplateSpecializationType::PrintTemplateArgumentList(
434                                        TemplateArgs.getFlatArgumentList(),
435                                        TemplateArgs.flat_size(),
436                                                              Policy);
437 }
438
439 ClassTemplateDecl *
440 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
441   if (SpecializedPartialSpecialization *PartialSpec
442       = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
443     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
444   return SpecializedTemplate.get<ClassTemplateDecl*>();
445 }
446
447 //===----------------------------------------------------------------------===//
448 // ClassTemplatePartialSpecializationDecl Implementation
449 //===----------------------------------------------------------------------===//
450 ClassTemplatePartialSpecializationDecl *
451 ClassTemplatePartialSpecializationDecl::
452 Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
453        TemplateParameterList *Params,
454        ClassTemplateDecl *SpecializedTemplate,
455        TemplateArgumentListBuilder &Builder,
456        TemplateArgumentLoc *ArgInfos, unsigned N,
457        ClassTemplatePartialSpecializationDecl *PrevDecl) {
458   TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
459   for (unsigned I = 0; I != N; ++I)
460     ClonedArgs[I] = ArgInfos[I];
461
462   ClassTemplatePartialSpecializationDecl *Result
463     = new (Context)ClassTemplatePartialSpecializationDecl(Context,
464                                                           DC, L, Params,
465                                                           SpecializedTemplate,
466                                                           Builder,
467                                                           ClonedArgs, N,
468                                                           PrevDecl);
469   Result->setSpecializationKind(TSK_ExplicitSpecialization);
470   Context.getTypeDeclType(Result, PrevDecl);
471   return Result;
472 }
473
474 //===----------------------------------------------------------------------===//
475 // FriendTemplateDecl Implementation
476 //===----------------------------------------------------------------------===//
477
478 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
479                                                DeclContext *DC,
480                                                SourceLocation L,
481                                                unsigned NParams,
482                                                TemplateParameterList **Params,
483                                                FriendUnion Friend,
484                                                SourceLocation FLoc) {
485   FriendTemplateDecl *Result
486     = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
487   return Result;
488 }