зеркало из https://github.com/microsoft/clang-1.git
Refine handling for return value conversions with respect to virtual
offsets for covariant thunks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83965 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
3c0ef8cc0d
Коммит
d9878a181f
|
@ -47,7 +47,8 @@ private:
|
|||
typedef llvm::DenseMap<const CXXMethodDecl *, CallOffset> Thunks_t;
|
||||
Thunks_t Thunks;
|
||||
typedef llvm::DenseMap<const CXXMethodDecl *,
|
||||
std::pair<CallOffset, CallOffset> > CovariantThunks_t;
|
||||
std::pair<std::pair<CallOffset, CallOffset>,
|
||||
CanQualType> > CovariantThunks_t;
|
||||
CovariantThunks_t CovariantThunks;
|
||||
std::vector<Index_t> VCalls;
|
||||
typedef CXXRecordDecl::method_iterator method_iter;
|
||||
|
@ -81,7 +82,8 @@ public:
|
|||
}
|
||||
|
||||
void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
|
||||
const CXXRecordDecl *RD, uint64_t Offset) {
|
||||
const CXXRecordDecl *RD, uint64_t Offset,
|
||||
bool updateVBIndex) {
|
||||
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
|
||||
e = RD->bases_end(); i != e; ++i) {
|
||||
const CXXRecordDecl *Base =
|
||||
|
@ -91,11 +93,12 @@ public:
|
|||
int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
|
||||
llvm::Constant *m = wrap(BaseOffset);
|
||||
m = wrap((0?700:0) + BaseOffset);
|
||||
VBIndex[Base] = -(offsets.size()*LLVMPointerWidth/8)
|
||||
- 3*LLVMPointerWidth/8;
|
||||
if (updateVBIndex)
|
||||
VBIndex[Base] = -(offsets.size()*LLVMPointerWidth/8)
|
||||
- 3*LLVMPointerWidth/8;
|
||||
offsets.push_back(m);
|
||||
}
|
||||
GenerateVBaseOffsets(offsets, Base, Offset);
|
||||
GenerateVBaseOffsets(offsets, Base, Offset, updateVBIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +156,12 @@ public:
|
|||
CallOffset ReturnOffset = std::make_pair(0, 0);
|
||||
if (oret != ret) {
|
||||
// FIXME: calculate offsets for covariance
|
||||
ReturnOffset = std::make_pair(42,getVbaseOffset(oret, ret));
|
||||
Index_t nv = 0;
|
||||
if (CovariantThunks.count(OMD)) {
|
||||
oret = CovariantThunks[OMD].second;
|
||||
CovariantThunks.erase(OMD);
|
||||
}
|
||||
ReturnOffset = std::make_pair(nv, getVbaseOffset(oret, ret));
|
||||
}
|
||||
Index[MD] = i;
|
||||
submethods[i] = m;
|
||||
|
@ -174,7 +182,9 @@ public:
|
|||
// FIXME: calculate non-virtual offset
|
||||
ThisOffset = std::make_pair(0, -((idx+extra+2)*LLVMPointerWidth/8));
|
||||
if (ReturnOffset.first || ReturnOffset.second)
|
||||
CovariantThunks[MD] = std::make_pair(ThisOffset, ReturnOffset);
|
||||
CovariantThunks[MD] = std::make_pair(std::make_pair(ThisOffset,
|
||||
ReturnOffset),
|
||||
oret);
|
||||
else
|
||||
Thunks[MD] = ThisOffset;
|
||||
return true;
|
||||
|
@ -208,10 +218,10 @@ public:
|
|||
i != e; ++i) {
|
||||
const CXXMethodDecl *MD = i->first;
|
||||
Index_t idx = Index[MD];
|
||||
Index_t nv_t = i->second.first.first;
|
||||
Index_t v_t = i->second.first.second;
|
||||
Index_t nv_r = i->second.second.first;
|
||||
Index_t v_r = i->second.second.second;
|
||||
Index_t nv_t = i->second.first.first.first;
|
||||
Index_t v_t = i->second.first.first.second;
|
||||
Index_t nv_r = i->second.first.second.first;
|
||||
Index_t v_r = i->second.first.second.second;
|
||||
submethods[idx] = CGM.BuildCovariantThunk(MD, Extern, nv_t, v_t, nv_r,
|
||||
v_r);
|
||||
}
|
||||
|
@ -385,7 +395,7 @@ public:
|
|||
|
||||
std::vector<llvm::Constant *> offsets;
|
||||
extra = 0;
|
||||
GenerateVBaseOffsets(offsets, RD, Offset);
|
||||
GenerateVBaseOffsets(offsets, RD, Offset, !ForVirtualBase);
|
||||
if (ForVirtualBase)
|
||||
extra = offsets.size();
|
||||
|
||||
|
|
|
@ -757,7 +757,7 @@ struct test13_D : test13_NV1, virtual test13_B2 {
|
|||
virtual void Dd() { }
|
||||
virtual void D2() { }
|
||||
virtual void fooNV1() { }
|
||||
} test13_d;
|
||||
};
|
||||
|
||||
// CHECK-LP64:__ZTV8test13_D:
|
||||
// CHECK-LP64-NEXT: .quad 24
|
||||
|
@ -842,6 +842,95 @@ struct test13_D : test13_NV1, virtual test13_B2 {
|
|||
// CHECK-LP32-NEXT: .long __ZTv0_n32_N9test13_B22B2Ev
|
||||
|
||||
|
||||
class test14 {
|
||||
public:
|
||||
virtual void initWithInt(int a);
|
||||
static test14 *withInt(int a);
|
||||
};
|
||||
|
||||
void test14::initWithInt(int a) { }
|
||||
|
||||
test14 *test14::withInt(int a) {
|
||||
test14 *me = new test14;
|
||||
me->initWithInt(a);
|
||||
return me;
|
||||
}
|
||||
|
||||
|
||||
struct test15_B {
|
||||
virtual test15_B *foo1() { return 0; }
|
||||
virtual test15_B *foo2() { return 0; }
|
||||
virtual test15_B *foo3() { return 0; }
|
||||
int i;
|
||||
};
|
||||
|
||||
struct test15_NV1 {
|
||||
virtual void fooNV1() { }
|
||||
int i;
|
||||
};
|
||||
|
||||
struct test15_B2 : test15_NV1, virtual test15_B {
|
||||
virtual test15_B2 *foo1() { return 0; }
|
||||
virtual test15_B2 *foo2() { return 0; }
|
||||
int i;
|
||||
};
|
||||
|
||||
struct test15_D : test15_NV1, virtual test15_B2 {
|
||||
virtual test15_D *foo1() { return 0; }
|
||||
};
|
||||
|
||||
// CHECK-LP64:__ZTV8test15_D:
|
||||
// CHECK-LP64-NEXT: .quad 32
|
||||
// CHECK-LP64-NEXT: .quad 16
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .quad __ZTI8test15_D
|
||||
// CHECK-LP64-NEXT: .quad __ZN10test15_NV16fooNV1Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN8test15_D4foo1Ev
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .quad 18446744073709551600
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .quad 16
|
||||
// CHECK-LP64-NEXT: .quad 18446744073709551600
|
||||
// CHECK-LP64-NEXT: .quad __ZTI8test15_D
|
||||
// CHECK-LP64-NEXT: .quad __ZN10test15_NV16fooNV1Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZTcv0_n40_v0_n24_N8test15_D4foo1Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN9test15_B24foo2Ev
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .quad 18446744073709551600
|
||||
// CHECK-LP64-NEXT: .quad 18446744073709551584
|
||||
// CHECK-LP64-NEXT: .quad 18446744073709551584
|
||||
// CHECK-LP64-NEXT: .quad __ZTI8test15_D
|
||||
// CHECK-LP64-NEXT: .quad __ZTcv0_n24_v0_n32_N8test15_D4foo1Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZTcv0_n32_v0_n24_N9test15_B24foo2Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN8test15_B4foo3Ev
|
||||
|
||||
// CHECK-LP32:__ZTV8test15_D:
|
||||
// CHECK-LP32-NEXT: .long 20
|
||||
// CHECK-LP32-NEXT: .long 8
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .long __ZTI8test15_D
|
||||
// CHECK-LP32-NEXT: .long __ZN10test15_NV16fooNV1Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN8test15_D4foo1Ev
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .long 4294967288
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .long 12
|
||||
// CHECK-LP32-NEXT: .long 4294967288
|
||||
// CHECK-LP32-NEXT: .long __ZTI8test15_D
|
||||
// CHECK-LP32-NEXT: .long __ZN10test15_NV16fooNV1Ev
|
||||
// CHECK-LP32-NEXT: .long __ZTcv0_n20_v0_n12_N8test15_D4foo1Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN9test15_B24foo2Ev
|
||||
// CHECK-LP32-NEXT: .space 4
|
||||
// CHECK-LP32-NEXT: .long 4294967284
|
||||
// CHECK-LP32-NEXT: .long 4294967276
|
||||
// CHECK-LP32-NEXT: .long 4294967276
|
||||
// CHECK-LP32-NEXT: .long __ZTI8test15_D
|
||||
// CHECK-LP32-NEXT: .long __ZTcv0_n12_v0_n16_N8test15_D4foo1Ev
|
||||
// CHECK-LP32-NEXT: .long __ZTcv0_n16_v0_n12_N9test15_B24foo2Ev
|
||||
// CHECK-LP32-NEXT: .long __ZN8test15_B4foo3Ev
|
||||
|
||||
|
||||
|
||||
// CHECK-LP64: __ZTV1B:
|
||||
// CHECK-LP64-NEXT: .space 8
|
||||
// CHECK-LP64-NEXT: .quad __ZTI1B
|
||||
|
@ -920,20 +1009,8 @@ struct test13_D : test13_NV1, virtual test13_B2 {
|
|||
// CHECK-LP64-NEXT: .quad __ZN2D14bar4Ev
|
||||
// CHECK-LP64-NEXT: .quad __ZN2D14bar5Ev
|
||||
|
||||
class test14 {
|
||||
public:
|
||||
virtual void initWithInt(int a);
|
||||
static test14 *withInt(int a);
|
||||
};
|
||||
|
||||
void test14::initWithInt(int a) { }
|
||||
|
||||
test14 *test14::withInt(int a) {
|
||||
test14 *me = new test14;
|
||||
me->initWithInt(a);
|
||||
return me;
|
||||
}
|
||||
|
||||
test15_D d15;
|
||||
test13_D d13;
|
||||
test11_D d11;
|
||||
test10_D d10;
|
||||
test9_D d9;
|
||||
|
|
Загрузка…
Ссылка в новой задаче