SemaTemplateInstantiateDecl.cpp revision 5545e166a956a20d7a6b58408e251a1119025485
1//===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl Instantiation ===/
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//  This file implements C++ template instantiation for declarations.
10//
11//===----------------------------------------------------------------------===/
12#include "Sema.h"
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/DeclTemplate.h"
15#include "clang/AST/DeclVisitor.h"
16#include "clang/AST/Expr.h"
17#include "llvm/Support/Compiler.h"
18
19using namespace clang;
20
21namespace {
22  class VISIBILITY_HIDDEN TemplateDeclInstantiator
23    : public DeclVisitor<TemplateDeclInstantiator, Decl *>
24  {
25    Sema &SemaRef;
26    DeclContext *Owner;
27    const TemplateArgument *TemplateArgs;
28    unsigned NumTemplateArgs;
29
30  public:
31    typedef Sema::OwningExprResult OwningExprResult;
32
33    TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
34                             const TemplateArgument *TemplateArgs,
35                             unsigned NumTemplateArgs)
36      : SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs),
37        NumTemplateArgs(NumTemplateArgs) { }
38
39    // FIXME: Once we get closer to completion, replace these
40    // manually-written declarations with automatically-generated ones
41    // from clang/AST/DeclNodes.def.
42    Decl *VisitTypedefDecl(TypedefDecl *D);
43    Decl *VisitFieldDecl(FieldDecl *D);
44    Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
45    Decl *VisitEnumDecl(EnumDecl *D);
46    Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
47    Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
48    Decl *VisitParmVarDecl(ParmVarDecl *D);
49    Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
50
51    // Base case. FIXME: Remove once we can instantiate everything.
52    Decl *VisitDecl(Decl *) {
53      return 0;
54    }
55
56    // Helper functions for instantiating methods.
57    QualType InstantiateFunctionType(FunctionDecl *D,
58                             llvm::SmallVectorImpl<ParmVarDecl *> &Params);
59    bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
60  };
61}
62
63Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
64  bool Invalid = false;
65  QualType T = D->getUnderlyingType();
66  if (T->isDependentType()) {
67    T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
68                                D->getLocation(),
69                                D->getDeclName());
70    if (T.isNull()) {
71      Invalid = true;
72      T = SemaRef.Context.IntTy;
73    }
74  }
75
76  // Create the new typedef
77  TypedefDecl *Typedef
78    = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocation(),
79                          D->getIdentifier(), T);
80  if (Invalid)
81    Typedef->setInvalidDecl();
82
83  Owner->addDecl(Typedef);
84  return Typedef;
85}
86
87Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
88  bool Invalid = false;
89  QualType T = D->getType();
90  if (T->isDependentType())  {
91    T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
92                                D->getLocation(),
93                                D->getDeclName());
94    if (!T.isNull() && T->isFunctionType()) {
95      // C++ [temp.arg.type]p3:
96      //   If a declaration acquires a function type through a type
97      //   dependent on a template-parameter and this causes a
98      //   declaration that does not use the syntactic form of a
99      //   function declarator to have function type, the program is
100      //   ill-formed.
101      SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
102        << T;
103      T = QualType();
104      Invalid = true;
105    }
106  }
107
108  Expr *BitWidth = D->getBitWidth();
109  if (Invalid)
110    BitWidth = 0;
111  else if (BitWidth) {
112    OwningExprResult InstantiatedBitWidth
113      = SemaRef.InstantiateExpr(BitWidth, TemplateArgs, NumTemplateArgs);
114    if (InstantiatedBitWidth.isInvalid()) {
115      Invalid = true;
116      BitWidth = 0;
117    } else
118      BitWidth = (Expr *)InstantiatedBitWidth.release();
119  }
120
121  FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(), T,
122                                            cast<RecordDecl>(Owner),
123                                            D->getLocation(),
124                                            D->isMutable(),
125                                            BitWidth,
126                                            D->getAccess(),
127                                            0);
128  if (Field) {
129    if (Invalid)
130      Field->setInvalidDecl();
131
132    Owner->addDecl(Field);
133  }
134
135  return Field;
136}
137
138Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
139  Expr *AssertExpr = D->getAssertExpr();
140
141  OwningExprResult InstantiatedAssertExpr
142    = SemaRef.InstantiateExpr(AssertExpr, TemplateArgs, NumTemplateArgs);
143  if (InstantiatedAssertExpr.isInvalid())
144    return 0;
145
146  OwningExprResult Message = SemaRef.Clone(D->getMessage());
147  Decl *StaticAssert
148    = (Decl *)SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
149                                                move(InstantiatedAssertExpr),
150                                                   move(Message));
151  return StaticAssert;
152}
153
154Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
155  EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner,
156                                    D->getLocation(), D->getIdentifier(),
157                                    /*PrevDecl=*/0);
158  Owner->addDecl(Enum);
159  Enum->startDefinition();
160
161  llvm::SmallVector<Sema::DeclTy *, 16> Enumerators;
162
163  EnumConstantDecl *LastEnumConst = 0;
164  for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
165         ECEnd = D->enumerator_end();
166       EC != ECEnd; ++EC) {
167    // The specified value for the enumerator.
168    OwningExprResult Value = SemaRef.Owned((Expr *)0);
169    if (Expr *UninstValue = EC->getInitExpr())
170      Value = SemaRef.InstantiateExpr(UninstValue,
171                                      TemplateArgs, NumTemplateArgs);
172
173    // Drop the initial value and continue.
174    bool isInvalid = false;
175    if (Value.isInvalid()) {
176      Value = SemaRef.Owned((Expr *)0);
177      isInvalid = true;
178    }
179
180    EnumConstantDecl *EnumConst
181      = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
182                                  EC->getLocation(), EC->getIdentifier(),
183                                  move(Value));
184
185    if (isInvalid) {
186      if (EnumConst)
187        EnumConst->setInvalidDecl();
188      Enum->setInvalidDecl();
189    }
190
191    if (EnumConst) {
192      Enum->addDecl(EnumConst);
193      Enumerators.push_back(EnumConst);
194      LastEnumConst = EnumConst;
195    }
196  }
197
198  SemaRef.ActOnEnumBody(Enum->getLocation(), Enum,
199                        &Enumerators[0], Enumerators.size());
200
201  return Enum;
202}
203
204Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
205  // Only handle actual methods; we'll deal with constructors,
206  // destructors, etc. separately.
207  if (D->getKind() != Decl::CXXMethod)
208    return 0;
209
210  llvm::SmallVector<ParmVarDecl *, 16> Params;
211  QualType T = InstantiateFunctionType(D, Params);
212  if (T.isNull())
213    return 0;
214
215  // Build the instantiated method declaration.
216  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
217  CXXMethodDecl *Method
218    = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
219                            D->getDeclName(), T, D->isStatic(),
220                            D->isInline());
221
222  // Attach the parameters
223  for (unsigned P = 0; P < Params.size(); ++P)
224    Params[P]->setOwningFunction(Method);
225  Method->setParams(SemaRef.Context, &Params[0], Params.size());
226
227  if (InitMethodInstantiation(Method, D))
228    Method->setInvalidDecl();
229
230  NamedDecl *PrevDecl
231    = SemaRef.LookupQualifiedName(Owner, Method->getDeclName(),
232                                  Sema::LookupOrdinaryName, true);
233  // In C++, the previous declaration we find might be a tag type
234  // (class or enum). In this case, the new declaration will hide the
235  // tag type. Note that this does does not apply if we're declaring a
236  // typedef (C++ [dcl.typedef]p4).
237  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
238    PrevDecl = 0;
239  bool Redeclaration = false;
240  bool OverloadableAttrRequired = false;
241  if (SemaRef.CheckFunctionDeclaration(Method, PrevDecl, Redeclaration,
242                                       /*FIXME:*/OverloadableAttrRequired))
243    Method->setInvalidDecl();
244
245  if (!Method->isInvalidDecl() || !PrevDecl)
246    Owner->addDecl(Method);
247  return Method;
248}
249
250Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
251  llvm::SmallVector<ParmVarDecl *, 16> Params;
252  QualType T = InstantiateFunctionType(D, Params);
253  if (T.isNull())
254    return 0;
255  assert(Params.size() == 0 && "Destructor with parameters?");
256
257  // Build the instantiated destructor declaration.
258  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
259  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
260  CXXDestructorDecl *Destructor
261    = CXXDestructorDecl::Create(SemaRef.Context, Record,
262                                D->getLocation(),
263             SemaRef.Context.DeclarationNames.getCXXDestructorName(ClassTy),
264                                T, D->isInline(), false);
265  if (InitMethodInstantiation(Destructor, D))
266    Destructor->setInvalidDecl();
267
268  bool Redeclaration = false;
269  bool OverloadableAttrRequired = false;
270  NamedDecl *PrevDecl = 0;
271  if (SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration,
272                                       /*FIXME:*/OverloadableAttrRequired))
273    Destructor->setInvalidDecl();
274  Owner->addDecl(Destructor);
275  return Destructor;
276}
277
278Decl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
279  QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs,
280                                           NumTemplateArgs, D->getLocation(),
281                                           D->getDeclName());
282  if (OrigT.isNull())
283    return 0;
284
285  QualType T = SemaRef.adjustParameterType(OrigT);
286
287  if (D->getDefaultArg()) {
288    // FIXME: Leave a marker for "uninstantiated" default
289    // arguments. They only get instantiated on demand at the call
290    // site.
291    unsigned DiagID = SemaRef.Diags.getCustomDiagID(Diagnostic::Warning,
292        "sorry, dropping default argument during template instantiation");
293    SemaRef.Diag(D->getDefaultArg()->getSourceRange().getBegin(), DiagID)
294      << D->getDefaultArg()->getSourceRange();
295  }
296
297  // Allocate the parameter
298  ParmVarDecl *Param = 0;
299  if (T == OrigT)
300    Param = ParmVarDecl::Create(SemaRef.Context, Owner, D->getLocation(),
301                                D->getIdentifier(), T, D->getStorageClass(),
302                                0);
303  else
304    Param = OriginalParmVarDecl::Create(SemaRef.Context, Owner,
305                                        D->getLocation(), D->getIdentifier(),
306                                        T, OrigT, D->getStorageClass(), 0);
307
308  // Note: we don't try to instantiate function parameters until after
309  // we've instantiated the function's type. Therefore, we don't have
310  // to check for 'void' parameter types here.
311  return Param;
312}
313
314Decl *
315TemplateDeclInstantiator::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
316  // Since parameter types can decay either before or after
317  // instantiation, we simply treat OriginalParmVarDecls as
318  // ParmVarDecls the same way, and create one or the other depending
319  // on what happens after template instantiation.
320  return VisitParmVarDecl(D);
321}
322
323Decl *Sema::InstantiateDecl(Decl *D, DeclContext *Owner,
324                            const TemplateArgument *TemplateArgs,
325                            unsigned NumTemplateArgs) {
326  TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs,
327                                        NumTemplateArgs);
328  return Instantiator.Visit(D);
329}
330
331/// \brief Instantiates the type of the given function, including
332/// instantiating all of the function parameters.
333///
334/// \param D The function that we will be instantiated
335///
336/// \param Params the instantiated parameter declarations
337
338/// \returns the instantiated function's type if successfull, a NULL
339/// type if there was an error.
340QualType
341TemplateDeclInstantiator::InstantiateFunctionType(FunctionDecl *D,
342                              llvm::SmallVectorImpl<ParmVarDecl *> &Params) {
343  bool InvalidDecl = false;
344
345  // Instantiate the function parameters
346  TemplateDeclInstantiator ParamInstantiator(SemaRef, 0,
347                                             TemplateArgs, NumTemplateArgs);
348  llvm::SmallVector<QualType, 16> ParamTys;
349  for (FunctionDecl::param_iterator P = D->param_begin(),
350                                 PEnd = D->param_end();
351       P != PEnd; ++P) {
352    if (ParmVarDecl *PInst = (ParmVarDecl *)ParamInstantiator.Visit(*P)) {
353      if (PInst->getType()->isVoidType()) {
354        SemaRef.Diag(PInst->getLocation(), diag::err_param_with_void_type);
355        PInst->setInvalidDecl();
356      }
357      else if (SemaRef.RequireNonAbstractType(PInst->getLocation(),
358                                              PInst->getType(),
359                                              diag::err_abstract_type_in_decl,
360                                              1 /* parameter type */))
361        PInst->setInvalidDecl();
362
363      Params.push_back(PInst);
364      ParamTys.push_back(PInst->getType());
365
366      if (PInst->isInvalidDecl())
367        InvalidDecl = true;
368    } else
369      InvalidDecl = true;
370  }
371
372  // FIXME: Deallocate dead declarations.
373  if (InvalidDecl)
374    return QualType();
375
376  const FunctionProtoType *Proto = D->getType()->getAsFunctionProtoType();
377  assert(Proto && "Missing prototype?");
378  QualType ResultType
379    = SemaRef.InstantiateType(Proto->getResultType(),
380                              TemplateArgs, NumTemplateArgs,
381                              D->getLocation(), D->getDeclName());
382  if (ResultType.isNull())
383    return QualType();
384
385  return SemaRef.BuildFunctionType(ResultType, &ParamTys[0], ParamTys.size(),
386                                   Proto->isVariadic(), Proto->getTypeQuals(),
387                                   D->getLocation(), D->getDeclName());
388}
389
390/// \brief Initializes common fields of an instantiated method
391/// declaration (New) from the corresponding fields of its template
392/// (Tmpl).
393///
394/// \returns true if there was an error
395bool
396TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
397                                                  CXXMethodDecl *Tmpl) {
398  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
399  New->setAccess(Tmpl->getAccess());
400  if (Tmpl->isVirtual()) {
401    New->setVirtual();
402    Record->setAggregate(false);
403    Record->setPOD(false);
404    Record->setPolymorphic(true);
405  }
406  if (Tmpl->isDeleted())
407    New->setDeleted();
408  if (Tmpl->isPure()) {
409    New->setPure();
410    Record->setAbstract(true);
411  }
412
413  // FIXME: attributes
414  // FIXME: New needs a pointer to Tmpl
415  return false;
416}
417