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