DeclTemplate.cpp revision 193326
1193326Sed//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file implements the C++ related Decl classes for templates.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "clang/AST/DeclCXX.h"
15193326Sed#include "clang/AST/DeclTemplate.h"
16193326Sed#include "clang/AST/Expr.h"
17193326Sed#include "clang/AST/ASTContext.h"
18193326Sed#include "clang/Basic/IdentifierTable.h"
19193326Sed#include "llvm/ADT/STLExtras.h"
20193326Sedusing namespace clang;
21193326Sed
22193326Sed//===----------------------------------------------------------------------===//
23193326Sed// TemplateParameterList Implementation
24193326Sed//===----------------------------------------------------------------------===//
25193326Sed
26193326SedTemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
27193326Sed                                             SourceLocation LAngleLoc,
28193326Sed                                             Decl **Params, unsigned NumParams,
29193326Sed                                             SourceLocation RAngleLoc)
30193326Sed  : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
31193326Sed    NumParams(NumParams) {
32193326Sed  for (unsigned Idx = 0; Idx < NumParams; ++Idx)
33193326Sed    begin()[Idx] = Params[Idx];
34193326Sed}
35193326Sed
36193326SedTemplateParameterList *
37193326SedTemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc,
38193326Sed                              SourceLocation LAngleLoc, Decl **Params,
39193326Sed                              unsigned NumParams, SourceLocation RAngleLoc) {
40193326Sed  unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams;
41193326Sed  unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
42193326Sed  void *Mem = C.Allocate(Size, Align);
43193326Sed  return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
44193326Sed                                         NumParams, RAngleLoc);
45193326Sed}
46193326Sed
47193326Sedunsigned TemplateParameterList::getMinRequiredArguments() const {
48193326Sed  unsigned NumRequiredArgs = size();
49193326Sed  iterator Param = const_cast<TemplateParameterList *>(this)->end(),
50193326Sed      ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
51193326Sed  while (Param != ParamBegin) {
52193326Sed    --Param;
53193326Sed    if (!(isa<TemplateTypeParmDecl>(*Param) &&
54193326Sed          cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
55193326Sed        !(isa<NonTypeTemplateParmDecl>(*Param) &&
56193326Sed          cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&
57193326Sed        !(isa<TemplateTemplateParmDecl>(*Param) &&
58193326Sed          cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument()))
59193326Sed      break;
60193326Sed
61193326Sed    --NumRequiredArgs;
62193326Sed  }
63193326Sed
64193326Sed  return NumRequiredArgs;
65193326Sed}
66193326Sed
67193326Sed//===----------------------------------------------------------------------===//
68193326Sed// TemplateDecl Implementation
69193326Sed//===----------------------------------------------------------------------===//
70193326Sed
71193326SedTemplateDecl::~TemplateDecl() {
72193326Sed}
73193326Sed
74193326Sed//===----------------------------------------------------------------------===//
75193326Sed// FunctionTemplateDecl Implementation
76193326Sed//===----------------------------------------------------------------------===//
77193326Sed
78193326SedFunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
79193326Sed                                                   DeclContext *DC,
80193326Sed                                                   SourceLocation L,
81193326Sed                                                   DeclarationName Name,
82193326Sed                                                   TemplateParameterList *Params,
83193326Sed                                                   NamedDecl *Decl) {
84193326Sed  return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
85193326Sed}
86193326Sed
87193326Sed//===----------------------------------------------------------------------===//
88193326Sed// ClassTemplateDecl Implementation
89193326Sed//===----------------------------------------------------------------------===//
90193326Sed
91193326SedClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
92193326Sed                                             DeclContext *DC,
93193326Sed                                             SourceLocation L,
94193326Sed                                             DeclarationName Name,
95193326Sed                                             TemplateParameterList *Params,
96193326Sed                                             NamedDecl *Decl,
97193326Sed                                             ClassTemplateDecl *PrevDecl) {
98193326Sed  Common *CommonPtr;
99193326Sed  if (PrevDecl)
100193326Sed    CommonPtr = PrevDecl->CommonPtr;
101193326Sed  else
102193326Sed    CommonPtr = new (C) Common;
103193326Sed
104193326Sed  return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
105193326Sed                                   CommonPtr);
106193326Sed}
107193326Sed
108193326SedClassTemplateDecl::~ClassTemplateDecl() {
109193326Sed  assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed");
110193326Sed}
111193326Sed
112193326Sedvoid ClassTemplateDecl::Destroy(ASTContext& C) {
113193326Sed  if (!PreviousDeclaration) {
114193326Sed    CommonPtr->~Common();
115193326Sed    C.Deallocate((void*)CommonPtr);
116193326Sed  }
117193326Sed  CommonPtr = 0;
118193326Sed
119193326Sed  this->~ClassTemplateDecl();
120193326Sed  C.Deallocate((void*)this);
121193326Sed}
122193326Sed
123193326SedQualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
124193326Sed  if (!CommonPtr->InjectedClassNameType.isNull())
125193326Sed    return CommonPtr->InjectedClassNameType;
126193326Sed
127193326Sed  // FIXME: n2800 14.6.1p1 should say how the template arguments
128193326Sed  // corresponding to template parameter packs should be pack
129193326Sed  // expansions. We already say that in 14.6.2.1p2, so it would be
130193326Sed  // better to fix that redundancy.
131193326Sed
132193326Sed  TemplateParameterList *Params = getTemplateParameters();
133193326Sed
134193326Sed  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
135193326Sed  llvm::SmallVector<TemplateArgument, 16> CanonTemplateArgs;
136193326Sed  TemplateArgs.reserve(Params->size());
137193326Sed  CanonTemplateArgs.reserve(Params->size());
138193326Sed
139193326Sed  for (TemplateParameterList::iterator
140193326Sed         Param = Params->begin(), ParamEnd = Params->end();
141193326Sed       Param != ParamEnd; ++Param) {
142193326Sed    if (isa<TemplateTypeParmDecl>(*Param)) {
143193326Sed      QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
144193326Sed      TemplateArgs.push_back(TemplateArgument((*Param)->getLocation(),
145193326Sed                                              ParamType));
146193326Sed      CanonTemplateArgs.push_back(
147193326Sed                         TemplateArgument((*Param)->getLocation(),
148193326Sed                                          Context.getCanonicalType(ParamType)));
149193326Sed    } else if (NonTypeTemplateParmDecl *NTTP =
150193326Sed                 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
151193326Sed      // FIXME: Build canonical expression, too!
152193326Sed      Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
153193326Sed                                          NTTP->getLocation(),
154193326Sed                                          NTTP->getType()->isDependentType(),
155193326Sed                                          /*Value-dependent=*/true);
156193326Sed      TemplateArgs.push_back(TemplateArgument(E));
157193326Sed      CanonTemplateArgs.push_back(TemplateArgument(E));
158193326Sed    } else {
159193326Sed      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
160193326Sed      TemplateArgs.push_back(TemplateArgument(TTP->getLocation(), TTP));
161193326Sed      CanonTemplateArgs.push_back(TemplateArgument(TTP->getLocation(),
162193326Sed                                              Context.getCanonicalDecl(TTP)));
163193326Sed    }
164193326Sed  }
165193326Sed
166193326Sed  // FIXME: I should really move the "build-the-canonical-type" logic
167193326Sed  // into ASTContext::getTemplateSpecializationType.
168193326Sed  TemplateName Name = TemplateName(this);
169193326Sed  QualType CanonType = Context.getTemplateSpecializationType(
170193326Sed                                       Context.getCanonicalTemplateName(Name),
171193326Sed                                             &CanonTemplateArgs[0],
172193326Sed                                             CanonTemplateArgs.size());
173193326Sed
174193326Sed  CommonPtr->InjectedClassNameType
175193326Sed    = Context.getTemplateSpecializationType(Name,
176193326Sed                                            &TemplateArgs[0],
177193326Sed                                            TemplateArgs.size(),
178193326Sed                                            CanonType);
179193326Sed  return CommonPtr->InjectedClassNameType;
180193326Sed}
181193326Sed
182193326Sed//===----------------------------------------------------------------------===//
183193326Sed// TemplateTypeParm Allocation/Deallocation Method Implementations
184193326Sed//===----------------------------------------------------------------------===//
185193326Sed
186193326SedTemplateTypeParmDecl *
187193326SedTemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
188193326Sed                             SourceLocation L, unsigned D, unsigned P,
189193326Sed                             IdentifierInfo *Id, bool Typename) {
190193326Sed  QualType Type = C.getTemplateTypeParmType(D, P, Id);
191193326Sed  return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type);
192193326Sed}
193193326Sed
194193326Sed//===----------------------------------------------------------------------===//
195193326Sed// NonTypeTemplateParmDecl Method Implementations
196193326Sed//===----------------------------------------------------------------------===//
197193326Sed
198193326SedNonTypeTemplateParmDecl *
199193326SedNonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
200193326Sed                                SourceLocation L, unsigned D, unsigned P,
201193326Sed                                IdentifierInfo *Id, QualType T,
202193326Sed                                SourceLocation TypeSpecStartLoc) {
203193326Sed  return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T,
204193326Sed                                         TypeSpecStartLoc);
205193326Sed}
206193326Sed
207193326SedSourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
208193326Sed  return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
209193326Sed                        : SourceLocation();
210193326Sed}
211193326Sed
212193326Sed//===----------------------------------------------------------------------===//
213193326Sed// TemplateTemplateParmDecl Method Implementations
214193326Sed//===----------------------------------------------------------------------===//
215193326Sed
216193326SedTemplateTemplateParmDecl *
217193326SedTemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
218193326Sed                                 SourceLocation L, unsigned D, unsigned P,
219193326Sed                                 IdentifierInfo *Id,
220193326Sed                                 TemplateParameterList *Params) {
221193326Sed  return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
222193326Sed}
223193326Sed
224193326SedSourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
225193326Sed  return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
226193326Sed                        : SourceLocation();
227193326Sed}
228193326Sed
229193326Sed//===----------------------------------------------------------------------===//
230193326Sed// TemplateArgument Implementation
231193326Sed//===----------------------------------------------------------------------===//
232193326Sed
233193326SedTemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
234193326Sed  TypeOrValue = reinterpret_cast<uintptr_t>(E);
235193326Sed  StartLoc = E->getSourceRange().getBegin();
236193326Sed}
237193326Sed
238193326Sed//===----------------------------------------------------------------------===//
239193326Sed// TemplateArgumentList Implementation
240193326Sed//===----------------------------------------------------------------------===//
241193326SedTemplateArgumentList::TemplateArgumentList(ASTContext &Context,
242193326Sed                                           TemplateArgument *TemplateArgs,
243193326Sed                                           unsigned NumTemplateArgs,
244193326Sed                                           bool CopyArgs)
245193326Sed  : NumArguments(NumTemplateArgs) {
246193326Sed  if (!CopyArgs) {
247193326Sed    Arguments.setPointer(TemplateArgs);
248193326Sed    Arguments.setInt(1);
249193326Sed    return;
250193326Sed  }
251193326Sed
252193326Sed  unsigned Size = sizeof(TemplateArgument) * NumTemplateArgs;
253193326Sed  unsigned Align = llvm::AlignOf<TemplateArgument>::Alignment;
254193326Sed  void *Mem = Context.Allocate(Size, Align);
255193326Sed  Arguments.setPointer((TemplateArgument *)Mem);
256193326Sed  Arguments.setInt(0);
257193326Sed
258193326Sed  TemplateArgument *Args = (TemplateArgument *)Mem;
259193326Sed  for (unsigned I = 0; I != NumTemplateArgs; ++I)
260193326Sed    new (Args + I) TemplateArgument(TemplateArgs[I]);
261193326Sed}
262193326Sed
263193326SedTemplateArgumentList::~TemplateArgumentList() {
264193326Sed  // FIXME: Deallocate template arguments
265193326Sed}
266193326Sed
267193326Sed//===----------------------------------------------------------------------===//
268193326Sed// ClassTemplateSpecializationDecl Implementation
269193326Sed//===----------------------------------------------------------------------===//
270193326SedClassTemplateSpecializationDecl::
271193326SedClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
272193326Sed                                DeclContext *DC, SourceLocation L,
273193326Sed                                ClassTemplateDecl *SpecializedTemplate,
274193326Sed                                TemplateArgument *TemplateArgs,
275193326Sed                                unsigned NumTemplateArgs)
276193326Sed  : CXXRecordDecl(DK,
277193326Sed                  SpecializedTemplate->getTemplatedDecl()->getTagKind(),
278193326Sed                  DC, L,
279193326Sed                  // FIXME: Should we use DeclarationName for the name of
280193326Sed                  // class template specializations?
281193326Sed                  SpecializedTemplate->getIdentifier()),
282193326Sed    SpecializedTemplate(SpecializedTemplate),
283193326Sed    TemplateArgs(Context, TemplateArgs, NumTemplateArgs, /*CopyArgs=*/true),
284193326Sed    SpecializationKind(TSK_Undeclared) {
285193326Sed}
286193326Sed
287193326SedClassTemplateSpecializationDecl *
288193326SedClassTemplateSpecializationDecl::Create(ASTContext &Context,
289193326Sed                                        DeclContext *DC, SourceLocation L,
290193326Sed                                        ClassTemplateDecl *SpecializedTemplate,
291193326Sed                                        TemplateArgument *TemplateArgs,
292193326Sed                                        unsigned NumTemplateArgs,
293193326Sed                                   ClassTemplateSpecializationDecl *PrevDecl) {
294193326Sed  ClassTemplateSpecializationDecl *Result
295193326Sed    = new (Context)ClassTemplateSpecializationDecl(Context,
296193326Sed                                                   ClassTemplateSpecialization,
297193326Sed                                                   DC, L,
298193326Sed                                                   SpecializedTemplate,
299193326Sed                                                   TemplateArgs,
300193326Sed                                                   NumTemplateArgs);
301193326Sed  Context.getTypeDeclType(Result, PrevDecl);
302193326Sed  return Result;
303193326Sed}
304193326Sed
305193326Sed//===----------------------------------------------------------------------===//
306193326Sed// ClassTemplatePartialSpecializationDecl Implementation
307193326Sed//===----------------------------------------------------------------------===//
308193326SedClassTemplatePartialSpecializationDecl *
309193326SedClassTemplatePartialSpecializationDecl::
310193326SedCreate(ASTContext &Context, DeclContext *DC, SourceLocation L,
311193326Sed       TemplateParameterList *Params,
312193326Sed       ClassTemplateDecl *SpecializedTemplate,
313193326Sed       TemplateArgument *TemplateArgs, unsigned NumTemplateArgs,
314193326Sed       ClassTemplatePartialSpecializationDecl *PrevDecl) {
315193326Sed  ClassTemplatePartialSpecializationDecl *Result
316193326Sed    = new (Context)ClassTemplatePartialSpecializationDecl(Context,
317193326Sed                                                          DC, L, Params,
318193326Sed                                                          SpecializedTemplate,
319193326Sed                                                          TemplateArgs,
320193326Sed                                                          NumTemplateArgs);
321193326Sed  Result->setSpecializationKind(TSK_ExplicitSpecialization);
322193326Sed  Context.getTypeDeclType(Result, PrevDecl);
323193326Sed  return Result;
324193326Sed}
325