SemaTemplateInstantiateDecl.cpp revision 5545e166a956a20d7a6b58408e251a1119025485
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
238dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    : public DeclVisitor<TemplateDeclInstantiator, Decl *>
248dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  {
258dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Sema &SemaRef;
268dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    DeclContext *Owner;
278dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    const TemplateArgument *TemplateArgs;
288dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    unsigned NumTemplateArgs;
298dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
308dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  public:
318dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    typedef Sema::OwningExprResult OwningExprResult;
328dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
338dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
348dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                             const TemplateArgument *TemplateArgs,
358dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                             unsigned NumTemplateArgs)
368dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      : SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs),
378dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        NumTemplateArgs(NumTemplateArgs) { }
388dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
398dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // FIXME: Once we get closer to completion, replace these
408dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // manually-written declarations with automatically-generated ones
418dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // from clang/AST/DeclNodes.def.
428dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitTypedefDecl(TypedefDecl *D);
438dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitFieldDecl(FieldDecl *D);
448dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
458dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitEnumDecl(EnumDecl *D);
462dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
4703b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor    Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
482dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Decl *VisitParmVarDecl(ParmVarDecl *D);
492dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
505545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
518dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // Base case. FIXME: Remove once we can instantiate everything.
528dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Decl *VisitDecl(Decl *) {
538dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      return 0;
548dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
555545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
565545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    // Helper functions for instantiating methods.
575545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    QualType InstantiateFunctionType(FunctionDecl *D,
585545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                             llvm::SmallVectorImpl<ParmVarDecl *> &Params);
595545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
608dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  };
618dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
628dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
638dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
648dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  bool Invalid = false;
658dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  QualType T = D->getUnderlyingType();
668dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (T->isDependentType()) {
678dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
688dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                D->getLocation(),
698dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                D->getDeclName());
708dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (T.isNull()) {
718dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Invalid = true;
728dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      T = SemaRef.Context.IntTy;
738dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
748dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
758dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
768dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  // Create the new typedef
778dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  TypedefDecl *Typedef
788dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocation(),
798dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                          D->getIdentifier(), T);
808dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (Invalid)
818dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Typedef->setInvalidDecl();
828dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
838dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Owner->addDecl(Typedef);
848dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return Typedef;
858dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
868dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
878dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
888dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  bool Invalid = false;
898dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  QualType T = D->getType();
908dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (T->isDependentType())  {
918dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
928dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                D->getLocation(),
938dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                D->getDeclName());
948dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (!T.isNull() && T->isFunctionType()) {
958dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      // C++ [temp.arg.type]p3:
968dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   If a declaration acquires a function type through a type
978dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   dependent on a template-parameter and this causes a
988dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   declaration that does not use the syntactic form of a
998dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   function declarator to have function type, the program is
1008dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      //   ill-formed.
1018dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
1028dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        << T;
1038dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      T = QualType();
1048dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Invalid = true;
1058dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
1068dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
1078dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1088dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Expr *BitWidth = D->getBitWidth();
1098dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (Invalid)
1108dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    BitWidth = 0;
1118dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  else if (BitWidth) {
1128dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    OwningExprResult InstantiatedBitWidth
1138dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      = SemaRef.InstantiateExpr(BitWidth, TemplateArgs, NumTemplateArgs);
1148dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (InstantiatedBitWidth.isInvalid()) {
1158dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Invalid = true;
1168dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      BitWidth = 0;
1178dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    } else
1188dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      BitWidth = (Expr *)InstantiatedBitWidth.release();
1198dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
1208dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1218dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(), T,
1228dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            cast<RecordDecl>(Owner),
1238dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            D->getLocation(),
1248dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            D->isMutable(),
1258dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            BitWidth,
1268dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            D->getAccess(),
1278dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                            0);
1288dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (Field) {
1298dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (Invalid)
1308dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Field->setInvalidDecl();
1318dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1328dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    Owner->addDecl(Field);
1338dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
1348dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1358dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return Field;
1368dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
1378dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1388dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
1398dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Expr *AssertExpr = D->getAssertExpr();
1408dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1418dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  OwningExprResult InstantiatedAssertExpr
1428dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    = SemaRef.InstantiateExpr(AssertExpr, TemplateArgs, NumTemplateArgs);
1438dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  if (InstantiatedAssertExpr.isInvalid())
1448dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    return 0;
1458dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1468dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  OwningExprResult Message = SemaRef.Clone(D->getMessage());
1478dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Decl *StaticAssert
1488dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    = (Decl *)SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
1498dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                                move(InstantiatedAssertExpr),
1508dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                                   move(Message));
1518dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return StaticAssert;
1528dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
1538dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1548dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
1558dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner,
1568dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                    D->getLocation(), D->getIdentifier(),
1578dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                    /*PrevDecl=*/0);
1588dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Owner->addDecl(Enum);
1598dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  Enum->startDefinition();
1608dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1618dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  llvm::SmallVector<Sema::DeclTy *, 16> Enumerators;
1628dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1638dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  EnumConstantDecl *LastEnumConst = 0;
1648dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
1658dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor         ECEnd = D->enumerator_end();
1668dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor       EC != ECEnd; ++EC) {
1678dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // The specified value for the enumerator.
1688dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    OwningExprResult Value = SemaRef.Owned((Expr *)0);
1698dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (Expr *UninstValue = EC->getInitExpr())
1708dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Value = SemaRef.InstantiateExpr(UninstValue,
1718dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                      TemplateArgs, NumTemplateArgs);
1728dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1738dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    // Drop the initial value and continue.
1748dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    bool isInvalid = false;
1758dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (Value.isInvalid()) {
1768dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Value = SemaRef.Owned((Expr *)0);
1778dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      isInvalid = true;
1788dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
1798dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1808dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    EnumConstantDecl *EnumConst
1818dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
1828dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                  EC->getLocation(), EC->getIdentifier(),
1838dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                  move(Value));
1848dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1858dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (isInvalid) {
1868dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      if (EnumConst)
1878dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor        EnumConst->setInvalidDecl();
1888dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Enum->setInvalidDecl();
1898dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
1908dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1918dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    if (EnumConst) {
1928dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Enum->addDecl(EnumConst);
1938dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      Enumerators.push_back(EnumConst);
1948dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor      LastEnumConst = EnumConst;
1958dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor    }
1968dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  }
1978dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
1988dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  SemaRef.ActOnEnumBody(Enum->getLocation(), Enum,
1998dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                        &Enumerators[0], Enumerators.size());
2008dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2018dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return Enum;
2028dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
2038dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
2042dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas GregorDecl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
2052dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Only handle actual methods; we'll deal with constructors,
2062dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // destructors, etc. separately.
2072dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (D->getKind() != Decl::CXXMethod)
2082dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    return 0;
2092dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2105545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  llvm::SmallVector<ParmVarDecl *, 16> Params;
2115545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  QualType T = InstantiateFunctionType(D, Params);
2122dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (T.isNull())
2132dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    return 0;
2142dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2152dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Build the instantiated method declaration.
2162dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
2172dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  CXXMethodDecl *Method
2182dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
2192dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                            D->getDeclName(), T, D->isStatic(),
2202dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                            D->isInline());
2212dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2225545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // Attach the parameters
2235545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  for (unsigned P = 0; P < Params.size(); ++P)
2245545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Params[P]->setOwningFunction(Method);
2255545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  Method->setParams(SemaRef.Context, &Params[0], Params.size());
2265545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
2275545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (InitMethodInstantiation(Method, D))
2285545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Method->setInvalidDecl();
2292dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2302dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  NamedDecl *PrevDecl
2312dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    = SemaRef.LookupQualifiedName(Owner, Method->getDeclName(),
2322dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                  Sema::LookupOrdinaryName, true);
2332dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // In C++, the previous declaration we find might be a tag type
2342dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // (class or enum). In this case, the new declaration will hide the
2352dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // tag type. Note that this does does not apply if we're declaring a
2362dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // typedef (C++ [dcl.typedef]p4).
2372dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
2382dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    PrevDecl = 0;
2392dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  bool Redeclaration = false;
2402dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  bool OverloadableAttrRequired = false;
2412dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (SemaRef.CheckFunctionDeclaration(Method, PrevDecl, Redeclaration,
2422dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                       /*FIXME:*/OverloadableAttrRequired))
2432dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Method->setInvalidDecl();
2442dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2452dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (!Method->isInvalidDecl() || !PrevDecl)
2462dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Owner->addDecl(Method);
2472dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  return Method;
2482dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor}
2492dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
25003b2b07aaef3a585aec13048a33356c7f635de72Douglas GregorDecl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
2515545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  llvm::SmallVector<ParmVarDecl *, 16> Params;
2525545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  QualType T = InstantiateFunctionType(D, Params);
25303b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  if (T.isNull())
25403b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor    return 0;
2555545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  assert(Params.size() == 0 && "Destructor with parameters?");
2565545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
25703b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  // Build the instantiated destructor declaration.
25803b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
25903b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
26003b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  CXXDestructorDecl *Destructor
26103b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor    = CXXDestructorDecl::Create(SemaRef.Context, Record,
26203b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor                                D->getLocation(),
26303b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor             SemaRef.Context.DeclarationNames.getCXXDestructorName(ClassTy),
26403b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor                                T, D->isInline(), false);
2655545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (InitMethodInstantiation(Destructor, D))
2665545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Destructor->setInvalidDecl();
26703b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor
26803b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  bool Redeclaration = false;
26903b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  bool OverloadableAttrRequired = false;
27003b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  NamedDecl *PrevDecl = 0;
27103b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  if (SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration,
27203b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor                                       /*FIXME:*/OverloadableAttrRequired))
27303b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor    Destructor->setInvalidDecl();
27403b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  Owner->addDecl(Destructor);
27503b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor  return Destructor;
27603b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor}
27703b2b07aaef3a585aec13048a33356c7f635de72Douglas Gregor
2782dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas GregorDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
2792dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs,
2802dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                           NumTemplateArgs, D->getLocation(),
2812dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                           D->getDeclName());
2822dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (OrigT.isNull())
2832dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    return 0;
2842dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2852dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  QualType T = SemaRef.adjustParameterType(OrigT);
2862dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2872dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (D->getDefaultArg()) {
2882dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    // FIXME: Leave a marker for "uninstantiated" default
2892dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    // arguments. They only get instantiated on demand at the call
2902dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    // site.
2912dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    unsigned DiagID = SemaRef.Diags.getCustomDiagID(Diagnostic::Warning,
2922dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor        "sorry, dropping default argument during template instantiation");
2932dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    SemaRef.Diag(D->getDefaultArg()->getSourceRange().getBegin(), DiagID)
2942dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor      << D->getDefaultArg()->getSourceRange();
2952dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  }
2962dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
2972dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Allocate the parameter
2982dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  ParmVarDecl *Param = 0;
2992dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  if (T == OrigT)
3002dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Param = ParmVarDecl::Create(SemaRef.Context, Owner, D->getLocation(),
3012dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                D->getIdentifier(), T, D->getStorageClass(),
3022dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                0);
3032dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  else
3042dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor    Param = OriginalParmVarDecl::Create(SemaRef.Context, Owner,
3052dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                        D->getLocation(), D->getIdentifier(),
3062dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor                                        T, OrigT, D->getStorageClass(), 0);
3072dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
3082dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Note: we don't try to instantiate function parameters until after
3092dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // we've instantiated the function's type. Therefore, we don't have
3102dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // to check for 'void' parameter types here.
3112dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  return Param;
3122dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor}
3132dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
3142dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas GregorDecl *
3152dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas GregorTemplateDeclInstantiator::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
3162dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // Since parameter types can decay either before or after
3172dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // instantiation, we simply treat OriginalParmVarDecls as
3182dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // ParmVarDecls the same way, and create one or the other depending
3192dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  // on what happens after template instantiation.
3202dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor  return VisitParmVarDecl(D);
3212dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor}
3222dc0e64e57b2a1786fa53a7dbd1d5c8e255eadb0Douglas Gregor
3238dbc2694424b4e842b1d5ea39744a137b58600c3Douglas GregorDecl *Sema::InstantiateDecl(Decl *D, DeclContext *Owner,
3248dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                            const TemplateArgument *TemplateArgs,
3258dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                            unsigned NumTemplateArgs) {
3268dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs,
3278dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor                                        NumTemplateArgs);
3288dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor  return Instantiator.Visit(D);
3298dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor}
3308dbc2694424b4e842b1d5ea39744a137b58600c3Douglas Gregor
3315545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \brief Instantiates the type of the given function, including
3325545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// instantiating all of the function parameters.
3335545e166a956a20d7a6b58408e251a1119025485Douglas Gregor///
3345545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \param D The function that we will be instantiated
3355545e166a956a20d7a6b58408e251a1119025485Douglas Gregor///
3365545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \param Params the instantiated parameter declarations
3375545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
3385545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \returns the instantiated function's type if successfull, a NULL
3395545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// type if there was an error.
3405545e166a956a20d7a6b58408e251a1119025485Douglas GregorQualType
3415545e166a956a20d7a6b58408e251a1119025485Douglas GregorTemplateDeclInstantiator::InstantiateFunctionType(FunctionDecl *D,
3425545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                              llvm::SmallVectorImpl<ParmVarDecl *> &Params) {
3435545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  bool InvalidDecl = false;
3445545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
3455545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // Instantiate the function parameters
3465545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  TemplateDeclInstantiator ParamInstantiator(SemaRef, 0,
3475545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                             TemplateArgs, NumTemplateArgs);
3485545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  llvm::SmallVector<QualType, 16> ParamTys;
3495545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  for (FunctionDecl::param_iterator P = D->param_begin(),
3505545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                 PEnd = D->param_end();
3515545e166a956a20d7a6b58408e251a1119025485Douglas Gregor       P != PEnd; ++P) {
3525545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    if (ParmVarDecl *PInst = (ParmVarDecl *)ParamInstantiator.Visit(*P)) {
3535545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      if (PInst->getType()->isVoidType()) {
3545545e166a956a20d7a6b58408e251a1119025485Douglas Gregor        SemaRef.Diag(PInst->getLocation(), diag::err_param_with_void_type);
3555545e166a956a20d7a6b58408e251a1119025485Douglas Gregor        PInst->setInvalidDecl();
3565545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      }
3575545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      else if (SemaRef.RequireNonAbstractType(PInst->getLocation(),
3585545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                              PInst->getType(),
3595545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                              diag::err_abstract_type_in_decl,
3605545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                              1 /* parameter type */))
3615545e166a956a20d7a6b58408e251a1119025485Douglas Gregor        PInst->setInvalidDecl();
3625545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
3635545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      Params.push_back(PInst);
3645545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      ParamTys.push_back(PInst->getType());
3655545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
3665545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      if (PInst->isInvalidDecl())
3675545e166a956a20d7a6b58408e251a1119025485Douglas Gregor        InvalidDecl = true;
3685545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    } else
3695545e166a956a20d7a6b58408e251a1119025485Douglas Gregor      InvalidDecl = true;
3705545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  }
3715545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
3725545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // FIXME: Deallocate dead declarations.
3735545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (InvalidDecl)
3745545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    return QualType();
3755545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
3765545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  const FunctionProtoType *Proto = D->getType()->getAsFunctionProtoType();
3775545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  assert(Proto && "Missing prototype?");
3785545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  QualType ResultType
3795545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    = SemaRef.InstantiateType(Proto->getResultType(),
3805545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                              TemplateArgs, NumTemplateArgs,
3815545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                              D->getLocation(), D->getDeclName());
3825545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (ResultType.isNull())
3835545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    return QualType();
3845545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
3855545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  return SemaRef.BuildFunctionType(ResultType, &ParamTys[0], ParamTys.size(),
3865545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                   Proto->isVariadic(), Proto->getTypeQuals(),
3875545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                   D->getLocation(), D->getDeclName());
3885545e166a956a20d7a6b58408e251a1119025485Douglas Gregor}
3895545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
3905545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \brief Initializes common fields of an instantiated method
3915545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// declaration (New) from the corresponding fields of its template
3925545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// (Tmpl).
3935545e166a956a20d7a6b58408e251a1119025485Douglas Gregor///
3945545e166a956a20d7a6b58408e251a1119025485Douglas Gregor/// \returns true if there was an error
3955545e166a956a20d7a6b58408e251a1119025485Douglas Gregorbool
3965545e166a956a20d7a6b58408e251a1119025485Douglas GregorTemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
3975545e166a956a20d7a6b58408e251a1119025485Douglas Gregor                                                  CXXMethodDecl *Tmpl) {
3985545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
3995545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  New->setAccess(Tmpl->getAccess());
4005545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (Tmpl->isVirtual()) {
4015545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    New->setVirtual();
4025545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Record->setAggregate(false);
4035545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Record->setPOD(false);
4045545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Record->setPolymorphic(true);
4055545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  }
4065545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (Tmpl->isDeleted())
4075545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    New->setDeleted();
4085545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  if (Tmpl->isPure()) {
4095545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    New->setPure();
4105545e166a956a20d7a6b58408e251a1119025485Douglas Gregor    Record->setAbstract(true);
4115545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  }
4125545e166a956a20d7a6b58408e251a1119025485Douglas Gregor
4135545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // FIXME: attributes
4145545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  // FIXME: New needs a pointer to Tmpl
4155545e166a956a20d7a6b58408e251a1119025485Douglas Gregor  return false;
4165545e166a956a20d7a6b58408e251a1119025485Douglas Gregor}
417