forked from OSchip/llvm-project
Don't try to emit the vtable for a class just because we're emitting a
virtual function from it. Fixes PR7241. llvm-svn: 105345
This commit is contained in:
parent
f2dffcef82
commit
6a7f9f5c8f
|
@ -2745,7 +2745,7 @@ void CodeGenVTables::EmitThunks(GlobalDecl GD)
|
|||
const CXXRecordDecl *RD = MD->getParent();
|
||||
|
||||
// Compute VTable related info for this class.
|
||||
ComputeVTableRelatedInformation(RD);
|
||||
ComputeVTableRelatedInformation(RD, false);
|
||||
|
||||
ThunksMapTy::const_iterator I = Thunks.find(MD);
|
||||
if (I == Thunks.end()) {
|
||||
|
@ -2758,24 +2758,30 @@ void CodeGenVTables::EmitThunks(GlobalDecl GD)
|
|||
EmitThunk(GD, ThunkInfoVector[I]);
|
||||
}
|
||||
|
||||
void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) {
|
||||
uint64_t *&LayoutData = VTableLayoutMap[RD];
|
||||
|
||||
// Check if we've computed this information before.
|
||||
if (LayoutData)
|
||||
return;
|
||||
void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD,
|
||||
bool RequireVTable) {
|
||||
VTableLayoutData &Entry = VTableLayoutMap[RD];
|
||||
|
||||
// We may need to generate a definition for this vtable.
|
||||
if (!isKeyFunctionInAnotherTU(CGM.getContext(), RD) &&
|
||||
RD->getTemplateSpecializationKind()
|
||||
!= TSK_ExplicitInstantiationDeclaration)
|
||||
CGM.DeferredVTables.push_back(RD);
|
||||
if (RequireVTable && !Entry.getInt()) {
|
||||
if (!isKeyFunctionInAnotherTU(CGM.getContext(), RD) &&
|
||||
RD->getTemplateSpecializationKind()
|
||||
!= TSK_ExplicitInstantiationDeclaration)
|
||||
CGM.DeferredVTables.push_back(RD);
|
||||
|
||||
Entry.setInt(true);
|
||||
}
|
||||
|
||||
// Check if we've computed this information before.
|
||||
if (Entry.getPointer())
|
||||
return;
|
||||
|
||||
VTableBuilder Builder(*this, RD, 0, /*MostDerivedClassIsVirtual=*/0, RD);
|
||||
|
||||
// Add the VTable layout.
|
||||
uint64_t NumVTableComponents = Builder.getNumVTableComponents();
|
||||
LayoutData = new uint64_t[NumVTableComponents + 1];
|
||||
uint64_t *LayoutData = new uint64_t[NumVTableComponents + 1];
|
||||
Entry.setPointer(LayoutData);
|
||||
|
||||
// Store the number of components.
|
||||
LayoutData[0] = NumVTableComponents;
|
||||
|
@ -2990,7 +2996,7 @@ llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTable(const CXXRecordDecl *RD) {
|
|||
CGM.getMangleContext().mangleCXXVTable(RD, OutName);
|
||||
llvm::StringRef Name = OutName.str();
|
||||
|
||||
ComputeVTableRelatedInformation(RD);
|
||||
ComputeVTableRelatedInformation(RD, true);
|
||||
|
||||
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
|
||||
llvm::ArrayType *ArrayType =
|
||||
|
|
|
@ -207,8 +207,12 @@ class CodeGenVTables {
|
|||
|
||||
/// Thunks - Contains all thunks that a given method decl will need.
|
||||
ThunksMapTy Thunks;
|
||||
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t *> VTableLayoutMapTy;
|
||||
|
||||
// The layout entry and a bool indicating whether we've actually emitted
|
||||
// the vtable.
|
||||
typedef llvm::PointerIntPair<uint64_t *, 1, bool> VTableLayoutData;
|
||||
typedef llvm::DenseMap<const CXXRecordDecl *, VTableLayoutData>
|
||||
VTableLayoutMapTy;
|
||||
|
||||
/// VTableLayoutMap - Stores the vtable layout for all record decls.
|
||||
/// The layout is stored as an array of 64-bit integers, where the first
|
||||
|
@ -237,13 +241,13 @@ class CodeGenVTables {
|
|||
uint64_t getNumVTableComponents(const CXXRecordDecl *RD) const {
|
||||
assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
|
||||
|
||||
return VTableLayoutMap.lookup(RD)[0];
|
||||
return VTableLayoutMap.lookup(RD).getPointer()[0];
|
||||
}
|
||||
|
||||
const uint64_t *getVTableComponentsData(const CXXRecordDecl *RD) const {
|
||||
assert(VTableLayoutMap.count(RD) && "No vtable layout for this class!");
|
||||
|
||||
uint64_t *Components = VTableLayoutMap.lookup(RD);
|
||||
uint64_t *Components = VTableLayoutMap.lookup(RD).getPointer();
|
||||
return &Components[1];
|
||||
}
|
||||
|
||||
|
@ -275,7 +279,8 @@ class CodeGenVTables {
|
|||
/// ComputeVTableRelatedInformation - Compute and store all vtable related
|
||||
/// information (vtable layout, vbase offset offsets, thunks etc) for the
|
||||
/// given record decl.
|
||||
void ComputeVTableRelatedInformation(const CXXRecordDecl *RD);
|
||||
void ComputeVTableRelatedInformation(const CXXRecordDecl *RD,
|
||||
bool VTableRequired);
|
||||
|
||||
/// CreateVTableInitializer - Create a vtable initializer for the given record
|
||||
/// decl.
|
||||
|
|
|
@ -234,6 +234,18 @@ namespace Test8 {
|
|||
void C::bar(NonPOD var) {}
|
||||
}
|
||||
|
||||
// PR7241: Emitting thunks for a method shouldn't require the vtable for
|
||||
// that class to be emitted.
|
||||
namespace Test9 {
|
||||
struct A { virtual ~A() { } };
|
||||
struct B : A { virtual void test() const {} };
|
||||
struct C : B { C(); ~C(); };
|
||||
struct D : C { D() {} };
|
||||
void test() {
|
||||
D d;
|
||||
}
|
||||
}
|
||||
|
||||
/**** The following has to go at the end of the file ****/
|
||||
|
||||
// This is from Test5:
|
||||
|
|
|
@ -27,6 +27,11 @@ int main() {
|
|||
// CHECK: call void @_ZN13basic_istreamIcED2Ev
|
||||
// CHECK: }
|
||||
|
||||
// basic_istream's base dtor is a no-op.
|
||||
// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev
|
||||
// CHECK-NOT: call
|
||||
// CHECK: }
|
||||
|
||||
// basic_iostream's deleting dtor calls its complete dtor, then
|
||||
// operator delete().
|
||||
// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev
|
||||
|
@ -44,9 +49,3 @@ int main() {
|
|||
// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED0Ev
|
||||
// CHECK: call void @_ZN13basic_istreamIcED1Ev
|
||||
// CHECK: call void @_ZdlPv
|
||||
|
||||
// basic_istream's base dtor is a no-op.
|
||||
// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev
|
||||
// CHECK-NOT: call
|
||||
// CHECK: }
|
||||
|
||||
|
|
Loading…
Reference in New Issue