diff options
author | Anders Carlsson <andersca@mac.com> | 2009-12-02 17:15:43 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-12-02 17:15:43 +0000 |
commit | f98849eb8aa991668e5c47eeb7b2899772af3810 (patch) | |
tree | 11966ec08d59ff029272b1a82e0237c433a1589d /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | fffbc0c5d92deee5304a4e0b560e15f36f07b944 (diff) | |
download | bcm5719-llvm-f98849eb8aa991668e5c47eeb7b2899772af3810.tar.gz bcm5719-llvm-f98849eb8aa991668e5c47eeb7b2899772af3810.zip |
In Sema, whenever we think that a function is going to cause a vtable to be generated, we mark any virtual implicit member functions as referenced.
llvm-svn: 90327
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7df86ee66c3..4db769bd91a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -15,6 +15,7 @@ #include "Lookup.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/RecordLayout.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/TypeOrdering.h" @@ -2172,7 +2173,6 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { ClassDecl->addDecl(Destructor); AddOverriddenMethods(ClassDecl, Destructor); - CheckDestructor(Destructor, false); } } @@ -2371,7 +2371,7 @@ void Sema::CheckConstructor(CXXConstructorDecl *Constructor) { /// CheckDestructor - Checks a fully-formed destructor for well-formedness, /// issuing any diagnostics required. Returns true on error. -bool Sema::CheckDestructor(CXXDestructorDecl *Destructor, bool Diagnose) { +bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) { CXXRecordDecl *RD = Destructor->getParent(); if (Destructor->isVirtual()) { @@ -2386,7 +2386,7 @@ bool Sema::CheckDestructor(CXXDestructorDecl *Destructor, bool Diagnose) { FunctionDecl *OperatorDelete = 0; DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Delete); - if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete, Diagnose)) + if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete)) return true; Destructor->setOperatorDelete(OperatorDelete); @@ -3083,7 +3083,8 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, } else { Constructor->setUsed(); } - return; + + MaybeMarkVirtualImplicitMembersReferenced(CurrentLocation, Constructor); } void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, @@ -4994,3 +4995,31 @@ Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) { VD->setDeclaredInCondition(true); return Dcl; } + +void Sema::MaybeMarkVirtualImplicitMembersReferenced(SourceLocation Loc, + CXXMethodDecl *MD) { + // Ignore dependent types. + if (MD->isDependentContext()) + return; + + CXXRecordDecl *RD = MD->getParent(); + const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); + const CXXMethodDecl *KeyFunction = Layout.getKeyFunction(); + + if (!KeyFunction) { + // This record does not have a key function, so we assume that the vtable + // will be emitted when it's used by the constructor. + if (!isa<CXXConstructorDecl>(MD)) + return; + } else if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl()) { + // We don't have the right key function. + return; + } + + if (CXXDestructorDecl *Dtor = RD->getDestructor(Context)) { + if (Dtor->isImplicit() && Dtor->isVirtual()) + MarkDeclarationReferenced(Loc, Dtor); + } + + // FIXME: Need to handle the virtual assignment operator here too. +} |