[cfe-commits] r86116 - in /cfe/trunk/lib/AST: RecordLayoutBuilder.cpp RecordLayoutBuilder.h
Mike Stump
mrs at apple.com
Wed Nov 4 20:02:15 PST 2009
Author: mrs
Date: Wed Nov 4 22:02:15 2009
New Revision: 86116
URL: http://llvm.org/viewvc/llvm-project?rev=86116&view=rev
Log:
Refine layout for indirect virtual base classes.
Modified:
cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
cfe/trunk/lib/AST/RecordLayoutBuilder.h
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=86116&r1=86115&r2=86116&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Wed Nov 4 22:02:15 2009
@@ -174,9 +174,24 @@
LayoutBaseNonVirtually(RD, true);
}
-void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
+uint64_t ASTRecordLayoutBuilder::getBaseOffset(const CXXRecordDecl *Base) {
+ for (size_t i = 0; i < Bases.size(); ++i) {
+ if (Bases[i].first == Base)
+ return Bases[i].second;
+ }
+ for (size_t i = 0; i < VBases.size(); ++i) {
+ if (VBases[i].first == Base)
+ return VBases[i].second;
+ }
+ assert(0 && "missing base");
+ return 0;
+}
+
+
+void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
+ const CXXRecordDecl *RD,
const CXXRecordDecl *PB,
- int64_t Offset,
+ uint64_t Offset,
llvm::SmallSet<const CXXRecordDecl*, 32> &mark,
llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) {
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
@@ -185,20 +200,7 @@
"Cannot layout class with dependent bases.");
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-#if 0
- const ASTRecordLayout &L = Ctx.getASTRecordLayout(Base);
- const CXXRecordDecl *PB = L.getPrimaryBase();
- if (PB && L.getPrimaryBaseWasVirtual()
- && IndirectPrimary.count(PB)) {
- int64_t BaseOffset;
- // FIXME: calculate this.
- BaseOffset = (1<<63) | (1<<31);
- VBases.push_back(PB);
- VBaseOffsets.push_back(BaseOffset);
- }
-#endif
- int64_t BaseOffset = Offset;;
- // FIXME: Calculate BaseOffset.
+ uint64_t BaseOffset = Offset;
if (i->isVirtual()) {
if (Base == PB) {
// Only lay things out once.
@@ -220,11 +222,20 @@
LayoutVirtualBase(Base);
BaseOffset = VBases.back().second;
}
+ } else {
+ if (RD == Class)
+ BaseOffset = getBaseOffset(Base);
+ else {
+ const ASTRecordLayout &Layout
+ = Ctx.getASTRecordLayout(RD);
+ BaseOffset = Offset + Layout.getBaseClassOffset(Base);
+ }
}
+
if (Base->getNumVBases()) {
const ASTRecordLayout &L = Ctx.getASTRecordLayout(Base);
const CXXRecordDecl *PB = L.getPrimaryBase();
- LayoutVirtualBases(Base, PB, BaseOffset, mark, IndirectPrimary);
+ LayoutVirtualBases(Class, Base, PB, BaseOffset, mark, IndirectPrimary);
}
}
}
@@ -295,7 +306,7 @@
const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
uint64_t NumElements = Ctx.getConstantArrayElementCount(AT);
- unsigned ElementOffset = Offset;
+ uint64_t ElementOffset = Offset;
for (uint64_t I = 0; I != NumElements; ++I) {
if (!canPlaceRecordAtOffset(RD, ElementOffset))
return false;
@@ -366,7 +377,7 @@
const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
uint64_t NumElements = Ctx.getConstantArrayElementCount(AT);
- unsigned ElementOffset = Offset;
+ uint64_t ElementOffset = Offset;
for (uint64_t I = 0; I != NumElements; ++I) {
UpdateEmptyClassOffsets(RD, ElementOffset);
@@ -419,29 +430,13 @@
void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD,
bool IsVirtualBase) {
// Layout the base.
- unsigned Offset = LayoutBase(RD);
+ uint64_t Offset = LayoutBase(RD);
// Add base class offsets.
if (IsVirtualBase)
VBases.push_back(std::make_pair(RD, Offset));
else
Bases.push_back(std::make_pair(RD, Offset));
-
-#if 0
- // And now add offsets for all our primary virtual bases as well, so
- // they all have offsets.
- const ASTRecordLayout *L = &BaseInfo;
- const CXXRecordDecl *PB = L->getPrimaryBase();
- while (PB) {
- if (L->getPrimaryBaseWasVirtual()) {
- VBases.push_back(PB);
- VBaseOffsets.push_back(Size);
- }
- PB = L->getPrimaryBase();
- if (PB)
- L = &Ctx.getASTRecordLayout(PB);
- }
-#endif
}
void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
@@ -476,7 +471,7 @@
if (RD) {
llvm::SmallSet<const CXXRecordDecl*, 32> mark;
- LayoutVirtualBases(RD, PrimaryBase, 0, mark, IndirectPrimaryBases);
+ LayoutVirtualBases(RD, RD, PrimaryBase, 0, mark, IndirectPrimaryBases);
}
// Finally, round the size of the total struct up to the alignment of the
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=86116&r1=86115&r2=86116&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Wed Nov 4 22:02:15 2009
@@ -99,9 +99,9 @@
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
void LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVBase);
void LayoutVirtualBase(const CXXRecordDecl *RD);
- void LayoutVirtualBases(const CXXRecordDecl *RD, const CXXRecordDecl *PB,
- int64_t Offset,
- llvm::SmallSet<const CXXRecordDecl*, 32> &mark,
+ void LayoutVirtualBases(const CXXRecordDecl *Class, const CXXRecordDecl *RD,
+ const CXXRecordDecl *PB, uint64_t Offset,
+ llvm::SmallSet<const CXXRecordDecl*, 32> &mark,
llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
/// canPlaceRecordAtOffset - Return whether a record (either a base class
@@ -124,6 +124,9 @@
/// given offset.
void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset);
+ /// getBaseOffset - Get the offset of a direct base class.
+ uint64_t getBaseOffset(const CXXRecordDecl *Base);
+
/// FinishLayout - Finalize record layout. Adjust record size based on the
/// alignment.
void FinishLayout();
More information about the cfe-commits
mailing list