SemaTemplateInstantiateDecl.cpp revision 06c0fecd197fef21e265a41bca8dc5022de1f864
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 *VisitTranslationUnitDecl(TranslationUnitDecl *D);
43    Decl *VisitNamespaceDecl(NamespaceDecl *D);
44    Decl *VisitTypedefDecl(TypedefDecl *D);
45    Decl *VisitFieldDecl(FieldDecl *D);
46    Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
47    Decl *VisitEnumDecl(EnumDecl *D);
48    Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
49    Decl *VisitCXXRecordDecl(CXXRecordDecl *D);
50    Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
51    Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
52    Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
53    Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
54    ParmVarDecl *VisitParmVarDecl(ParmVarDecl *D);
55    Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
56
57    // Base case. FIXME: Remove once we can instantiate everything.
58    Decl *VisitDecl(Decl *) {
59      return 0;
60    }
61
62    // Helper functions for instantiating methods.
63    QualType InstantiateFunctionType(FunctionDecl *D,
64                             llvm::SmallVectorImpl<ParmVarDecl *> &Params);
65    bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
66  };
67}
68
69Decl *
70TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
71  assert(false && "Translation units cannot be instantiated");
72  return D;
73}
74
75Decl *
76TemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) {
77  assert(false && "Namespaces cannot be instantiated");
78  return D;
79}
80
81Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
82  bool Invalid = false;
83  QualType T = D->getUnderlyingType();
84  if (T->isDependentType()) {
85    T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
86                                D->getLocation(),
87                                D->getDeclName());
88    if (T.isNull()) {
89      Invalid = true;
90      T = SemaRef.Context.IntTy;
91    }
92  }
93
94  // Create the new typedef
95  TypedefDecl *Typedef
96    = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocation(),
97                          D->getIdentifier(), T);
98  if (Invalid)
99    Typedef->setInvalidDecl();
100
101  Owner->addDecl(Typedef);
102  return Typedef;
103}
104
105Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
106  bool Invalid = false;
107  QualType T = D->getType();
108  if (T->isDependentType())  {
109    T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
110                                D->getLocation(),
111                                D->getDeclName());
112    if (!T.isNull() && T->isFunctionType()) {
113      // C++ [temp.arg.type]p3:
114      //   If a declaration acquires a function type through a type
115      //   dependent on a template-parameter and this causes a
116      //   declaration that does not use the syntactic form of a
117      //   function declarator to have function type, the program is
118      //   ill-formed.
119      SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
120        << T;
121      T = QualType();
122      Invalid = true;
123    }
124  }
125
126  Expr *BitWidth = D->getBitWidth();
127  if (Invalid)
128    BitWidth = 0;
129  else if (BitWidth) {
130    OwningExprResult InstantiatedBitWidth
131      = SemaRef.InstantiateExpr(BitWidth, TemplateArgs, NumTemplateArgs);
132    if (InstantiatedBitWidth.isInvalid()) {
133      Invalid = true;
134      BitWidth = 0;
135    } else
136      BitWidth = (Expr *)InstantiatedBitWidth.release();
137  }
138
139  FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(), T,
140                                            cast<RecordDecl>(Owner),
141                                            D->getLocation(),
142                                            D->isMutable(),
143                                            BitWidth,
144                                            D->getAccess(),
145                                            0);
146  if (Field) {
147    if (Invalid)
148      Field->setInvalidDecl();
149
150    Owner->addDecl(Field);
151  }
152
153  return Field;
154}
155
156Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
157  Expr *AssertExpr = D->getAssertExpr();
158
159  OwningExprResult InstantiatedAssertExpr
160    = SemaRef.InstantiateExpr(AssertExpr, TemplateArgs, NumTemplateArgs);
161  if (InstantiatedAssertExpr.isInvalid())
162    return 0;
163
164  OwningExprResult Message = SemaRef.Clone(D->getMessage());
165  Decl *StaticAssert
166    = (Decl *)SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
167                                                move(InstantiatedAssertExpr),
168                                                   move(Message));
169  return StaticAssert;
170}
171
172Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
173  EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner,
174                                    D->getLocation(), D->getIdentifier(),
175                                    /*PrevDecl=*/0);
176  Enum->setAccess(D->getAccess());
177  Owner->addDecl(Enum);
178  Enum->startDefinition();
179
180  llvm::SmallVector<Sema::DeclTy *, 16> Enumerators;
181
182  EnumConstantDecl *LastEnumConst = 0;
183  for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
184         ECEnd = D->enumerator_end();
185       EC != ECEnd; ++EC) {
186    // The specified value for the enumerator.
187    OwningExprResult Value = SemaRef.Owned((Expr *)0);
188    if (Expr *UninstValue = EC->getInitExpr())
189      Value = SemaRef.InstantiateExpr(UninstValue,
190                                      TemplateArgs, NumTemplateArgs);
191
192    // Drop the initial value and continue.
193    bool isInvalid = false;
194    if (Value.isInvalid()) {
195      Value = SemaRef.Owned((Expr *)0);
196      isInvalid = true;
197    }
198
199    EnumConstantDecl *EnumConst
200      = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
201                                  EC->getLocation(), EC->getIdentifier(),
202                                  move(Value));
203
204    if (isInvalid) {
205      if (EnumConst)
206        EnumConst->setInvalidDecl();
207      Enum->setInvalidDecl();
208    }
209
210    if (EnumConst) {
211      Enum->addDecl(EnumConst);
212      Enumerators.push_back(EnumConst);
213      LastEnumConst = EnumConst;
214    }
215  }
216
217  SemaRef.ActOnEnumBody(Enum->getLocation(), Enum,
218                        &Enumerators[0], Enumerators.size());
219
220  return Enum;
221}
222
223Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) {
224  assert(false && "EnumConstantDecls can only occur within EnumDecls.");
225  return 0;
226}
227
228Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
229  CXXRecordDecl *PrevDecl = 0;
230  if (D->isInjectedClassName())
231    PrevDecl = cast<CXXRecordDecl>(Owner);
232
233  CXXRecordDecl *Record
234    = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner,
235                            D->getLocation(), D->getIdentifier(), PrevDecl);
236  Record->setImplicit(D->isImplicit());
237  Record->setAccess(D->getAccess());
238
239  if (!D->isInjectedClassName())
240    Record->setInstantiationOfMemberClass(D);
241
242  Owner->addDecl(Record);
243  return Record;
244}
245
246Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
247  // Only handle actual methods; we'll deal with constructors,
248  // destructors, etc. separately.
249  if (D->getKind() != Decl::CXXMethod)
250    return 0;
251
252  llvm::SmallVector<ParmVarDecl *, 16> Params;
253  QualType T = InstantiateFunctionType(D, Params);
254  if (T.isNull())
255    return 0;
256
257  // Build the instantiated method declaration.
258  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
259  CXXMethodDecl *Method
260    = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
261                            D->getDeclName(), T, D->isStatic(),
262                            D->isInline());
263
264  // Attach the parameters
265  for (unsigned P = 0; P < Params.size(); ++P)
266    Params[P]->setOwningFunction(Method);
267  Method->setParams(SemaRef.Context, &Params[0], Params.size());
268
269  if (InitMethodInstantiation(Method, D))
270    Method->setInvalidDecl();
271
272  NamedDecl *PrevDecl
273    = SemaRef.LookupQualifiedName(Owner, Method->getDeclName(),
274                                  Sema::LookupOrdinaryName, true);
275  // In C++, the previous declaration we find might be a tag type
276  // (class or enum). In this case, the new declaration will hide the
277  // tag type. Note that this does does not apply if we're declaring a
278  // typedef (C++ [dcl.typedef]p4).
279  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
280    PrevDecl = 0;
281  bool Redeclaration = false;
282  bool OverloadableAttrRequired = false;
283  if (SemaRef.CheckFunctionDeclaration(Method, PrevDecl, Redeclaration,
284                                       /*FIXME:*/OverloadableAttrRequired))
285    Method->setInvalidDecl();
286
287  if (!Method->isInvalidDecl() || !PrevDecl)
288    Owner->addDecl(Method);
289  return Method;
290}
291
292Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
293  llvm::SmallVector<ParmVarDecl *, 16> Params;
294  QualType T = InstantiateFunctionType(D, Params);
295  if (T.isNull())
296    return 0;
297
298  // Build the instantiated method declaration.
299  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
300  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
301  DeclarationName Name
302    = SemaRef.Context.DeclarationNames.getCXXConstructorName(ClassTy);
303  CXXConstructorDecl *Constructor
304    = CXXConstructorDecl::Create(SemaRef.Context, Record, D->getLocation(),
305                                 Name, T, D->isExplicit(), D->isInline(),
306                                 false);
307
308  // Attach the parameters
309  for (unsigned P = 0; P < Params.size(); ++P)
310    Params[P]->setOwningFunction(Constructor);
311  Constructor->setParams(SemaRef.Context, &Params[0], Params.size());
312
313  if (InitMethodInstantiation(Constructor, D))
314    Constructor->setInvalidDecl();
315
316  NamedDecl *PrevDecl
317    = SemaRef.LookupQualifiedName(Owner, Name, Sema::LookupOrdinaryName, true);
318
319  // In C++, the previous declaration we find might be a tag type
320  // (class or enum). In this case, the new declaration will hide the
321  // tag type. Note that this does does not apply if we're declaring a
322  // typedef (C++ [dcl.typedef]p4).
323  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
324    PrevDecl = 0;
325  bool Redeclaration = false;
326  bool OverloadableAttrRequired = false;
327  if (SemaRef.CheckFunctionDeclaration(Constructor, PrevDecl, Redeclaration,
328                                       /*FIXME:*/OverloadableAttrRequired))
329    Constructor->setInvalidDecl();
330
331  if (!Constructor->isInvalidDecl())
332    Owner->addDecl(Constructor);
333  return Constructor;
334}
335
336Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
337  llvm::SmallVector<ParmVarDecl *, 16> Params;
338  QualType T = InstantiateFunctionType(D, Params);
339  if (T.isNull())
340    return 0;
341  assert(Params.size() == 0 && "Destructor with parameters?");
342
343  // Build the instantiated destructor declaration.
344  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
345  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
346  CXXDestructorDecl *Destructor
347    = CXXDestructorDecl::Create(SemaRef.Context, Record,
348                                D->getLocation(),
349             SemaRef.Context.DeclarationNames.getCXXDestructorName(ClassTy),
350                                T, D->isInline(), false);
351  if (InitMethodInstantiation(Destructor, D))
352    Destructor->setInvalidDecl();
353
354  bool Redeclaration = false;
355  bool OverloadableAttrRequired = false;
356  NamedDecl *PrevDecl = 0;
357  if (SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration,
358                                       /*FIXME:*/OverloadableAttrRequired))
359    Destructor->setInvalidDecl();
360  Owner->addDecl(Destructor);
361  return Destructor;
362}
363
364Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
365  llvm::SmallVector<ParmVarDecl *, 16> Params;
366  QualType T = InstantiateFunctionType(D, Params);
367  if (T.isNull())
368    return 0;
369  assert(Params.size() == 0 && "Destructor with parameters?");
370
371  // Build the instantiated conversion declaration.
372  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
373  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
374  QualType ConvTy
375    = SemaRef.Context.getCanonicalType(T->getAsFunctionType()->getResultType());
376  CXXConversionDecl *Conversion
377    = CXXConversionDecl::Create(SemaRef.Context, Record,
378                                D->getLocation(),
379         SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(ConvTy),
380                                T, D->isInline(), D->isExplicit());
381  if (InitMethodInstantiation(Conversion, D))
382    Conversion->setInvalidDecl();
383
384  bool Redeclaration = false;
385  bool OverloadableAttrRequired = false;
386  NamedDecl *PrevDecl = 0;
387  if (SemaRef.CheckFunctionDeclaration(Conversion, PrevDecl, Redeclaration,
388                                       /*FIXME:*/OverloadableAttrRequired))
389    Conversion->setInvalidDecl();
390  Owner->addDecl(Conversion);
391  return Conversion;
392}
393
394ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
395  QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs,
396                                           NumTemplateArgs, D->getLocation(),
397                                           D->getDeclName());
398  if (OrigT.isNull())
399    return 0;
400
401  QualType T = SemaRef.adjustParameterType(OrigT);
402
403  if (D->getDefaultArg()) {
404    // FIXME: Leave a marker for "uninstantiated" default
405    // arguments. They only get instantiated on demand at the call
406    // site.
407    unsigned DiagID = SemaRef.Diags.getCustomDiagID(Diagnostic::Warning,
408        "sorry, dropping default argument during template instantiation");
409    SemaRef.Diag(D->getDefaultArg()->getSourceRange().getBegin(), DiagID)
410      << D->getDefaultArg()->getSourceRange();
411  }
412
413  // Allocate the parameter
414  ParmVarDecl *Param = 0;
415  if (T == OrigT)
416    Param = ParmVarDecl::Create(SemaRef.Context, Owner, D->getLocation(),
417                                D->getIdentifier(), T, D->getStorageClass(),
418                                0);
419  else
420    Param = OriginalParmVarDecl::Create(SemaRef.Context, Owner,
421                                        D->getLocation(), D->getIdentifier(),
422                                        T, OrigT, D->getStorageClass(), 0);
423
424  // Note: we don't try to instantiate function parameters until after
425  // we've instantiated the function's type. Therefore, we don't have
426  // to check for 'void' parameter types here.
427  return Param;
428}
429
430Decl *
431TemplateDeclInstantiator::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
432  // Since parameter types can decay either before or after
433  // instantiation, we simply treat OriginalParmVarDecls as
434  // ParmVarDecls the same way, and create one or the other depending
435  // on what happens after template instantiation.
436  return VisitParmVarDecl(D);
437}
438
439Decl *Sema::InstantiateDecl(Decl *D, DeclContext *Owner,
440                            const TemplateArgument *TemplateArgs,
441                            unsigned NumTemplateArgs) {
442  TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs,
443                                        NumTemplateArgs);
444  return Instantiator.Visit(D);
445}
446
447/// \brief Instantiates the type of the given function, including
448/// instantiating all of the function parameters.
449///
450/// \param D The function that we will be instantiated
451///
452/// \param Params the instantiated parameter declarations
453
454/// \returns the instantiated function's type if successfull, a NULL
455/// type if there was an error.
456QualType
457TemplateDeclInstantiator::InstantiateFunctionType(FunctionDecl *D,
458                              llvm::SmallVectorImpl<ParmVarDecl *> &Params) {
459  bool InvalidDecl = false;
460
461  // Instantiate the function parameters
462  TemplateDeclInstantiator ParamInstantiator(SemaRef, 0,
463                                             TemplateArgs, NumTemplateArgs);
464  llvm::SmallVector<QualType, 16> ParamTys;
465  for (FunctionDecl::param_iterator P = D->param_begin(),
466                                 PEnd = D->param_end();
467       P != PEnd; ++P) {
468    if (ParmVarDecl *PInst = ParamInstantiator.VisitParmVarDecl(*P)) {
469      if (PInst->getType()->isVoidType()) {
470        SemaRef.Diag(PInst->getLocation(), diag::err_param_with_void_type);
471        PInst->setInvalidDecl();
472      }
473      else if (SemaRef.RequireNonAbstractType(PInst->getLocation(),
474                                              PInst->getType(),
475                                              diag::err_abstract_type_in_decl,
476                                              Sema::AbstractParamType))
477        PInst->setInvalidDecl();
478
479      Params.push_back(PInst);
480      ParamTys.push_back(PInst->getType());
481
482      if (PInst->isInvalidDecl())
483        InvalidDecl = true;
484    } else
485      InvalidDecl = true;
486  }
487
488  // FIXME: Deallocate dead declarations.
489  if (InvalidDecl)
490    return QualType();
491
492  const FunctionProtoType *Proto = D->getType()->getAsFunctionProtoType();
493  assert(Proto && "Missing prototype?");
494  QualType ResultType
495    = SemaRef.InstantiateType(Proto->getResultType(),
496                              TemplateArgs, NumTemplateArgs,
497                              D->getLocation(), D->getDeclName());
498  if (ResultType.isNull())
499    return QualType();
500
501  return SemaRef.BuildFunctionType(ResultType, &ParamTys[0], ParamTys.size(),
502                                   Proto->isVariadic(), Proto->getTypeQuals(),
503                                   D->getLocation(), D->getDeclName());
504}
505
506/// \brief Initializes common fields of an instantiated method
507/// declaration (New) from the corresponding fields of its template
508/// (Tmpl).
509///
510/// \returns true if there was an error
511bool
512TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
513                                                  CXXMethodDecl *Tmpl) {
514  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
515  New->setAccess(Tmpl->getAccess());
516  if (Tmpl->isVirtual()) {
517    New->setVirtual();
518    Record->setAggregate(false);
519    Record->setPOD(false);
520    Record->setPolymorphic(true);
521  }
522  if (Tmpl->isDeleted())
523    New->setDeleted();
524  if (Tmpl->isPure()) {
525    New->setPure();
526    Record->setAbstract(true);
527  }
528
529  // FIXME: attributes
530  // FIXME: New needs a pointer to Tmpl
531  return false;
532}
533