SemaTemplateInstantiateDecl.cpp revision d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4d
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  Owner->addDecl(Enum);
177  Enum->startDefinition();
178
179  llvm::SmallVector<Sema::DeclTy *, 16> Enumerators;
180
181  EnumConstantDecl *LastEnumConst = 0;
182  for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
183         ECEnd = D->enumerator_end();
184       EC != ECEnd; ++EC) {
185    // The specified value for the enumerator.
186    OwningExprResult Value = SemaRef.Owned((Expr *)0);
187    if (Expr *UninstValue = EC->getInitExpr())
188      Value = SemaRef.InstantiateExpr(UninstValue,
189                                      TemplateArgs, NumTemplateArgs);
190
191    // Drop the initial value and continue.
192    bool isInvalid = false;
193    if (Value.isInvalid()) {
194      Value = SemaRef.Owned((Expr *)0);
195      isInvalid = true;
196    }
197
198    EnumConstantDecl *EnumConst
199      = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
200                                  EC->getLocation(), EC->getIdentifier(),
201                                  move(Value));
202
203    if (isInvalid) {
204      if (EnumConst)
205        EnumConst->setInvalidDecl();
206      Enum->setInvalidDecl();
207    }
208
209    if (EnumConst) {
210      Enum->addDecl(EnumConst);
211      Enumerators.push_back(EnumConst);
212      LastEnumConst = EnumConst;
213    }
214  }
215
216  SemaRef.ActOnEnumBody(Enum->getLocation(), Enum,
217                        &Enumerators[0], Enumerators.size());
218
219  return Enum;
220}
221
222Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) {
223  assert(false && "EnumConstantDecls can only occur within EnumDecls.");
224  return 0;
225}
226
227Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
228  CXXRecordDecl *PrevDecl = 0;
229  if (D->isInjectedClassName())
230    PrevDecl = cast<CXXRecordDecl>(Owner);
231
232  CXXRecordDecl *Record
233    = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner,
234                            D->getLocation(), D->getIdentifier(), PrevDecl);
235  Record->setImplicit(D->isImplicit());
236  Record->setAccess(D->getAccess());
237
238  if (!D->isInjectedClassName())
239    Record->setInstantiationOfMemberClass(D);
240
241  Owner->addDecl(Record);
242  return Record;
243}
244
245Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
246  // Only handle actual methods; we'll deal with constructors,
247  // destructors, etc. separately.
248  if (D->getKind() != Decl::CXXMethod)
249    return 0;
250
251  llvm::SmallVector<ParmVarDecl *, 16> Params;
252  QualType T = InstantiateFunctionType(D, Params);
253  if (T.isNull())
254    return 0;
255
256  // Build the instantiated method declaration.
257  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
258  CXXMethodDecl *Method
259    = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
260                            D->getDeclName(), T, D->isStatic(),
261                            D->isInline());
262
263  // Attach the parameters
264  for (unsigned P = 0; P < Params.size(); ++P)
265    Params[P]->setOwningFunction(Method);
266  Method->setParams(SemaRef.Context, &Params[0], Params.size());
267
268  if (InitMethodInstantiation(Method, D))
269    Method->setInvalidDecl();
270
271  NamedDecl *PrevDecl
272    = SemaRef.LookupQualifiedName(Owner, Method->getDeclName(),
273                                  Sema::LookupOrdinaryName, true);
274  // In C++, the previous declaration we find might be a tag type
275  // (class or enum). In this case, the new declaration will hide the
276  // tag type. Note that this does does not apply if we're declaring a
277  // typedef (C++ [dcl.typedef]p4).
278  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
279    PrevDecl = 0;
280  bool Redeclaration = false;
281  bool OverloadableAttrRequired = false;
282  if (SemaRef.CheckFunctionDeclaration(Method, PrevDecl, Redeclaration,
283                                       /*FIXME:*/OverloadableAttrRequired))
284    Method->setInvalidDecl();
285
286  if (!Method->isInvalidDecl() || !PrevDecl)
287    Owner->addDecl(Method);
288  return Method;
289}
290
291Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
292  llvm::SmallVector<ParmVarDecl *, 16> Params;
293  QualType T = InstantiateFunctionType(D, Params);
294  if (T.isNull())
295    return 0;
296
297  // Build the instantiated method declaration.
298  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
299  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
300  DeclarationName Name
301    = SemaRef.Context.DeclarationNames.getCXXConstructorName(ClassTy);
302  CXXConstructorDecl *Constructor
303    = CXXConstructorDecl::Create(SemaRef.Context, Record, D->getLocation(),
304                                 Name, T, D->isExplicit(), D->isInline(),
305                                 false);
306
307  // Attach the parameters
308  for (unsigned P = 0; P < Params.size(); ++P)
309    Params[P]->setOwningFunction(Constructor);
310  Constructor->setParams(SemaRef.Context, &Params[0], Params.size());
311
312  if (InitMethodInstantiation(Constructor, D))
313    Constructor->setInvalidDecl();
314
315  NamedDecl *PrevDecl
316    = SemaRef.LookupQualifiedName(Owner, Name, Sema::LookupOrdinaryName, true);
317
318  // In C++, the previous declaration we find might be a tag type
319  // (class or enum). In this case, the new declaration will hide the
320  // tag type. Note that this does does not apply if we're declaring a
321  // typedef (C++ [dcl.typedef]p4).
322  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
323    PrevDecl = 0;
324  bool Redeclaration = false;
325  bool OverloadableAttrRequired = false;
326  if (SemaRef.CheckFunctionDeclaration(Constructor, PrevDecl, Redeclaration,
327                                       /*FIXME:*/OverloadableAttrRequired))
328    Constructor->setInvalidDecl();
329
330  if (!Constructor->isInvalidDecl())
331    Owner->addDecl(Constructor);
332  return Constructor;
333}
334
335Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
336  llvm::SmallVector<ParmVarDecl *, 16> Params;
337  QualType T = InstantiateFunctionType(D, Params);
338  if (T.isNull())
339    return 0;
340  assert(Params.size() == 0 && "Destructor with parameters?");
341
342  // Build the instantiated destructor declaration.
343  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
344  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
345  CXXDestructorDecl *Destructor
346    = CXXDestructorDecl::Create(SemaRef.Context, Record,
347                                D->getLocation(),
348             SemaRef.Context.DeclarationNames.getCXXDestructorName(ClassTy),
349                                T, D->isInline(), false);
350  if (InitMethodInstantiation(Destructor, D))
351    Destructor->setInvalidDecl();
352
353  bool Redeclaration = false;
354  bool OverloadableAttrRequired = false;
355  NamedDecl *PrevDecl = 0;
356  if (SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration,
357                                       /*FIXME:*/OverloadableAttrRequired))
358    Destructor->setInvalidDecl();
359  Owner->addDecl(Destructor);
360  return Destructor;
361}
362
363Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
364  llvm::SmallVector<ParmVarDecl *, 16> Params;
365  QualType T = InstantiateFunctionType(D, Params);
366  if (T.isNull())
367    return 0;
368  assert(Params.size() == 0 && "Destructor with parameters?");
369
370  // Build the instantiated conversion declaration.
371  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
372  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
373  QualType ConvTy
374    = SemaRef.Context.getCanonicalType(T->getAsFunctionType()->getResultType());
375  CXXConversionDecl *Conversion
376    = CXXConversionDecl::Create(SemaRef.Context, Record,
377                                D->getLocation(),
378         SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(ConvTy),
379                                T, D->isInline(), D->isExplicit());
380  if (InitMethodInstantiation(Conversion, D))
381    Conversion->setInvalidDecl();
382
383  bool Redeclaration = false;
384  bool OverloadableAttrRequired = false;
385  NamedDecl *PrevDecl = 0;
386  if (SemaRef.CheckFunctionDeclaration(Conversion, PrevDecl, Redeclaration,
387                                       /*FIXME:*/OverloadableAttrRequired))
388    Conversion->setInvalidDecl();
389  Owner->addDecl(Conversion);
390  return Conversion;
391}
392
393ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
394  QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs,
395                                           NumTemplateArgs, D->getLocation(),
396                                           D->getDeclName());
397  if (OrigT.isNull())
398    return 0;
399
400  QualType T = SemaRef.adjustParameterType(OrigT);
401
402  if (D->getDefaultArg()) {
403    // FIXME: Leave a marker for "uninstantiated" default
404    // arguments. They only get instantiated on demand at the call
405    // site.
406    unsigned DiagID = SemaRef.Diags.getCustomDiagID(Diagnostic::Warning,
407        "sorry, dropping default argument during template instantiation");
408    SemaRef.Diag(D->getDefaultArg()->getSourceRange().getBegin(), DiagID)
409      << D->getDefaultArg()->getSourceRange();
410  }
411
412  // Allocate the parameter
413  ParmVarDecl *Param = 0;
414  if (T == OrigT)
415    Param = ParmVarDecl::Create(SemaRef.Context, Owner, D->getLocation(),
416                                D->getIdentifier(), T, D->getStorageClass(),
417                                0);
418  else
419    Param = OriginalParmVarDecl::Create(SemaRef.Context, Owner,
420                                        D->getLocation(), D->getIdentifier(),
421                                        T, OrigT, D->getStorageClass(), 0);
422
423  // Note: we don't try to instantiate function parameters until after
424  // we've instantiated the function's type. Therefore, we don't have
425  // to check for 'void' parameter types here.
426  return Param;
427}
428
429Decl *
430TemplateDeclInstantiator::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
431  // Since parameter types can decay either before or after
432  // instantiation, we simply treat OriginalParmVarDecls as
433  // ParmVarDecls the same way, and create one or the other depending
434  // on what happens after template instantiation.
435  return VisitParmVarDecl(D);
436}
437
438Decl *Sema::InstantiateDecl(Decl *D, DeclContext *Owner,
439                            const TemplateArgument *TemplateArgs,
440                            unsigned NumTemplateArgs) {
441  TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs,
442                                        NumTemplateArgs);
443  return Instantiator.Visit(D);
444}
445
446/// \brief Instantiates the type of the given function, including
447/// instantiating all of the function parameters.
448///
449/// \param D The function that we will be instantiated
450///
451/// \param Params the instantiated parameter declarations
452
453/// \returns the instantiated function's type if successfull, a NULL
454/// type if there was an error.
455QualType
456TemplateDeclInstantiator::InstantiateFunctionType(FunctionDecl *D,
457                              llvm::SmallVectorImpl<ParmVarDecl *> &Params) {
458  bool InvalidDecl = false;
459
460  // Instantiate the function parameters
461  TemplateDeclInstantiator ParamInstantiator(SemaRef, 0,
462                                             TemplateArgs, NumTemplateArgs);
463  llvm::SmallVector<QualType, 16> ParamTys;
464  for (FunctionDecl::param_iterator P = D->param_begin(),
465                                 PEnd = D->param_end();
466       P != PEnd; ++P) {
467    if (ParmVarDecl *PInst = ParamInstantiator.VisitParmVarDecl(*P)) {
468      if (PInst->getType()->isVoidType()) {
469        SemaRef.Diag(PInst->getLocation(), diag::err_param_with_void_type);
470        PInst->setInvalidDecl();
471      }
472      else if (SemaRef.RequireNonAbstractType(PInst->getLocation(),
473                                              PInst->getType(),
474                                              diag::err_abstract_type_in_decl,
475                                              Sema::AbstractParamType))
476        PInst->setInvalidDecl();
477
478      Params.push_back(PInst);
479      ParamTys.push_back(PInst->getType());
480
481      if (PInst->isInvalidDecl())
482        InvalidDecl = true;
483    } else
484      InvalidDecl = true;
485  }
486
487  // FIXME: Deallocate dead declarations.
488  if (InvalidDecl)
489    return QualType();
490
491  const FunctionProtoType *Proto = D->getType()->getAsFunctionProtoType();
492  assert(Proto && "Missing prototype?");
493  QualType ResultType
494    = SemaRef.InstantiateType(Proto->getResultType(),
495                              TemplateArgs, NumTemplateArgs,
496                              D->getLocation(), D->getDeclName());
497  if (ResultType.isNull())
498    return QualType();
499
500  return SemaRef.BuildFunctionType(ResultType, &ParamTys[0], ParamTys.size(),
501                                   Proto->isVariadic(), Proto->getTypeQuals(),
502                                   D->getLocation(), D->getDeclName());
503}
504
505/// \brief Initializes common fields of an instantiated method
506/// declaration (New) from the corresponding fields of its template
507/// (Tmpl).
508///
509/// \returns true if there was an error
510bool
511TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
512                                                  CXXMethodDecl *Tmpl) {
513  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
514  New->setAccess(Tmpl->getAccess());
515  if (Tmpl->isVirtual()) {
516    New->setVirtual();
517    Record->setAggregate(false);
518    Record->setPOD(false);
519    Record->setPolymorphic(true);
520  }
521  if (Tmpl->isDeleted())
522    New->setDeleted();
523  if (Tmpl->isPure()) {
524    New->setPure();
525    Record->setAbstract(true);
526  }
527
528  // FIXME: attributes
529  // FIXME: New needs a pointer to Tmpl
530  return false;
531}
532