Refine the vcall for a function that is defined in a virtual base

class that is overridden in a base that isn't morally virtual.

llvm-svn: 86217
This commit is contained in:
Mike Stump
2009-11-06 02:38:24 +00:00
parent bee01e5b61
commit 72431bd9ea
2 changed files with 44 additions and 7 deletions

View File

@@ -242,15 +242,13 @@ public:
idx = VCalls.size()+1;
VCalls.push_back(0);
D1(printf(" vcall for %s at %d with delta %d most derived %s\n",
MD->getNameAsCString(),
(int)-VCalls.size()-3, (int)VCallOffset[MD],
MD->getNameAsCString(), (int)-idx-3, (int)VCalls[idx-1],
Class->getNameAsCString()));
} else {
VCallOffset[MD] = VCallOffset[OMD];
VCalls[idx-1] = -VCallOffset[OMD] + OverrideOffset/8;
D1(printf(" vcall patch for %s at %d with delta %d most derived %s\n",
MD->getNameAsCString(),
(int)-VCalls.size()-3, (int)VCallOffset[MD],
MD->getNameAsCString(), (int)-idx-3, (int)VCalls[idx-1],
Class->getNameAsCString()));
}
VCall[MD] = idx;
@@ -271,6 +269,16 @@ public:
// FIXME: finish off
int64_t O = VCallOffset[OMD] - OverrideOffset/8;
// int64_t O = CurrentVBaseOffset/8 - OverrideOffset/8;
if (VCall.count(OMD)) {
VCallOffset[MD] = VCallOffset[OMD];
Index_t idx = VCall[OMD];
VCalls[idx-1] = -VCallOffset[OMD] + OverrideOffset/8;
D1(printf(" vcall patch for %s at %d with delta %d most derived %s\n",
MD->getNameAsCString(), (int)-idx-3, (int)VCalls[idx-1],
Class->getNameAsCString()));
VCall[MD] = idx;
}
if (O || ReturnOffset.first || ReturnOffset.second) {
CallOffset ThisOffset = std::make_pair(O, 0);
@@ -374,8 +382,7 @@ public:
idx = VCalls.size()+1;
VCalls.push_back(0);
D1(printf(" vcall for %s at %d with delta %d\n",
MD->getNameAsCString(), (int)-VCalls.size()-3,
(int)VCallOffset[MD]));
MD->getNameAsCString(), (int)-VCalls.size()-3, 0));
}
}
}

View File

@@ -895,7 +895,7 @@ class test20_B : virtual test20_V {
class test20_B1 : virtual test20_V1 {
};
class test20_D : public test20_B, public test20_B1 {
} d;
};
// CHECK-LP64: __ZTV8test20_D:
// CHECK-LP64-NEXT: .quad 8
@@ -911,6 +911,34 @@ class test20_D : public test20_B, public test20_B1 {
// CHECK-LP64-NEXT: .quad __ZN9test20_V14foo2Ev
class test21_V {
virtual void foo();
};
class test21_V1 {
virtual void foo();
};
class test21_B : virtual test21_V {
};
class test21_B1 : virtual test21_V1 {
};
class test21_D : public test21_B, public test21_B1 {
void foo() { }
};
// CHECK-LP64: __ZTV8test21_D:
// CHECK-LP64-NEXT: .quad 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .quad __ZTI8test21_D
// CHECK-LP64-NEXT: .quad __ZN8test21_D3fooEv
// CHECK-LP64-NEXT: .space 8
// CHECK-LP64-NEXT: .quad 18446744073709551608
// CHECK-LP64-NEXT: .quad 18446744073709551608
// CHECK-LP64-NEXT: .quad __ZTI8test21_D
// CHECK-LP64-NEXT .quad __ZTv0_n24_N8test21_D3fooEv
// CHECK-LP64: __ZTV1B:
// CHECK-LP64-NEXT: .space 8
@@ -951,6 +979,8 @@ class test20_D : public test20_B, public test20_B1 {
// CHECK-LP64-NEXT: .quad __ZN2D14bar4Ev
// CHECK-LP64-NEXT: .quad __ZN2D14bar5Ev
test21_D d21;
test20_D d20;
test19_D d19;
test18_D d18;
test17_D d17;