From: Douglas Gregor Date: Tue, 24 Mar 2009 00:15:49 +0000 (+0000) Subject: Template instantiation for destructors. This is somewhat repetitive; X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=03b2b07aaef3a585aec13048a33356c7f635de72;p=clang Template instantiation for destructors. This is somewhat repetitive; eliminating the duplication is next on the list. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67579 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index d8e526c602..d924713349 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -44,9 +44,9 @@ namespace { Decl *VisitStaticAssertDecl(StaticAssertDecl *D); Decl *VisitEnumDecl(EnumDecl *D); Decl *VisitCXXMethodDecl(CXXMethodDecl *D); + Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); Decl *VisitParmVarDecl(ParmVarDecl *D); Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D); - // Base case. FIXME: Remove once we can instantiate everything. Decl *VisitDecl(Decl *) { return 0; @@ -265,6 +265,48 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { return Method; } +Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) { + QualType T = SemaRef.InstantiateType(D->getType(), TemplateArgs, + NumTemplateArgs, D->getLocation(), + D->getDeclName()); + if (T.isNull()) + return 0; + + // Build the instantiated destructor declaration. + CXXRecordDecl *Record = cast(Owner); + QualType ClassTy = SemaRef.Context.getTypeDeclType(Record); + CXXDestructorDecl *Destructor + = CXXDestructorDecl::Create(SemaRef.Context, Record, + D->getLocation(), + SemaRef.Context.DeclarationNames.getCXXDestructorName(ClassTy), + T, D->isInline(), false); + + Destructor->setAccess(D->getAccess()); + // FIXME: Duplicates some logic in ActOnFunctionDeclarator, + // VisitCXXDestructorDecl. + if (D->isVirtual()) { + Destructor->setVirtual(); + Record->setAggregate(false); + Record->setPOD(false); + Record->setPolymorphic(true); + } + if (D->isDeleted()) + Destructor->setDeleted(); + if (D->isPure()) { + Destructor->setPure(); + Record->setAbstract(true); + } + + bool Redeclaration = false; + bool OverloadableAttrRequired = false; + NamedDecl *PrevDecl = 0; + if (SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration, + /*FIXME:*/OverloadableAttrRequired)) + Destructor->setInvalidDecl(); + Owner->addDecl(Destructor); + return Destructor; +} + Decl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) { QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs, NumTemplateArgs, D->getLocation(), diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp index 2eb2b7a88c..a6a6235465 100644 --- a/test/SemaTemplate/instantiate-method.cpp +++ b/test/SemaTemplate/instantiate-method.cpp @@ -1,5 +1,4 @@ // RUN: clang -fsyntax-only -verify %s - template class X { public: @@ -41,3 +40,12 @@ void test_ovl(Overloading *oil, int i, long l) { void test_ovl_bad() { Overloading off; // expected-note{{in instantiation of template class 'class Overloading' requested here}} } + +template +class HasDestructor { + virtual ~HasDestructor() = 0; +}; + +int i = sizeof(HasDestructor); // FIXME: forces instantiation, but + // the code below should probably instantiate by itself. +int abstract_destructor[__is_abstract(HasDestructor)? 1 : -1];