[cfe-commits] r78971 - in /cfe/trunk: include/clang/AST/RecordLayout.h lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h lib/CodeGen/CGCXX.cpp
Mike Stump
mrs at apple.com
Thu Aug 13 18:44:03 PDT 2009
Author: mrs
Date: Thu Aug 13 20:44:03 2009
New Revision: 78971
URL: http://llvm.org/viewvc/llvm-project?rev=78971&view=rev
Log:
Deconflate virtual base offsets from non-virtual base offsets.
Deconflate a virtual base primary from a non-virtual base.
Modified:
cfe/trunk/include/clang/AST/RecordLayout.h
cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
cfe/trunk/lib/AST/RecordLayoutBuilder.h
cfe/trunk/lib/CodeGen/CGCXX.cpp
Modified: cfe/trunk/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecordLayout.h?rev=78971&r1=78970&r2=78971&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Thu Aug 13 20:44:03 2009
@@ -60,10 +60,12 @@
bool PrimaryBaseWasVirtual;
/// BaseOffsets - Contains a map from base classes to their offset.
- /// FIXME: Does it make sense to store offsets for virtual base classes
- /// here?
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets;
+
+ /// VBaseOffsets - Contains a map from vbase classes to their offset.
+ /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
+ llvm::DenseMap<const CXXRecordDecl *, uint64_t> VBaseOffsets;
};
/// CXXInfo - If the record layout is for a C++ record, this will have
@@ -90,7 +92,8 @@
uint64_t nonvirtualsize, unsigned nonvirtualalign,
const CXXRecordDecl *PB, bool PBVirtual,
const CXXRecordDecl **bases, const uint64_t *baseoffsets,
- unsigned basecount)
+ unsigned basecount, const CXXRecordDecl **vbases,
+ const uint64_t *vbaseoffsets,unsigned vbasecount)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
if (FieldCount > 0) {
@@ -105,6 +108,8 @@
CXXInfo->NonVirtualAlign = nonvirtualalign;
for (unsigned i = 0; i != basecount; ++i)
CXXInfo->BaseOffsets[bases[i]] = baseoffsets[i];
+ for (unsigned i = 0; i != vbasecount; ++i)
+ CXXInfo->VBaseOffsets[vbases[i]] = vbaseoffsets[i];
}
~ASTRecordLayout() {
@@ -174,6 +179,14 @@
return CXXInfo->BaseOffsets[Base];
}
+
+ /// getVBaseClassOffset - Get the offset, in bits, for the given base class.
+ uint64_t getVBaseClassOffset(const CXXRecordDecl *VBase) const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+ assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
+
+ return CXXInfo->VBaseOffsets[VBase];
+ }
};
} // end namespace clang
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=78971&r1=78970&r2=78971&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Thu Aug 13 20:44:03 2009
@@ -51,8 +51,8 @@
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
// Skip the PrimaryBase here, as it is laid down first.
- if (Base != PrimaryBase)
- LayoutBaseNonVirtually(Base);
+ if (Base != PrimaryBase || PrimaryBaseWasVirtual)
+ LayoutBaseNonVirtually(Base, false);
}
}
}
@@ -77,9 +77,10 @@
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
- if (PrimaryBaseWasVirtual) {
+
+ if (PrimaryBaseWasVirtual)
IndirectPrimary.insert(PrimaryBase);
- }
+
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) {
const CXXRecordDecl *Base =
@@ -163,7 +164,7 @@
}
void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
- LayoutBaseNonVirtually(RD);
+ LayoutBaseNonVirtually(RD, true);
}
void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
@@ -182,7 +183,8 @@
}
}
-void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD) {
+void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD,
+ bool IsVirtualBase) {
const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
assert(BaseInfo.getDataSize() > 0 &&
"FIXME: Handle empty classes.");
@@ -193,9 +195,14 @@
// Round up the current record size to the base's alignment boundary.
Size = (Size + (BaseAlign-1)) & ~(BaseAlign-1);
- // Add base class offsets.
- Bases.push_back(RD);
- BaseOffsets.push_back(Size);
+ // Add base class offsets.
+ if (IsVirtualBase) {
+ VBases.push_back(RD);
+ VBaseOffsets.push_back(Size);
+ } else {
+ Bases.push_back(RD);
+ BaseOffsets.push_back(Size);
+ }
// Reserve space for this base.
Size += BaseSize;
@@ -229,7 +236,7 @@
if (PrimaryBase) {
if (PrimaryBaseWasVirtual)
IndirectPrimary.insert(PrimaryBase);
- LayoutBaseNonVirtually(PrimaryBase);
+ LayoutBaseNonVirtually(PrimaryBase, PrimaryBaseWasVirtual);
}
LayoutNonVirtualBases(RD);
}
@@ -406,6 +413,8 @@
assert(Builder.Bases.size() == Builder.BaseOffsets.size() &&
"Base offsets vector must be same size as bases vector!");
+ assert(Builder.VBases.size() == Builder.VBaseOffsets.size() &&
+ "Base offsets vector must be same size as bases vector!");
// FIXME: This should be done in FinalizeLayout.
uint64_t DataSize =
@@ -422,7 +431,10 @@
Builder.PrimaryBaseWasVirtual,
Builder.Bases.data(),
Builder.BaseOffsets.data(),
- Builder.Bases.size());
+ Builder.Bases.size(),
+ Builder.VBases.data(),
+ Builder.VBaseOffsets.data(),
+ Builder.VBases.size());
}
const ASTRecordLayout *
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=78971&r1=78970&r2=78971&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Thu Aug 13 20:44:03 2009
@@ -42,6 +42,9 @@
llvm::SmallVector<const CXXRecordDecl *, 4> Bases;
llvm::SmallVector<uint64_t, 4> BaseOffsets;
+
+ llvm::SmallVector<const CXXRecordDecl *, 4> VBases;
+ llvm::SmallVector<uint64_t, 4> VBaseOffsets;
ASTRecordLayoutBuilder(ASTContext &Ctx);
@@ -68,7 +71,7 @@
void LayoutVtable(const CXXRecordDecl *RD,
llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
- void LayoutBaseNonVirtually(const CXXRecordDecl *RD);
+ void LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVBase);
void LayoutVirtualBase(const CXXRecordDecl *RD);
void LayoutVirtualBases(const CXXRecordDecl *RD,
llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=78971&r1=78970&r2=78971&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Thu Aug 13 20:44:03 2009
@@ -703,6 +703,7 @@
if (isPrimary) {
// The virtual base offsets come first...
+ // FIXME: audit
for (CXXRecordDecl::reverse_base_class_const_iterator i
= Class->bases_rbegin(),
e = Class->bases_rend(); i != e; ++i) {
@@ -710,7 +711,7 @@
continue;
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
- int64_t BaseOffset = Layout.getBaseClassOffset(Base) / 8;
+ int64_t BaseOffset = Layout.getVBaseClassOffset(Base) / 8;
llvm::Constant *m;
m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
@@ -741,7 +742,11 @@
if (TopPrimary) {
if (RD) {
- int64_t BaseOffset = -(Layout.getBaseClassOffset(RD) / 8);
+ int64_t BaseOffset;
+ if (ForVirtualBase)
+ BaseOffset = -(Layout.getVBaseClassOffset(RD) / 8);
+ else
+ BaseOffset = -(Layout.getBaseClassOffset(RD) / 8);
m = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), BaseOffset);
m = llvm::ConstantExpr::getIntToPtr(m, Ptr8Ty);
}
@@ -784,13 +789,15 @@
// The primary base comes first.
GenerateVtableForBase(PrimaryBase, RD, rtti, methods, true,
PrimaryBaseWasVirtual, IndirectPrimary);
+
+ // Then come the non-virtual bases.
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) {
if (i->isVirtual())
continue;
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
- if (Base != PrimaryBase)
+ if (Base != PrimaryBase || PrimaryBaseWasVirtual)
GenerateVtableForBase(Base, RD, rtti, methods, false, false,
IndirectPrimary);
}
More information about the cfe-commits
mailing list