[cfe-commits] r120257 - /cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
Anders Carlsson
andersca at mac.com
Sun Nov 28 11:18:44 PST 2010
Author: andersca
Date: Sun Nov 28 13:18:44 2010
New Revision: 120257
URL: http://llvm.org/viewvc/llvm-project?rev=120257&view=rev
Log:
More work on laying out virtual bases.
Modified:
cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
Modified: cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=120257&r1=120256&r2=120257&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRecordLayoutBuilder.cpp Sun Nov 28 13:18:44 2010
@@ -69,6 +69,10 @@
/// primary base classes for some other direct or indirect base class.
CXXIndirectPrimaryBaseSet IndirectPrimaryBases;
+ /// LaidOutVirtualBases - A set of all laid out virtual bases, used to avoid
+ /// avoid laying out virtual bases more than once.
+ llvm::SmallPtrSet<const CXXRecordDecl *, 4> LaidOutVirtualBases;
+
/// IsZeroInitializable - Whether this struct can be C++
/// zero-initialized with an LLVM zeroinitializer.
bool IsZeroInitializable;
@@ -110,11 +114,15 @@
/// LayoutVirtualBase - layout a single virtual base.
void LayoutVirtualBase(const CXXRecordDecl *BaseDecl, uint64_t BaseOffset);
+ /// LayoutVirtualBases - layout the virtual bases of a record decl.
+ void LayoutVirtualBases(const CXXRecordDecl *RD,
+ const ASTRecordLayout &Layout);
+
/// LayoutNonVirtualBase - layout a single non-virtual base.
void LayoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
uint64_t BaseOffset);
- /// LayoutNonVirtualBases - layout the non-virtual bases of a record decl.
+ /// LayoutNonVirtualBases - layout the virtual bases of a record decl.
void LayoutNonVirtualBases(const CXXRecordDecl *RD,
const ASTRecordLayout &Layout);
@@ -513,6 +521,35 @@
}
+/// LayoutVirtualBases - layout the non-virtual bases of a record decl.
+void
+CGRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
+ const ASTRecordLayout &Layout) {
+ for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+ E = RD->bases_end(); I != E; ++I) {
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ // We only want to lay out virtual bases that aren't indirect primary bases
+ // of some other base.
+ if (I->isVirtual() && !IndirectPrimaryBases.count(BaseDecl)) {
+ // Only lay out the base once.
+ if (!LaidOutVirtualBases.insert(BaseDecl))
+ continue;
+
+ uint64_t VBaseOffset = Layout.getVBaseClassOffsetInBits(BaseDecl);
+ LayoutVirtualBase(BaseDecl, VBaseOffset);
+ }
+
+ if (!BaseDecl->getNumVBases()) {
+ // This base isn't interesting since it doesn't have any virtual bases.
+ continue;
+ }
+
+ LayoutVirtualBases(BaseDecl, Layout);
+ }
+}
+
void CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
uint64_t BaseOffset) {
// Ignore empty bases.
@@ -630,17 +667,17 @@
}
}
- // We've laid out the non-virtual bases and the fields, now compute the
- // non-virtual base field types.
- if (RD)
- ComputeNonVirtualBaseType(RD);
-
if (RD) {
+ // We've laid out the non-virtual bases and the fields, now compute the
+ // non-virtual base field types.
+ ComputeNonVirtualBaseType(RD);
+
+ // And lay out the virtual bases.
RD->getIndirectPrimaryBases(IndirectPrimaryBases);
+ if (Layout.isPrimaryBaseVirtual())
+ IndirectPrimaryBases.insert(Layout.getPrimaryBase());
+ LayoutVirtualBases(RD, Layout);
}
-
- // FIXME: Lay out the virtual bases instead of just treating them as tail
- // padding.
// Append tail padding if necessary.
AppendTailPadding(Layout.getSize());
More information about the cfe-commits
mailing list