diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 30 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 43 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVtable.h | 12 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 16 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.h | 16 |
5 files changed, 50 insertions, 67 deletions
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp index edf19f78c87..1a9bc391709 100644 --- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -330,32 +330,6 @@ void CGRecordLayoutBuilder::CheckForMemberPointer(const FieldDecl *FD) { } -static const CXXMethodDecl *GetKeyFunction(const RecordDecl *D) { - const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(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; - - const FunctionDecl *fn; - if (MD->getBody(fn) && !fn->isOutOfLine()) - continue; - - // We found it. - return MD; - } - - return 0; -} - CGRecordLayout * CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types, const RecordDecl *D) { @@ -385,7 +359,5 @@ CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types, Types.addBitFieldInfo(Info.FD, Info.FieldNo, Info.Start, Info.Size); } - const CXXMethodDecl *KeyFunction = GetKeyFunction(D); - - return new CGRecordLayout(Ty, Builder.ContainsMemberPointer, KeyFunction); + return new CGRecordLayout(Ty, Builder.ContainsMemberPointer); } diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 224c829a5b1..715aa4c03c1 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -1060,10 +1060,10 @@ llvm::Constant *CodeGenModule::GenerateVtable(const CXXRecordDecl *LayoutClass, if (LayoutClass != RD) CreateDefinition = true; else { - // We have to convert it to have a record layout. - Types.ConvertTagDeclType(LayoutClass); - const CGRecordLayout &CGLayout = Types.getCGRecordLayout(LayoutClass); - if (const CXXMethodDecl *KeyFunction = CGLayout.getKeyFunction()) { + const ASTRecordLayout &Layout = + getContext().getASTRecordLayout(LayoutClass); + + if (const CXXMethodDecl *KeyFunction = Layout.getKeyFunction()) { if (!KeyFunction->getBody()) { // If there is a KeyFunction, and it isn't defined, just build a // reference to the vtable. @@ -1316,10 +1316,9 @@ llvm::Constant *CGVtableInfo::getVtable(const CXXRecordDecl *RD) { vtbl = CGM.GenerateVtable(RD, RD); bool CreateDefinition = true; - // We have to convert it to have a record layout. - CGM.getTypes().ConvertTagDeclType(RD); - const CGRecordLayout &CGLayout = CGM.getTypes().getCGRecordLayout(RD); - if (const CXXMethodDecl *KeyFunction = CGLayout.getKeyFunction()) { + + const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); + if (const CXXMethodDecl *KeyFunction = Layout.getKeyFunction()) { if (!KeyFunction->getBody()) { // If there is a KeyFunction, and it isn't defined, just build a // reference to the vtable. @@ -1339,3 +1338,31 @@ llvm::Constant *CGVtableInfo::getCtorVtable(const CXXRecordDecl *LayoutClass, uint64_t Offset) { return CGM.GenerateVtable(LayoutClass, RD, Offset); } + +void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) { + const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl()); + const CXXRecordDecl *RD = MD->getParent(); + + const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); + + // Get the key function. + const CXXMethodDecl *KeyFunction = Layout.getKeyFunction(); + + if (!KeyFunction) { + // If there's no key function, we don't want to emit the vtable here. + return; + } + + // Check if we have the key function. + if (KeyFunction->getCanonicalDecl() != MD->getCanonicalDecl()) + return; + + // If the key function is a destructor, we only want to emit the vtable once, + // so do it for the complete destructor. + if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() != Dtor_Complete) + return; + + // Emit the data. + GenerateClassData(RD); +} + diff --git a/clang/lib/CodeGen/CGVtable.h b/clang/lib/CodeGen/CGVtable.h index ac3cdee63be..5c2b74c9dd8 100644 --- a/clang/lib/CodeGen/CGVtable.h +++ b/clang/lib/CodeGen/CGVtable.h @@ -91,6 +91,11 @@ class CGVtableInfo { void ComputeMethodVtableIndices(const CXXRecordDecl *RD); + /// GenerateClassData - Generate all the class data requires to be generated + /// upon definition of a KeyFunction. This includes the vtable, the + /// rtti data structure and the VTT. + void GenerateClassData(const CXXRecordDecl *RD); + public: CGVtableInfo(CodeGenModule &CGM) : CGM(CGM) { } @@ -111,10 +116,9 @@ public: llvm::Constant *getVtable(const CXXRecordDecl *RD); llvm::Constant *getCtorVtable(const CXXRecordDecl *RD, const CXXRecordDecl *Class, uint64_t Offset); - /// GenerateClassData - Generate all the class data requires to be generated - /// upon definition of a KeyFunction. This includes the vtable, the - /// rtti data structure and the VTT. - void GenerateClassData(const CXXRecordDecl *RD); + + + void MaybeEmitVtable(GlobalDecl GD); }; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index a14733aba02..4b3b122b71c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -21,6 +21,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/RecordLayout.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" @@ -614,18 +615,9 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { Context.getSourceManager(), "Generating code for declaration"); - if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { - const CXXRecordDecl *RD = MD->getParent(); - // We have to convert it to have a record layout. - Types.ConvertTagDeclType(RD); - const CGRecordLayout &CGLayout = Types.getCGRecordLayout(RD); - // A definition of a KeyFunction, generates all the class data, such - // as vtable, rtti and the VTT. - if (CGLayout.getKeyFunction() - && (CGLayout.getKeyFunction()->getCanonicalDecl() - == MD->getCanonicalDecl())) - getVtableInfo().GenerateClassData(RD); - } + if (isa<CXXMethodDecl>(D)) + getVtableInfo().MaybeEmitVtable(GD); + if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D)) EmitCXXConstructor(CD, GD.getCtorType()); else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D)) diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 55827aac499..2ff602f900f 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -64,17 +64,9 @@ 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, - const CXXMethodDecl *KeyFunction) - : LLVMType(T), ContainsMemberPointer(ContainsMemberPointer), - KeyFunction(KeyFunction) { } + CGRecordLayout(const llvm::Type *T, bool ContainsMemberPointer) + : LLVMType(T), ContainsMemberPointer(ContainsMemberPointer) { } /// getLLVMType - Return llvm type associated with this record. const llvm::Type *getLLVMType() const { @@ -84,10 +76,6 @@ namespace CodeGen { bool containsMemberPointer() const { return ContainsMemberPointer; } - - const CXXMethodDecl *getKeyFunction() const { - return KeyFunction; - } }; /// CodeGenTypes - This class organizes the cross-module state that is used |