diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 38 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVtable.h | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 4 |
4 files changed, 44 insertions, 26 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 932bd079e93..a77a28ccdd8 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -3405,7 +3405,22 @@ void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0, /*IsVirtual=*/false, AddressPoints); - GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); + GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD); + + for (CXXRecordDecl::method_iterator i = RD->method_begin(), + e = RD->method_end(); i != e; ++i) { + if (!(*i)->isVirtual()) + continue; + if(!(*i)->hasInlineBody() && !(*i)->isImplicit()) + continue; + + if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) { + CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete)); + CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting)); + } else { + CGM.BuildThunksForVirtual(GlobalDecl(*i)); + } + } } llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) { @@ -3438,19 +3453,12 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) { return; } - // Emit the data. - GenerateClassData(CGM.getVtableLinkage(RD), RD); + if (Vtables.count(RD)) + return; - for (CXXRecordDecl::method_iterator i = RD->method_begin(), - e = RD->method_end(); i != e; ++i) { - if ((*i)->isVirtual() && ((*i)->hasInlineBody() || (*i)->isImplicit())) { - if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) { - CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete)); - CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting)); - } else { - CGM.BuildThunksForVirtual(GlobalDecl(*i)); - } - } - } + TemplateSpecializationKind kind = RD->getTemplateSpecializationKind(); + if (kind == TSK_ImplicitInstantiation) + CGM.DeferredVtables.push_back(RD); + else + GenerateClassData(CGM.getVtableLinkage(RD), RD); } - diff --git a/clang/lib/CodeGen/CGVtable.h b/clang/lib/CodeGen/CGVtable.h index 6ccb011985f..57220d9d5af 100644 --- a/clang/lib/CodeGen/CGVtable.h +++ b/clang/lib/CodeGen/CGVtable.h @@ -173,15 +173,7 @@ private: uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD); 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. - /// - /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT. - void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, - const CXXRecordDecl *RD); - + llvm::GlobalVariable * GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, bool GenerateDefinition, const CXXRecordDecl *LayoutClass, @@ -245,6 +237,14 @@ public: llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD); void MaybeEmitVtable(GlobalDecl GD); + + /// 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. + /// + /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT. + void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage, + const CXXRecordDecl *RD); }; } // end namespace CodeGen diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d6a56dad0ba..c67948d27f0 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -488,7 +488,15 @@ void CodeGenModule::EmitDeferred() { // Emit code for any potentially referenced deferred decls. Since a // previously unused static decl may become used during the generation of code // for a static function, iterate until no changes are made. - while (!DeferredDeclsToEmit.empty()) { + + while (!DeferredDeclsToEmit.empty() || !DeferredVtables.empty()) { + if (!DeferredVtables.empty()) { + const CXXRecordDecl *RD = DeferredVtables.back(); + DeferredVtables.pop_back(); + getVtableInfo().GenerateClassData(getVtableLinkage(RD), RD); + continue; + } + GlobalDecl D = DeferredDeclsToEmit.back(); DeferredDeclsToEmit.pop_back(); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index c86f8b45bcd..40dc5638898 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -451,7 +451,9 @@ public: /// GetTargetTypeStoreSize - Return the store size, in character units, of /// the given LLVM type. CharUnits GetTargetTypeStoreSize(const llvm::Type *Ty) const; - + + std::vector<const CXXRecordDecl*> DeferredVtables; + private: /// UniqueMangledName - Unique a name by (if necessary) inserting it into the /// MangledNames string map. |