diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGRTTI.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/CGVTables.cpp | 25 | ||||
-rw-r--r-- | lib/CodeGen/CGVTables.h | 11 |
3 files changed, 30 insertions, 22 deletions
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index e98d0e8cea..60c3a5f84b 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -270,8 +270,9 @@ static bool IsStandardLibraryRTTIDescriptor(QualType Ty) { /// the given type exists somewhere else, and that we should not emit the type /// information in this translation unit. Assumes that it is not a /// standard-library type. -static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context, - QualType Ty) { +static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty) { + ASTContext &Context = CGM.getContext(); + // If RTTI is disabled, don't consider key functions. if (!Context.getLangOptions().RTTI) return false; @@ -283,13 +284,7 @@ static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context, if (!RD->isDynamicClass()) return false; - // Get the key function. - const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD); - if (KeyFunction && !KeyFunction->hasBody()) { - // The class has a key function, but it is not defined in this translation - // unit, so we should use the external descriptor for it. - return true; - } + return !CGM.getVTables().ShouldEmitVTableInThisTU(RD); } return false; @@ -528,8 +523,7 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) { // Check if there is already an external RTTI descriptor for this type. bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty); - if (!Force && - (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty))) + if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty))) return GetAddrOfExternalRTTIDescriptor(Ty); // Emit the standard library with external linkage. diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index bed4670f7f..e1ed98cdf5 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -2336,6 +2336,27 @@ void CodeGenVTables::ComputeMethodVTableIndices(const CXXRecordDecl *RD) { NumVirtualFunctionPointers[RD] = CurrentIndex; } +bool CodeGenVTables::ShouldEmitVTableInThisTU(const CXXRecordDecl *RD) { + assert(RD->isDynamicClass() && "Non dynamic classes have no VTable."); + + TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind(); + if (TSK == TSK_ExplicitInstantiationDeclaration) + return false; + + const CXXMethodDecl *KeyFunction = CGM.getContext().getKeyFunction(RD); + if (!KeyFunction) + return true; + + // Itanium C++ ABI, 5.2.6 Instantiated Templates: + // An instantiation of a class template requires: + // - In the object where instantiated, the virtual table... + if (TSK == TSK_ImplicitInstantiation || + TSK == TSK_ExplicitInstantiationDefinition) + return true; + + return KeyFunction->hasBody(); +} + uint64_t CodeGenVTables::getNumVirtualFunctionPointers(const CXXRecordDecl *RD) { llvm::DenseMap<const CXXRecordDecl *, uint64_t>::iterator I = NumVirtualFunctionPointers.find(RD); @@ -2703,9 +2724,7 @@ void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD, // We may need to generate a definition for this vtable. if (RequireVTable && !Entry.getInt()) { - if (!isKeyFunctionInAnotherTU(CGM.getContext(), RD) && - RD->getTemplateSpecializationKind() - != TSK_ExplicitInstantiationDeclaration) + if (ShouldEmitVTableInThisTU(RD)) CGM.DeferredVTables.push_back(RD); Entry.setInt(true); diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h index abcafd6c9c..1d2e8c1e04 100644 --- a/lib/CodeGen/CGVTables.h +++ b/lib/CodeGen/CGVTables.h @@ -295,14 +295,9 @@ public: CodeGenVTables(CodeGenModule &CGM) : CGM(CGM) { } - // isKeyFunctionInAnotherTU - True if this record has a key function and it is - // in another translation unit. - static bool isKeyFunctionInAnotherTU(ASTContext &Context, - const CXXRecordDecl *RD) { - assert (RD->isDynamicClass() && "Non dynamic classes have no key."); - const CXXMethodDecl *KeyFunction = Context.getKeyFunction(RD); - return KeyFunction && !KeyFunction->hasBody(); - } + /// \brief True if the VTable of this record must be emitted in the + /// translation unit. + bool ShouldEmitVTableInThisTU(const CXXRecordDecl *RD); /// needsVTTParameter - Return whether the given global decl needs a VTT /// parameter, which it does if it's a base constructor or destructor with |