forked from OSchip/llvm-project
Fix a bunch of VTT layout bugs, add simple tests for VTT layout.
llvm-svn: 93709
This commit is contained in:
parent
5fcd99b10f
commit
1af3df854f
|
@ -1314,6 +1314,17 @@ class VTTBuilder {
|
|||
e = RD->bases_end(); i != e; ++i) {
|
||||
const CXXRecordDecl *Base =
|
||||
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
|
||||
|
||||
// Itanium C++ ABI 2.6.2:
|
||||
// Secondary virtual pointers are present for all bases with either
|
||||
// virtual bases or virtual function declarations overridden along a
|
||||
// virtual path.
|
||||
//
|
||||
// If the base class is not dynamic, we don't want to add it, nor any
|
||||
// of its base classes.
|
||||
if (!Base->isDynamicClass())
|
||||
continue;
|
||||
|
||||
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
|
||||
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
|
||||
const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
|
||||
|
@ -1330,10 +1341,9 @@ class VTTBuilder {
|
|||
const CXXRecordDecl *subVtblClass = VtblClass;
|
||||
if ((Base->getNumVBases() || BaseMorallyVirtual)
|
||||
&& !NonVirtualPrimaryBase) {
|
||||
// FIXME: Slightly too many of these for __ZTT8test8_B2
|
||||
llvm::Constant *init;
|
||||
if (BaseMorallyVirtual)
|
||||
init = BuildVtablePtr(vtbl, VtblClass, RD, Offset);
|
||||
if (BaseMorallyVirtual || VtblClass == Class)
|
||||
init = BuildVtablePtr(vtbl, VtblClass, Base, BaseOffset);
|
||||
else {
|
||||
init = getCtorVtable(BaseSubobject(Base, BaseOffset));
|
||||
|
||||
|
@ -1351,7 +1361,10 @@ class VTTBuilder {
|
|||
/// BuiltVTT - Add the VTT to Inits. Offset is the offset in bits to the
|
||||
/// currnet object we're working on.
|
||||
void BuildVTT(const CXXRecordDecl *RD, uint64_t Offset, bool MorallyVirtual) {
|
||||
if (RD->getNumVBases() == 0 && !MorallyVirtual)
|
||||
// Itanium C++ ABI 2.6.2:
|
||||
// An array of virtual table addresses, called the VTT, is declared for
|
||||
// each class type that has indirect or direct virtual base classes.
|
||||
if (RD->getNumVBases() == 0)
|
||||
return;
|
||||
|
||||
llvm::Constant *Vtable;
|
||||
|
|
|
@ -375,13 +375,13 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
|
|||
// CHECK-LP64-NEXT: .quad (__ZTV7test8_D) + 32
|
||||
// CHECK-LP64-NEXT: .quad (__ZTC7test8_D8_8test8_B2) + 32
|
||||
// CHECK-LP64-NEXT: .quad (__ZTC7test8_D8_9test8_B2a) + 32
|
||||
// CHECK-LP64-NEXT .quad (__ZTC7test8_D8_9test8_B2a) + 64
|
||||
// CHECK-LP64-NEXT .quad (__ZTC7test8_D8_9test8_B2a) + 96
|
||||
// CHECK-LP64-NEXT .quad (__ZTC7test8_D8_8test8_B2) + 72
|
||||
// CHECK-LP64-NEXT .quad (__ZTC7test8_D8_8test8_B2) + 104
|
||||
// CHECK-LP64-NEXT .quad (__ZTV7test8_D) + 72
|
||||
// CHECK-LP64: .quad (__ZTV7test8_D) + 160
|
||||
// CHECK-LP64: .quad (__ZTV7test8_D) + 192
|
||||
// CHECK-LP64-NEXT: .quad (__ZTC7test8_D8_9test8_B2a) + 64
|
||||
// CHECK-LP64-NEXT: .quad (__ZTC7test8_D8_9test8_B2a) + 96
|
||||
// CHECK-LP64-NEXT: .quad (__ZTC7test8_D8_8test8_B2) + 72
|
||||
// CHECK-LP64-NEXT: .quad (__ZTC7test8_D8_8test8_B2) + 104
|
||||
// CHECK-LP64-NEXT: .quad (__ZTV7test8_D) + 72
|
||||
// CHECK-LP64-NEXT: .quad (__ZTV7test8_D) + 160
|
||||
// CHECK-LP64-NEXT: .quad (__ZTV7test8_D) + 192
|
||||
|
||||
|
||||
struct test9_B3 { virtual void funcB3(); int i; };
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
|
||||
|
||||
namespace Test1 {
|
||||
struct A { };
|
||||
|
||||
struct B : virtual A {
|
||||
virtual void f();
|
||||
};
|
||||
|
||||
void B::f() { }
|
||||
}
|
||||
|
||||
// Test1::B should just have a single entry in its VTT, which points to the vtable.
|
||||
// CHECK: @_ZTTN5Test11BE = constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN5Test11BE, i64 0, i64 3) to i8*)]
|
||||
|
||||
namespace Test2 {
|
||||
struct A { };
|
||||
|
||||
struct B : A { virtual void f(); };
|
||||
struct C : virtual B { };
|
||||
|
||||
C c;
|
||||
}
|
||||
|
||||
// Check that we don't add a secondary virtual pointer for Test2::A, since Test2::A doesn't have any virtual member functions or bases.
|
||||
// CHECK: @_ZTTN5Test21CE = weak_odr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*)] ; <[2 x i8*]*> [#uses=0]
|
Loading…
Reference in New Issue