[cfe-commits] r105345 - in /cfe/trunk: lib/CodeGen/CGVTables.cpp lib/CodeGen/CGVTables.h test/CodeGenCXX/thunks.cpp test/CodeGenCXX/virtual-base-destructor-call.cpp
John McCall
rjmccall at apple.com
Wed Jun 2 14:22:02 PDT 2010
Author: rjmccall
Date: Wed Jun 2 16:22:02 2010
New Revision: 105345
URL: http://llvm.org/viewvc/llvm-project?rev=105345&view=rev
Log:
Don't try to emit the vtable for a class just because we're emitting a
virtual function from it.
Fixes PR7241.
Modified:
cfe/trunk/lib/CodeGen/CGVTables.cpp
cfe/trunk/lib/CodeGen/CGVTables.h
cfe/trunk/test/CodeGenCXX/thunks.cpp
cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp
Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=105345&r1=105344&r2=105345&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Wed Jun 2 16:22:02 2010
@@ -2745,7 +2745,7 @@
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 @@
EmitThunk(GD, ThunkInfoVector[I]);
}
-void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD) {
- uint64_t *&LayoutData = VTableLayoutMap[RD];
+void CodeGenVTables::ComputeVTableRelatedInformation(const CXXRecordDecl *RD,
+ bool RequireVTable) {
+ VTableLayoutData &Entry = VTableLayoutMap[RD];
+
+ // We may need to generate a definition for this vtable.
+ 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 (LayoutData)
+ if (Entry.getPointer())
return;
- // We may need to generate a definition for this vtable.
- if (!isKeyFunctionInAnotherTU(CGM.getContext(), RD) &&
- RD->getTemplateSpecializationKind()
- != TSK_ExplicitInstantiationDeclaration)
- CGM.DeferredVTables.push_back(RD);
-
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 @@
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 =
Modified: cfe/trunk/lib/CodeGen/CGVTables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.h?rev=105345&r1=105344&r2=105345&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.h (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.h Wed Jun 2 16:22:02 2010
@@ -207,8 +207,12 @@
/// 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 @@
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 @@
/// 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.
Modified: cfe/trunk/test/CodeGenCXX/thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thunks.cpp?rev=105345&r1=105344&r2=105345&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/thunks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/thunks.cpp Wed Jun 2 16:22:02 2010
@@ -234,6 +234,18 @@
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:
Modified: cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp?rev=105345&r1=105344&r2=105345&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/virtual-base-destructor-call.cpp Wed Jun 2 16:22:02 2010
@@ -27,6 +27,11 @@
// 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 @@
// 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: }
-
More information about the cfe-commits
mailing list