зеркало из https://github.com/microsoft/clang-1.git
Add ability to generate vcall offsets for primary virtual base.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78396 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
116b7d9cd0
Коммит
928f1506eb
|
@ -56,6 +56,8 @@ class ASTRecordLayout {
|
|||
|
||||
/// PrimaryBase - The primary base for our vtable.
|
||||
const CXXRecordDecl *PrimaryBase;
|
||||
/// PrimaryBase - Wether or not the primary base was a virtual base.
|
||||
bool PrimaryBaseWasVirtual;
|
||||
|
||||
/// BaseOffsets - Contains a map from base classes to their offset.
|
||||
/// FIXME: Does it make sense to store offsets for virtual base classes
|
||||
|
@ -86,8 +88,9 @@ class ASTRecordLayout {
|
|||
ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize,
|
||||
const uint64_t *fieldoffsets, unsigned fieldcount,
|
||||
uint64_t nonvirtualsize, unsigned nonvirtualalign,
|
||||
const CXXRecordDecl *PB, const CXXRecordDecl **bases,
|
||||
const uint64_t *baseoffsets, unsigned basecount)
|
||||
const CXXRecordDecl *PB, bool PBVirtual,
|
||||
const CXXRecordDecl **bases, const uint64_t *baseoffsets,
|
||||
unsigned basecount)
|
||||
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
|
||||
FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
|
||||
if (FieldCount > 0) {
|
||||
|
@ -97,6 +100,7 @@ class ASTRecordLayout {
|
|||
}
|
||||
|
||||
CXXInfo->PrimaryBase = PB;
|
||||
CXXInfo->PrimaryBaseWasVirtual = PBVirtual;
|
||||
CXXInfo->NonVirtualSize = nonvirtualsize;
|
||||
CXXInfo->NonVirtualAlign = nonvirtualalign;
|
||||
for (unsigned i = 0; i != basecount; ++i)
|
||||
|
@ -156,6 +160,12 @@ public:
|
|||
|
||||
return CXXInfo->PrimaryBase;
|
||||
}
|
||||
/// getPrimaryBaseWasVirtual - Indicates if the primary base was virtual.
|
||||
bool getPrimaryBaseWasVirtual() const {
|
||||
assert(CXXInfo && "Record layout does not have C++ specific info!");
|
||||
|
||||
return CXXInfo->PrimaryBaseWasVirtual;
|
||||
}
|
||||
|
||||
/// getBaseClassOffset - Get the offset, in bits, for the given base class.
|
||||
uint64_t getBaseClassOffset(const CXXRecordDecl *Base) const {
|
||||
|
|
|
@ -30,7 +30,7 @@ void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
|
|||
// FIXME: audit indirect virtual bases
|
||||
if (!RD->isPolymorphic() && !RD->getNumVBases()) {
|
||||
// There is no primary base in this case.
|
||||
setPrimaryBase(0);
|
||||
setPrimaryBase(0, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
|
|||
const CXXRecordDecl *Base =
|
||||
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
|
||||
if (Base->isDynamicClass()) {
|
||||
setPrimaryBase(Base);
|
||||
setPrimaryBase(Base, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
|
|||
// is expensive.
|
||||
// FIXME: audit indirect virtual bases
|
||||
if (RD->getNumVBases() == 0) {
|
||||
setPrimaryBase(0);
|
||||
setPrimaryBase(0, false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -143,15 +143,15 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
|
|||
if (FirstPrimary==0)
|
||||
FirstPrimary = Base;
|
||||
if (!IndirectPrimary.count(Base)) {
|
||||
setPrimaryBase(Base);
|
||||
setPrimaryBase(Base, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise if is the first nearly empty base, if one exists, otherwise
|
||||
// there is no primary base class.
|
||||
setPrimaryBase(FirstPrimary);
|
||||
// Otherwise if is the first nearly empty virtual base, if one exists,
|
||||
// otherwise there is no primary base class.
|
||||
setPrimaryBase(FirstPrimary, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -404,6 +404,7 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
|
|||
NonVirtualSize,
|
||||
Builder.NonVirtualAlignment,
|
||||
Builder.PrimaryBase,
|
||||
Builder.PrimaryBaseWasVirtual,
|
||||
Builder.Bases.data(),
|
||||
Builder.BaseOffsets.data(),
|
||||
Builder.Bases.size());
|
||||
|
|
|
@ -37,6 +37,7 @@ class ASTRecordLayoutBuilder {
|
|||
uint64_t NonVirtualSize;
|
||||
unsigned NonVirtualAlignment;
|
||||
const CXXRecordDecl *PrimaryBase;
|
||||
bool PrimaryBaseWasVirtual;
|
||||
|
||||
llvm::SmallVector<const CXXRecordDecl *, 4> Bases;
|
||||
llvm::SmallVector<uint64_t, 4> BaseOffsets;
|
||||
|
@ -54,7 +55,10 @@ class ASTRecordLayoutBuilder {
|
|||
void SelectPrimaryBase(const CXXRecordDecl *RD);
|
||||
void SelectPrimaryForBase(const CXXRecordDecl *RD,
|
||||
llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
|
||||
void setPrimaryBase(const CXXRecordDecl *PB) { PrimaryBase = PB; }
|
||||
void setPrimaryBase(const CXXRecordDecl *PB, bool Virtual) {
|
||||
PrimaryBase = PB;
|
||||
PrimaryBaseWasVirtual = Virtual;
|
||||
}
|
||||
bool IsNearlyEmpty(const CXXRecordDecl *RD);
|
||||
void LayoutVtable(const CXXRecordDecl *RD);
|
||||
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
|
||||
|
|
|
@ -614,9 +614,11 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
|
|||
|
||||
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
|
||||
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
|
||||
const bool PrimaryBaseWasVirtual = Layout.getPrimaryBase();
|
||||
|
||||
// The primary base comes first.
|
||||
GenerateVtableForBase(PrimaryBase, RD, rtti, methods, true);
|
||||
GenerateVtableForBase(PrimaryBase, RD, rtti, methods, true,
|
||||
PrimaryBaseWasVirtual);
|
||||
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
|
||||
e = RD->bases_end(); i != e; ++i) {
|
||||
if (i->isVirtual())
|
||||
|
|
|
@ -121,10 +121,10 @@ int main() {
|
|||
// CHECK-LP32: .long __ZN1C4bee1Ev
|
||||
// CHECK-LP32: .long __ZN1C4bee2Ev
|
||||
|
||||
// CHECK-LP32: __ZTV1F:
|
||||
// CHECK-LP32 .space 4
|
||||
// CHECK-LP32:__ZTV1F:
|
||||
// CHECK-LP32: .space 4
|
||||
// CHECK-LP32 .long 8
|
||||
// CHECK-LP32 .space 4
|
||||
// CHECK-LP32: .space 4
|
||||
// CHECK-LP32: .space 4
|
||||
// CHECK-LP32: .long __ZTI1F
|
||||
// CHECK-LP32: .long __ZN1D3booEv
|
||||
|
@ -143,9 +143,9 @@ int main() {
|
|||
// CHECK-LP32: .long __ZN2D14bar5Ev
|
||||
|
||||
// CHECK-LP64: __ZTV1F:
|
||||
// CHECK-LP64 .space 8
|
||||
// CHECK-LP64: .space 8
|
||||
// CHECK-LP64 .quad 16
|
||||
// CHECK-LP64 .space 8
|
||||
// CHECK-LP64: .space 8
|
||||
// CHECK-LP64: .space 8
|
||||
// CHECK-LP64: .quad __ZTI1F
|
||||
// CHECK-LP64: .quad __ZN1D3booEv
|
||||
|
|
Загрузка…
Ссылка в новой задаче