summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-12-02 17:15:43 +0000
committerAnders Carlsson <andersca@mac.com>2009-12-02 17:15:43 +0000
commitf98849eb8aa991668e5c47eeb7b2899772af3810 (patch)
tree11966ec08d59ff029272b1a82e0237c433a1589d /clang/lib/Sema/SemaDeclCXX.cpp
parentfffbc0c5d92deee5304a4e0b560e15f36f07b944 (diff)
downloadbcm5719-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.cpp37
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.
+}
OpenPOWER on IntegriCloud