From 1d116976b4d6357b2c3be099fbf5d718b1d5cea7 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Mon, 12 Oct 2009 21:16:22 +0000 Subject: [PATCH] Store the key function of a record decl inside CGRecordLayout. llvm-svn: 83900 --- clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 29 ++++++++++++++++++++- clang/lib/CodeGen/CodeGenTypes.h | 15 +++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index d26c7721da27..7baf69d87689 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -326,6 +326,31 @@ void CGRecordLayoutBuilder::CheckForMemberPointer(const FieldDecl *FD) { } +static const CXXMethodDecl *GetKeyFunction(const RecordDecl *D) { + const CXXRecordDecl *RD = dyn_cast(D); + if (!RD || !RD->isDynamicClass()) + return 0; + + for (CXXRecordDecl::method_iterator I = RD->method_begin(), + E = RD->method_end(); I != E; ++I) { + const CXXMethodDecl *MD = *I; + + if (!MD->isVirtual()) + continue; + + if (MD->isPure()) + continue; + + if (MD->getBody()) + continue; + + // We found it. + return MD; + } + + return 0; +} + CGRecordLayout * CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types, const RecordDecl *D) { @@ -355,5 +380,7 @@ CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types, Types.addBitFieldInfo(Info.FD, Info.FieldNo, Info.Start, Info.Size); } - return new CGRecordLayout(Ty, Builder.ContainsMemberPointer); + const CXXMethodDecl *KeyFunction = GetKeyFunction(D); + + return new CGRecordLayout(Ty, Builder.ContainsMemberPointer, KeyFunction); } diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index ad71e0ad053c..a92a019b988e 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -61,9 +61,17 @@ namespace CodeGen { /// is a member pointer, or a struct that contains a member pointer. bool ContainsMemberPointer; + /// KeyFunction - The key function of the record layout (if one exists), + /// which is the first non-pure virtual function that is not inline at the + /// point of class definition. + /// See http://www.codesourcery.com/public/cxx-abi/abi.html#vague-vtable. + const CXXMethodDecl *KeyFunction; + public: - CGRecordLayout(const llvm::Type *T, bool ContainsMemberPointer) - : LLVMType(T), ContainsMemberPointer(ContainsMemberPointer) { } + CGRecordLayout(const llvm::Type *T, bool ContainsMemberPointer, + const CXXMethodDecl *KeyFunction) + : LLVMType(T), ContainsMemberPointer(ContainsMemberPointer), + KeyFunction(KeyFunction) { } /// getLLVMType - Return llvm type associated with this record. const llvm::Type *getLLVMType() const { @@ -74,6 +82,9 @@ namespace CodeGen { return ContainsMemberPointer; } + const CXXMethodDecl *getKeyFunction() const { + return KeyFunction; + } }; /// CodeGenTypes - This class organizes the cross-module state that is used