зеркало из https://github.com/microsoft/clang-1.git
Pass information about whether a base is virtual or not down to getCtorVtable, we need this information in the vtable builder.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97356 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
438bc42785
Коммит
5d7af6b0da
|
@ -46,7 +46,8 @@ class VTTBuilder {
|
|||
llvm::DenseMap<std::pair<const CXXRecordDecl *, BaseSubobject>, uint64_t>
|
||||
CtorVtableAddressPoints;
|
||||
|
||||
llvm::Constant *getCtorVtable(const BaseSubobject &Base) {
|
||||
llvm::Constant *getCtorVtable(const BaseSubobject &Base,
|
||||
bool BaseIsVirtual) {
|
||||
if (!GenerateDefinition)
|
||||
return 0;
|
||||
|
||||
|
@ -54,7 +55,7 @@ class VTTBuilder {
|
|||
if (!CtorVtable) {
|
||||
// Build the vtable.
|
||||
CGVtableInfo::CtorVtableInfo Info
|
||||
= CGM.getVtableInfo().getCtorVtable(Class, Base);
|
||||
= CGM.getVtableInfo().getCtorVtable(Class, Base, BaseIsVirtual);
|
||||
|
||||
CtorVtable = Info.Vtable;
|
||||
|
||||
|
@ -166,7 +167,7 @@ class VTTBuilder {
|
|||
if (BaseMorallyVirtual || VtblClass == Class)
|
||||
init = BuildVtablePtr(vtbl, VtblClass, Base, BaseOffset);
|
||||
else {
|
||||
init = getCtorVtable(BaseSubobject(Base, BaseOffset));
|
||||
init = getCtorVtable(BaseSubobject(Base, BaseOffset), i->isVirtual());
|
||||
|
||||
subvtbl = init;
|
||||
subVtblClass = Base;
|
||||
|
@ -186,7 +187,8 @@ 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) {
|
||||
void BuildVTT(const CXXRecordDecl *RD, uint64_t Offset, bool BaseIsVirtual,
|
||||
bool 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.
|
||||
|
@ -204,7 +206,8 @@ class VTTBuilder {
|
|||
Vtable = ClassVtbl;
|
||||
VtableClass = Class;
|
||||
} else {
|
||||
Vtable = getCtorVtable(BaseSubobject(RD, Offset));
|
||||
Vtable = getCtorVtable(BaseSubobject(RD, Offset),
|
||||
/*IsVirtual=*/BaseIsVirtual);
|
||||
VtableClass = RD;
|
||||
}
|
||||
|
||||
|
@ -235,7 +238,7 @@ class VTTBuilder {
|
|||
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
|
||||
uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base);
|
||||
|
||||
BuildVTT(Base, BaseOffset, MorallyVirtual);
|
||||
BuildVTT(Base, BaseOffset, /*BaseIsVirtual=*/false, MorallyVirtual);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,7 +252,7 @@ class VTTBuilder {
|
|||
if (i->isVirtual() && !SeenVBase.count(Base)) {
|
||||
SeenVBase.insert(Base);
|
||||
uint64_t BaseOffset = BLayout.getVBaseClassOffset(Base);
|
||||
BuildVTT(Base, BaseOffset, false);
|
||||
BuildVTT(Base, BaseOffset, /*BaseIsVirtual=*/true, false);
|
||||
}
|
||||
VirtualVTTs(Base);
|
||||
}
|
||||
|
@ -335,13 +338,13 @@ CGVtableInfo::GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
|
|||
|
||||
CGVtableInfo::CtorVtableInfo
|
||||
CGVtableInfo::getCtorVtable(const CXXRecordDecl *RD,
|
||||
const BaseSubobject &Base) {
|
||||
const BaseSubobject &Base, bool BaseIsVirtual) {
|
||||
CtorVtableInfo Info;
|
||||
|
||||
Info.Vtable = GenerateVtable(llvm::GlobalValue::InternalLinkage,
|
||||
/*GenerateDefinition=*/true,
|
||||
RD, Base.getBase(), Base.getBaseOffset(),
|
||||
Info.AddressPoints);
|
||||
BaseIsVirtual, Info.AddressPoints);
|
||||
return Info;
|
||||
}
|
||||
|
||||
|
|
|
@ -1076,6 +1076,10 @@ private:
|
|||
/// holds the offset from the layout class to the most derived class.
|
||||
const uint64_t MostDerivedClassOffset;
|
||||
|
||||
/// MostDerivedClassIsVirtual - Whether the most derived class is a virtual
|
||||
/// base. (This only makes sense when building a construction vtable).
|
||||
bool MostDerivedClassIsVirtual;
|
||||
|
||||
/// LayoutClass - The class we're using for layout information. Will be
|
||||
/// different than the most derived class if we're building a construction
|
||||
/// vtable.
|
||||
|
@ -1214,7 +1218,7 @@ private:
|
|||
void AddMethods(BaseSubobject Base, BaseSubobject FirstBaseInPrimaryBaseChain,
|
||||
PrimaryBasesSetVectorTy &PrimaryBases);
|
||||
|
||||
// LayoutVtable - Layout the vtable for the most derived class, including its
|
||||
// LayoutVtable - Layout the vtable for the given base class, including its
|
||||
// secondary vtables and any vtables for virtual bases.
|
||||
void LayoutVtable();
|
||||
|
||||
|
@ -1245,11 +1249,13 @@ private:
|
|||
|
||||
public:
|
||||
VtableBuilder(CGVtableInfo &VtableInfo, const CXXRecordDecl *MostDerivedClass,
|
||||
uint64_t MostDerivedClassOffset,
|
||||
uint64_t MostDerivedClassOffset, bool MostDerivedClassIsVirtual,
|
||||
const CXXRecordDecl *LayoutClass)
|
||||
: VtableInfo(VtableInfo), MostDerivedClass(MostDerivedClass),
|
||||
MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass),
|
||||
Context(MostDerivedClass->getASTContext()), Overriders(MostDerivedClass) {
|
||||
MostDerivedClassOffset(MostDerivedClassOffset),
|
||||
MostDerivedClassIsVirtual(MostDerivedClassIsVirtual),
|
||||
LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()),
|
||||
Overriders(MostDerivedClass) {
|
||||
|
||||
LayoutVtable();
|
||||
}
|
||||
|
@ -1678,7 +1684,7 @@ VtableBuilder::AddMethods(BaseSubobject Base,
|
|||
|
||||
void VtableBuilder::LayoutVtable() {
|
||||
LayoutPrimaryAndAndSecondaryVtables(BaseSubobject(MostDerivedClass, 0),
|
||||
/*BaseIsVirtual=*/false);
|
||||
MostDerivedClassIsVirtual);
|
||||
|
||||
VisitedVirtualBasesSetTy VBases;
|
||||
|
||||
|
@ -3318,16 +3324,23 @@ CGVtableInfo::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
|
|||
bool GenerateDefinition,
|
||||
const CXXRecordDecl *LayoutClass,
|
||||
const CXXRecordDecl *RD, uint64_t Offset,
|
||||
bool IsVirtual,
|
||||
AddressPointsMapTy& AddressPoints) {
|
||||
if (GenerateDefinition) {
|
||||
if (LayoutClass == RD) {
|
||||
VtableBuilder Builder(*this, RD, Offset, LayoutClass);
|
||||
assert(!IsVirtual &&
|
||||
"Can't only have a virtual base in construction vtables!");
|
||||
VtableBuilder Builder(*this, RD, Offset,
|
||||
/*MostDerivedClassIsVirtual=*/false,
|
||||
LayoutClass);
|
||||
|
||||
if (CGM.getLangOptions().DumpVtableLayouts)
|
||||
Builder.dumpLayout(llvm::errs());
|
||||
} else if (CGM.getLangOptions().DumpVtableLayouts) {
|
||||
// We only build construction vtables when dumping vtable layouts for now.
|
||||
VtableBuilder Builder(*this, RD, Offset, LayoutClass);
|
||||
VtableBuilder Builder(*this, RD, Offset,
|
||||
/*MostDerivedClassIsVirtual=*/IsVirtual,
|
||||
LayoutClass);
|
||||
Builder.dumpLayout(llvm::errs());
|
||||
}
|
||||
}
|
||||
|
@ -3390,6 +3403,7 @@ void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
|
|||
|
||||
AddressPointsMapTy AddressPoints;
|
||||
Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
|
||||
/*IsVirtual=*/false,
|
||||
AddressPoints);
|
||||
GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
|
||||
}
|
||||
|
@ -3401,7 +3415,7 @@ llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
|
|||
AddressPointsMapTy AddressPoints;
|
||||
Vtable = GenerateVtable(llvm::GlobalValue::ExternalLinkage,
|
||||
/*GenerateDefinition=*/false, RD, RD, 0,
|
||||
AddressPoints);
|
||||
/*IsVirtual=*/false, AddressPoints);
|
||||
}
|
||||
|
||||
return Vtable;
|
||||
|
|
|
@ -185,7 +185,7 @@ private:
|
|||
llvm::GlobalVariable *
|
||||
GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
|
||||
bool GenerateDefinition, const CXXRecordDecl *LayoutClass,
|
||||
const CXXRecordDecl *RD, uint64_t Offset,
|
||||
const CXXRecordDecl *RD, uint64_t Offset, bool IsVirtual,
|
||||
AddressPointsMapTy& AddressPoints);
|
||||
|
||||
llvm::GlobalVariable *GenerateVTT(llvm::GlobalVariable::LinkageTypes Linkage,
|
||||
|
@ -239,7 +239,8 @@ public:
|
|||
};
|
||||
|
||||
CtorVtableInfo getCtorVtable(const CXXRecordDecl *RD,
|
||||
const BaseSubobject &Base);
|
||||
const BaseSubobject &Base,
|
||||
bool BaseIsVirtual);
|
||||
|
||||
llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче