SemaTemplateInstantiateDecl.cpp revision 48dd19b19ddb9e105f8cf0bf6f0732ca4e6a385b
18dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl Instantiation ===/
28dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//
38dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//                     The LLVM Compiler Infrastructure
48dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//
58dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// This file is distributed under the University of Illinois Open Source
68dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor// License. See LICENSE.TXT for details.
78dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//===----------------------------------------------------------------------===/
88dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//
98dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//  This file implements C++ template instantiation for declarations.
108dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//
118dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor//===----------------------------------------------------------------------===/
128dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "Sema.h"
138dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "clang/AST/ASTContext.h"
148dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "clang/AST/DeclTemplate.h"
158dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "clang/AST/DeclVisitor.h"
168dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "clang/AST/Expr.h"
178dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor#include "llvm/Support/Compiler.h"
188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregorusing namespace clang;
208dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
218dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregornamespace {
228dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  class VISIBILITY_HIDDEN TemplateDeclInstantiator
23b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    : public DeclVisitor<TemplateDeclInstantiator, Decl *> {
248dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Sema &SemaRef;
258dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    DeclContext *Owner;
267e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    const TemplateArgumentList &TemplateArgs;
278dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
288dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  public:
298dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    typedef Sema::OwningExprResult OwningExprResult;
308dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
318dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
327e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                             const TemplateArgumentList &TemplateArgs)
337e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor      : SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs) { }
348dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
358dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // FIXME: Once we get closer to completion, replace these
368dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // manually-written declarations with automatically-generated ones
378dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // from clang/AST/DeclNodes.def.
384f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor    Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
394f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor    Decl *VisitNamespaceDecl(NamespaceDecl *D);
408dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitTypedefDecl(TypedefDecl *D);
413d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor    Decl *VisitVarDecl(VarDecl *D);
428dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitFieldDecl(FieldDecl *D);
438dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
448dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitEnumDecl(EnumDecl *D);
456477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor    Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
46d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor    Decl *VisitCXXRecordDecl(CXXRecordDecl *D);
472dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
48615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor    Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
4903b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor    Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
50bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor    Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
516477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor    ParmVarDecl *VisitParmVarDecl(ParmVarDecl *D);
522dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
535545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
548dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // Base case. FIXME: Remove once we can instantiate everything.
558dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitDecl(Decl *) {
563d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor      assert(false && "Template instantiation of unknown declaration kind!");
578dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      return 0;
588dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
595545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
605545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    // Helper functions for instantiating methods.
615545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    QualType InstantiateFunctionType(FunctionDecl *D,
625545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                             llvm::SmallVectorImpl<ParmVarDecl *> &Params);
635545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
648dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  };
658dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
668dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
674f722be4587a7a0dece399fb5405dda158971ae1Douglas GregorDecl *
684f722be4587a7a0dece399fb5405dda158971ae1Douglas GregorTemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
694f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor  assert(false && "Translation units cannot be instantiated");
704f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor  return D;
714f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor}
724f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor
734f722be4587a7a0dece399fb5405dda158971ae1Douglas GregorDecl *
744f722be4587a7a0dece399fb5405dda158971ae1Douglas GregorTemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) {
754f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor  assert(false && "Namespaces cannot be instantiated");
764f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor  return D;
774f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor}
784f722be4587a7a0dece399fb5405dda158971ae1Douglas Gregor
798dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
808dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  bool Invalid = false;
818dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  QualType T = D->getUnderlyingType();
828dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (T->isDependentType()) {
831eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor    T = SemaRef.InstantiateType(T, TemplateArgs,
841eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor                                D->getLocation(), D->getDeclName());
858dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (T.isNull()) {
868dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Invalid = true;
878dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      T = SemaRef.Context.IntTy;
888dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
898dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
908dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
918dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  // Create the new typedef
928dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  TypedefDecl *Typedef
938dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocation(),
948dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                          D->getIdentifier(), T);
958dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (Invalid)
968dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Typedef->setInvalidDecl();
978dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
986ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  Owner->addDecl(SemaRef.Context, Typedef);
998dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return Typedef;
1008dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
1018dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1023d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas GregorDecl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
1033d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  // Instantiate the type of the declaration
1043d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  QualType T = SemaRef.InstantiateType(D->getType(), TemplateArgs,
1053d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor                                       D->getTypeSpecStartLoc(),
1063d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor                                       D->getDeclName());
1073d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  if (T.isNull())
1083d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor    return 0;
1093d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor
1103d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  // Build the instantiataed declaration
1113d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  VarDecl *Var = VarDecl::Create(SemaRef.Context, Owner,
1123d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor                                 D->getLocation(), D->getIdentifier(),
1133d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor                                 T, D->getStorageClass(),
1143d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor                                 D->getTypeSpecStartLoc());
1153d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  Var->setThreadSpecified(D->isThreadSpecified());
1163d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  Var->setCXXDirectInitializer(D->hasCXXDirectInitializer());
1173d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  Var->setDeclaredInCondition(D->isDeclaredInCondition());
1183d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor
1193d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  // FIXME: In theory, we could have a previous declaration for
1203d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  // variables that are not static data members.
1213d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  bool Redeclaration = false;
122eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner  SemaRef.CheckVariableDeclaration(Var, 0, Redeclaration);
1236ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  Owner->addDecl(SemaRef.Context, Var);
1243d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor
1253d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  if (D->getInit()) {
1263d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor    OwningExprResult Init
1277e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor      = SemaRef.InstantiateExpr(D->getInit(), TemplateArgs);
1283d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor    if (Init.isInvalid())
1293d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor      Var->setInvalidDecl();
1303d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor    else
131b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner      SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var), move(Init),
1323d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor                                   D->hasCXXDirectInitializer());
1333d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  }
1343d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor
1353d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor  return Var;
1363d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor}
1373d7a12a50558c31d4351e923c15ab57688f4fdf2Douglas Gregor
1388dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
1398dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  bool Invalid = false;
1408dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  QualType T = D->getType();
1418dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (T->isDependentType())  {
1421eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor    T = SemaRef.InstantiateType(T, TemplateArgs,
1431eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor                                D->getLocation(), D->getDeclName());
1448dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (!T.isNull() && T->isFunctionType()) {
1458dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      // C++ [temp.arg.type]p3:
1468dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   If a declaration acquires a function type through a type
1478dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   dependent on a template-parameter and this causes a
1488dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   declaration that does not use the syntactic form of a
1498dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   function declarator to have function type, the program is
1508dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   ill-formed.
1518dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
1528dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        << T;
1538dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      T = QualType();
1548dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Invalid = true;
1558dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
1568dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
1578dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1588dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Expr *BitWidth = D->getBitWidth();
1598dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (Invalid)
1608dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    BitWidth = 0;
1618dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  else if (BitWidth) {
1628dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    OwningExprResult InstantiatedBitWidth
1637e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor      = SemaRef.InstantiateExpr(BitWidth, TemplateArgs);
1648dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (InstantiatedBitWidth.isInvalid()) {
1658dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Invalid = true;
1668dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      BitWidth = 0;
1678dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    } else
168e9146f2e9f1c4e281544e8c080934c72d41012caAnders Carlsson      BitWidth = InstantiatedBitWidth.takeAs<Expr>();
1698dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
1708dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1718dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(), T,
1728dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            cast<RecordDecl>(Owner),
1738dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            D->getLocation(),
1748dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            D->isMutable(),
1758dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            BitWidth,
1768dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            D->getAccess(),
1778dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            0);
1788dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (Field) {
1798dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (Invalid)
1808dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Field->setInvalidDecl();
1818dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1826ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor    Owner->addDecl(SemaRef.Context, Field);
1838dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
1848dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1858dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return Field;
1868dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
1878dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1888dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
1898dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Expr *AssertExpr = D->getAssertExpr();
1908dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1918dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  OwningExprResult InstantiatedAssertExpr
1927e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor    = SemaRef.InstantiateExpr(AssertExpr, TemplateArgs);
1938dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (InstantiatedAssertExpr.isInvalid())
1948dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    return 0;
1958dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1968dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  OwningExprResult Message = SemaRef.Clone(D->getMessage());
1978dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Decl *StaticAssert
198b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner    = SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
199b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner                                           move(InstantiatedAssertExpr),
200b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner                                           move(Message)).getAs<Decl>();
2018dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return StaticAssert;
2028dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
2038dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2048dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
2058dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner,
2068dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                    D->getLocation(), D->getIdentifier(),
2078dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                    /*PrevDecl=*/0);
20806c0fecd197fef21e265a41bca8dc5022de1f864Douglas Gregor  Enum->setAccess(D->getAccess());
2096ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  Owner->addDecl(SemaRef.Context, Enum);
2108dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Enum->startDefinition();
2118dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
212b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner  llvm::SmallVector<Sema::DeclPtrTy, 16> Enumerators;
2138dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2148dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  EnumConstantDecl *LastEnumConst = 0;
2156ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(SemaRef.Context),
2166ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor         ECEnd = D->enumerator_end(SemaRef.Context);
2178dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor       EC != ECEnd; ++EC) {
2188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // The specified value for the enumerator.
2198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    OwningExprResult Value = SemaRef.Owned((Expr *)0);
2208dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (Expr *UninstValue = EC->getInitExpr())
2217e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor      Value = SemaRef.InstantiateExpr(UninstValue, TemplateArgs);
2228dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2238dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // Drop the initial value and continue.
2248dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    bool isInvalid = false;
2258dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (Value.isInvalid()) {
2268dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Value = SemaRef.Owned((Expr *)0);
2278dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      isInvalid = true;
2288dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
2298dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2308dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    EnumConstantDecl *EnumConst
2318dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
2328dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                  EC->getLocation(), EC->getIdentifier(),
2338dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                  move(Value));
2348dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2358dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (isInvalid) {
2368dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      if (EnumConst)
2378dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        EnumConst->setInvalidDecl();
2388dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Enum->setInvalidDecl();
2398dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
2408dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2418dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (EnumConst) {
2426ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor      Enum->addDecl(SemaRef.Context, EnumConst);
243b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner      Enumerators.push_back(Sema::DeclPtrTy::make(EnumConst));
2448dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      LastEnumConst = EnumConst;
2458dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
2468dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
2478dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
248b28317a8e5e0e2953d1e5406d753d6c3c7f1e7d2Chris Lattner  SemaRef.ActOnEnumBody(Enum->getLocation(), Sema::DeclPtrTy::make(Enum),
2498dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                        &Enumerators[0], Enumerators.size());
2508dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2518dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return Enum;
2528dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
2538dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2546477b69cc93e0a0ff15036d60d604f3544da0f29Douglas GregorDecl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) {
2556477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor  assert(false && "EnumConstantDecls can only occur within EnumDecls.");
2566477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor  return 0;
2576477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor}
2586477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor
259d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas GregorDecl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
260d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  CXXRecordDecl *PrevDecl = 0;
261d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  if (D->isInjectedClassName())
262d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor    PrevDecl = cast<CXXRecordDecl>(Owner);
263d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
264d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  CXXRecordDecl *Record
265d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor    = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner,
266d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor                            D->getLocation(), D->getIdentifier(), PrevDecl);
267d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  Record->setImplicit(D->isImplicit());
268d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  Record->setAccess(D->getAccess());
269d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  if (!D->isInjectedClassName())
270d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor    Record->setInstantiationOfMemberClass(D);
271d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
2726ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  Owner->addDecl(SemaRef.Context, Record);
273d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  return Record;
274d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor}
275d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
2762dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas GregorDecl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
2772dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Only handle actual methods; we'll deal with constructors,
2782dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // destructors, etc. separately.
2792dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (D->getKind() != Decl::CXXMethod)
2802dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    return 0;
2812dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
28248dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor  Sema::LocalInstantiationScope Scope(SemaRef);
28348dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor
2845545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  llvm::SmallVector<ParmVarDecl *, 16> Params;
2855545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  QualType T = InstantiateFunctionType(D, Params);
2862dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (T.isNull())
2872dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    return 0;
2882dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2892dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Build the instantiated method declaration.
2902dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
2912dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  CXXMethodDecl *Method
2922dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
2932dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                            D->getDeclName(), T, D->isStatic(),
2942dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                            D->isInline());
2951eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  Method->setInstantiationOfMemberFunction(D);
2962dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2975545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // Attach the parameters
2985545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  for (unsigned P = 0; P < Params.size(); ++P)
2995545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Params[P]->setOwningFunction(Method);
3005545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  Method->setParams(SemaRef.Context, &Params[0], Params.size());
3015545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
3025545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (InitMethodInstantiation(Method, D))
3035545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Method->setInvalidDecl();
3042dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
3052dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  NamedDecl *PrevDecl
3062dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    = SemaRef.LookupQualifiedName(Owner, Method->getDeclName(),
3072dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                  Sema::LookupOrdinaryName, true);
3082dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // In C++, the previous declaration we find might be a tag type
3092dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // (class or enum). In this case, the new declaration will hide the
3102dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // tag type. Note that this does does not apply if we're declaring a
3112dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // typedef (C++ [dcl.typedef]p4).
3122dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
3132dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    PrevDecl = 0;
3142dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  bool Redeclaration = false;
3152dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  bool OverloadableAttrRequired = false;
316eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner  SemaRef.CheckFunctionDeclaration(Method, PrevDecl, Redeclaration,
317eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner                                   /*FIXME:*/OverloadableAttrRequired);
3182dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
3192dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (!Method->isInvalidDecl() || !PrevDecl)
3206ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor    Owner->addDecl(SemaRef.Context, Method);
3212dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  return Method;
3222dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor}
3232dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
324615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas GregorDecl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
32548dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor  Sema::LocalInstantiationScope Scope(SemaRef);
32648dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor
327615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  llvm::SmallVector<ParmVarDecl *, 16> Params;
328615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  QualType T = InstantiateFunctionType(D, Params);
329615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  if (T.isNull())
330615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor    return 0;
331615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor
332615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  // Build the instantiated method declaration.
333615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
334615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
335615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  DeclarationName Name
336615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor    = SemaRef.Context.DeclarationNames.getCXXConstructorName(ClassTy);
337615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  CXXConstructorDecl *Constructor
338615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor    = CXXConstructorDecl::Create(SemaRef.Context, Record, D->getLocation(),
339615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor                                 Name, T, D->isExplicit(), D->isInline(),
340615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor                                 false);
3411eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  Constructor->setInstantiationOfMemberFunction(D);
342615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor
343615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  // Attach the parameters
344615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  for (unsigned P = 0; P < Params.size(); ++P)
345615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor    Params[P]->setOwningFunction(Constructor);
346615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  Constructor->setParams(SemaRef.Context, &Params[0], Params.size());
347615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor
348615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  if (InitMethodInstantiation(Constructor, D))
349615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor    Constructor->setInvalidDecl();
350615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor
351615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  NamedDecl *PrevDecl
352615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor    = SemaRef.LookupQualifiedName(Owner, Name, Sema::LookupOrdinaryName, true);
353615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor
354615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  // In C++, the previous declaration we find might be a tag type
355615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  // (class or enum). In this case, the new declaration will hide the
356615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  // tag type. Note that this does does not apply if we're declaring a
357615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  // typedef (C++ [dcl.typedef]p4).
358615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
359615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor    PrevDecl = 0;
360615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  bool Redeclaration = false;
361615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  bool OverloadableAttrRequired = false;
362eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner  SemaRef.CheckFunctionDeclaration(Constructor, PrevDecl, Redeclaration,
363eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner                                   /*FIXME:*/OverloadableAttrRequired);
364615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor
365eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner  Owner->addDecl(SemaRef.Context, Constructor);
366615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor  return Constructor;
367615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor}
368615c5d4674355ba830b9978f462ca7a8c5d15f85Douglas Gregor
36903b2b07aaef3a585aec13048a33356c7f635de72Douglas GregorDecl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
37048dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor  Sema::LocalInstantiationScope Scope(SemaRef);
37148dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor
3725545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  llvm::SmallVector<ParmVarDecl *, 16> Params;
3735545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  QualType T = InstantiateFunctionType(D, Params);
37403b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  if (T.isNull())
37503b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor    return 0;
3765545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  assert(Params.size() == 0 && "Destructor with parameters?");
3775545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
37803b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  // Build the instantiated destructor declaration.
37903b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
38003b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
38103b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  CXXDestructorDecl *Destructor
38203b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor    = CXXDestructorDecl::Create(SemaRef.Context, Record,
38303b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor                                D->getLocation(),
38403b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor             SemaRef.Context.DeclarationNames.getCXXDestructorName(ClassTy),
38503b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor                                T, D->isInline(), false);
3861eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  Destructor->setInstantiationOfMemberFunction(D);
3875545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (InitMethodInstantiation(Destructor, D))
3885545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Destructor->setInvalidDecl();
38903b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor
39003b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  bool Redeclaration = false;
39103b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  bool OverloadableAttrRequired = false;
39203b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  NamedDecl *PrevDecl = 0;
393eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner  SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration,
394eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner                                   /*FIXME:*/OverloadableAttrRequired);
3956ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  Owner->addDecl(SemaRef.Context, Destructor);
39603b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  return Destructor;
39703b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor}
39803b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor
399bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas GregorDecl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
40048dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor  Sema::LocalInstantiationScope Scope(SemaRef);
40148dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor
402bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  llvm::SmallVector<ParmVarDecl *, 16> Params;
403bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  QualType T = InstantiateFunctionType(D, Params);
404bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  if (T.isNull())
405bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor    return 0;
406bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  assert(Params.size() == 0 && "Destructor with parameters?");
407bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor
408bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  // Build the instantiated conversion declaration.
409bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
410bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
411bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  QualType ConvTy
412bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor    = SemaRef.Context.getCanonicalType(T->getAsFunctionType()->getResultType());
413bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  CXXConversionDecl *Conversion
414bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor    = CXXConversionDecl::Create(SemaRef.Context, Record,
415bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor                                D->getLocation(),
416bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor         SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(ConvTy),
417bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor                                T, D->isInline(), D->isExplicit());
4181eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  Conversion->setInstantiationOfMemberFunction(D);
419bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  if (InitMethodInstantiation(Conversion, D))
420bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor    Conversion->setInvalidDecl();
421bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor
422bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  bool Redeclaration = false;
423bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  bool OverloadableAttrRequired = false;
424bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  NamedDecl *PrevDecl = 0;
425eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner  SemaRef.CheckFunctionDeclaration(Conversion, PrevDecl, Redeclaration,
426eaaebc7cf10dc1a2016183a262ad3256bc468759Chris Lattner                                   /*FIXME:*/OverloadableAttrRequired);
4276ab3524f72a6e64aa04973fa9433b5559abb3525Douglas Gregor  Owner->addDecl(SemaRef.Context, Conversion);
428bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor  return Conversion;
429bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor}
430bb969ed4193e2eadabfaa0dfd0b94312b6146349Douglas Gregor
4316477b69cc93e0a0ff15036d60d604f3544da0f29Douglas GregorParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
4322dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs,
4337e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                                           D->getLocation(), D->getDeclName());
4342dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (OrigT.isNull())
4352dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    return 0;
4362dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
4372dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  QualType T = SemaRef.adjustParameterType(OrigT);
4382dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
4392dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (D->getDefaultArg()) {
4402dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    // FIXME: Leave a marker for "uninstantiated" default
4412dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    // arguments. They only get instantiated on demand at the call
4422dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    // site.
4432dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    unsigned DiagID = SemaRef.Diags.getCustomDiagID(Diagnostic::Warning,
4442dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor        "sorry, dropping default argument during template instantiation");
4452dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    SemaRef.Diag(D->getDefaultArg()->getSourceRange().getBegin(), DiagID)
4462dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor      << D->getDefaultArg()->getSourceRange();
4472dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  }
4482dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
4492dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Allocate the parameter
4502dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  ParmVarDecl *Param = 0;
4512dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (T == OrigT)
4522dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Param = ParmVarDecl::Create(SemaRef.Context, Owner, D->getLocation(),
4532dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                D->getIdentifier(), T, D->getStorageClass(),
4542dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                0);
4552dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  else
4562dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Param = OriginalParmVarDecl::Create(SemaRef.Context, Owner,
4572dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                        D->getLocation(), D->getIdentifier(),
4582dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                        T, OrigT, D->getStorageClass(), 0);
4592dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
4602dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Note: we don't try to instantiate function parameters until after
4612dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // we've instantiated the function's type. Therefore, we don't have
4622dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // to check for 'void' parameter types here.
46348dd19b19ddb9e105f8cf0bf6f0732ca4e6a385bDouglas Gregor  SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param);
4642dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  return Param;
4652dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor}
4662dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
4672dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas GregorDecl *
4682dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas GregorTemplateDeclInstantiator::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
4692dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Since parameter types can decay either before or after
4702dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // instantiation, we simply treat OriginalParmVarDecls as
4712dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // ParmVarDecls the same way, and create one or the other depending
4722dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // on what happens after template instantiation.
4732dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  return VisitParmVarDecl(D);
4742dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor}
4752dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
4768dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *Sema::InstantiateDecl(Decl *D, DeclContext *Owner,
4777e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor                            const TemplateArgumentList &TemplateArgs) {
4787e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
4798dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return Instantiator.Visit(D);
4808dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
4818dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
4825545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \brief Instantiates the type of the given function, including
4835545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// instantiating all of the function parameters.
4845545e166a956a20d7a6b58408e251a1119025485Douglas Gregor///
4855545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \param D The function that we will be instantiated
4865545e166a956a20d7a6b58408e251a1119025485Douglas Gregor///
4875545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \param Params the instantiated parameter declarations
4885545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
4895545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \returns the instantiated function's type if successfull, a NULL
4905545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// type if there was an error.
4915545e166a956a20d7a6b58408e251a1119025485Douglas GregorQualType
4925545e166a956a20d7a6b58408e251a1119025485Douglas GregorTemplateDeclInstantiator::InstantiateFunctionType(FunctionDecl *D,
4935545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                              llvm::SmallVectorImpl<ParmVarDecl *> &Params) {
4945545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  bool InvalidDecl = false;
4955545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
4965545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // Instantiate the function parameters
4977e06390f8a60440d6fc5f0e633acdc2edd8ee924Douglas Gregor  TemplateDeclInstantiator ParamInstantiator(SemaRef, 0, TemplateArgs);
4985545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  llvm::SmallVector<QualType, 16> ParamTys;
4995545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  for (FunctionDecl::param_iterator P = D->param_begin(),
5005545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                 PEnd = D->param_end();
5015545e166a956a20d7a6b58408e251a1119025485Douglas Gregor       P != PEnd; ++P) {
5026477b69cc93e0a0ff15036d60d604f3544da0f29Douglas Gregor    if (ParmVarDecl *PInst = ParamInstantiator.VisitParmVarDecl(*P)) {
5035545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      if (PInst->getType()->isVoidType()) {
5045545e166a956a20d7a6b58408e251a1119025485Douglas Gregor        SemaRef.Diag(PInst->getLocation(), diag::err_param_with_void_type);
5055545e166a956a20d7a6b58408e251a1119025485Douglas Gregor        PInst->setInvalidDecl();
5065545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      }
5075545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      else if (SemaRef.RequireNonAbstractType(PInst->getLocation(),
5085545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                              PInst->getType(),
5095545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                              diag::err_abstract_type_in_decl,
5108211effbd3abc5948a5d6924c87e72323016a376Anders Carlsson                                              Sema::AbstractParamType))
5115545e166a956a20d7a6b58408e251a1119025485Douglas Gregor        PInst->setInvalidDecl();
5125545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
5135545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      Params.push_back(PInst);
5145545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      ParamTys.push_back(PInst->getType());
5155545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
5165545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      if (PInst->isInvalidDecl())
5175545e166a956a20d7a6b58408e251a1119025485Douglas Gregor        InvalidDecl = true;
5185545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    } else
5195545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      InvalidDecl = true;
5205545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  }
5215545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
5225545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // FIXME: Deallocate dead declarations.
5235545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (InvalidDecl)
5245545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    return QualType();
5255545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
5265545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  const FunctionProtoType *Proto = D->getType()->getAsFunctionProtoType();
5275545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  assert(Proto && "Missing prototype?");
5285545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  QualType ResultType
5291eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor    = SemaRef.InstantiateType(Proto->getResultType(), TemplateArgs,
5305545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                              D->getLocation(), D->getDeclName());
5315545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (ResultType.isNull())
5325545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    return QualType();
5335545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
5345545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  return SemaRef.BuildFunctionType(ResultType, &ParamTys[0], ParamTys.size(),
5355545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                   Proto->isVariadic(), Proto->getTypeQuals(),
5365545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                   D->getLocation(), D->getDeclName());
5375545e166a956a20d7a6b58408e251a1119025485Douglas Gregor}
5385545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
5395545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \brief Initializes common fields of an instantiated method
5405545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// declaration (New) from the corresponding fields of its template
5415545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// (Tmpl).
5425545e166a956a20d7a6b58408e251a1119025485Douglas Gregor///
5435545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \returns true if there was an error
5445545e166a956a20d7a6b58408e251a1119025485Douglas Gregorbool
5455545e166a956a20d7a6b58408e251a1119025485Douglas GregorTemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
5465545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                                  CXXMethodDecl *Tmpl) {
5475545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
5485545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  New->setAccess(Tmpl->getAccess());
5495545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (Tmpl->isVirtual()) {
5505545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    New->setVirtual();
5515545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Record->setAggregate(false);
5525545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Record->setPOD(false);
5535545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Record->setPolymorphic(true);
5545545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  }
5555545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (Tmpl->isDeleted())
5565545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    New->setDeleted();
5575545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (Tmpl->isPure()) {
5585545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    New->setPure();
5595545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Record->setAbstract(true);
5605545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  }
5615545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
5625545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // FIXME: attributes
5635545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // FIXME: New needs a pointer to Tmpl
5645545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  return false;
5655545e166a956a20d7a6b58408e251a1119025485Douglas Gregor}
566a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor
567a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor/// \brief Instantiate the definition of the given function from its
568a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor/// template.
569a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor///
570a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor/// \param Function the already-instantiated declaration of a
571a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor/// function.
572a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregorvoid Sema::InstantiateFunctionDefinition(FunctionDecl *Function) {
5731eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  // FIXME: make this work for function template specializations, too.
5741eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor
5751eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  // Find the function body that we'll be substituting.
5761eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  const FunctionDecl *PatternDecl
5771eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor    = Function->getInstantiatedFromMemberFunction();
5781eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  Stmt *Pattern = 0;
5791eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  if (PatternDecl)
5801eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor    Pattern = PatternDecl->getBody(Context, PatternDecl);
5811eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor
5821eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  if (!Pattern)
5831eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor    return;
5841eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor
5851eee0e753fb390b04848846e837714ec774b7bfdDouglas Gregor  // FIXME: instantiate the pattern
586a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor}
587a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor
588a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor/// \brief Instantiate the definition of the given variable from its
589a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor/// template.
590a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor///
591a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor/// \param Var the already-instantiated declaration of a variable.
592a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregorvoid Sema::InstantiateVariableDefinition(VarDecl *Var) {
593a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor  // FIXME: Implement this!
594a58861f6490780baec50689e06ca65f7438b85dcDouglas Gregor}
595