aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/RecordLayoutBuilder.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-05-26 15:54:25 +0000
committerAnders Carlsson <andersca@mac.com>2010-05-26 15:54:25 +0000
commit0c54fc91322faaa78422c3aaec261a26e45d7f8c (patch)
tree9dbd2bb015757183a671fd8e74dba0dec11271a0 /lib/AST/RecordLayoutBuilder.cpp
parent6a91c0328c81fe1be4e5380fb0e586cafee53b26 (diff)
Move ComputeEmptySubobjectSizes to EmptySubobjectMap.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104702 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp126
1 files changed, 65 insertions, 61 deletions
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 69aa0113b4..e845bdad6c 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -31,12 +31,70 @@ class EmptySubobjectMap {
/// Class - The class whose empty entries we're keeping track of.
const CXXRecordDecl *Class;
+ /// ComputeEmptySubobjectSizes - Compute the size of the largest base or
+ /// member subobject that is empty.
+ void ComputeEmptySubobjectSizes();
+
public:
+ /// This holds the size of the largest empty subobject (either a base
+ /// or a member). Will be zero if the record being built doesn't contain
+ /// any empty classes.
+ uint64_t SizeOfLargestEmptySubobject;
+
EmptySubobjectMap(ASTContext &Context, const CXXRecordDecl *Class)
- : Context(Context), Class(Class) { }
+ : Context(Context), Class(Class), SizeOfLargestEmptySubobject(0) { }
};
+
+void EmptySubobjectMap::ComputeEmptySubobjectSizes() {
+ // Check the bases.
+ for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
+ E = Class->bases_end(); I != E; ++I) {
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ uint64_t EmptySize = 0;
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
+ if (BaseDecl->isEmpty()) {
+ // If the class decl is empty, get its size.
+ EmptySize = Layout.getSize();
+ } else {
+ // Otherwise, we get the largest empty subobject for the decl.
+ EmptySize = Layout.getSizeOfLargestEmptySubobject();
+ }
+
+ SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
+ EmptySize);
+ }
+ // Check the fields.
+ for (CXXRecordDecl::field_iterator I = Class->field_begin(),
+ E = Class->field_end(); I != E; ++I) {
+ const FieldDecl *FD = *I;
+
+ const RecordType *RT =
+ Context.getBaseElementType(FD->getType())->getAs<RecordType>();
+
+ // We only care about record types.
+ if (!RT)
+ continue;
+
+ uint64_t EmptySize = 0;
+ const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl());
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
+ if (MemberDecl->isEmpty()) {
+ // If the class decl is empty, get its size.
+ EmptySize = Layout.getSize();
+ } else {
+ // Otherwise, we get the largest empty subobject for the decl.
+ EmptySize = Layout.getSizeOfLargestEmptySubobject();
+ }
+
+ SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
+ EmptySize);
+ }
+}
+
class RecordLayoutBuilder {
// FIXME: Remove this and make the appropriate fields public.
friend class clang::ASTContext;
@@ -100,11 +158,6 @@ class RecordLayoutBuilder {
/// VisitedVirtualBases - A set of all the visited virtual bases, used to
/// avoid visiting virtual bases more than once.
llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
-
- /// SizeOfLargestEmptySubobject - When laying out C++ classes, this holds the
- /// size of the largest empty subobject (either a base or a member).
- /// Will be zero if the record being built doesn't contain any empty classes.
- uint64_t SizeOfLargestEmptySubobject;
/// EmptyClassOffsets - A map from offsets to empty record decls.
typedef std::multimap<uint64_t, const CXXRecordDecl *> EmptyClassOffsetsTy;
@@ -114,8 +167,7 @@ class RecordLayoutBuilder {
: Context(Context), EmptySubobjects(0), Size(0), Alignment(8),
Packed(false), UnfilledBitsInLastByte(0), MaxFieldAlignment(0), DataSize(0),
IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8), PrimaryBase(0),
- PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0),
- SizeOfLargestEmptySubobject(0) { }
+ PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { }
void Layout(const RecordDecl *D);
void Layout(const CXXRecordDecl *D);
@@ -198,6 +250,10 @@ class RecordLayoutBuilder {
void operator=(const RecordLayoutBuilder&); // DO NOT IMPLEMENT
public:
static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD);
+
+ uint64_t getSizeOfLargestEmptySubobject() {
+ return EmptySubobjects->SizeOfLargestEmptySubobject;
+ }
};
} // end anonymous namespace
@@ -213,56 +269,6 @@ bool RecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
return false;
}
-void
-RecordLayoutBuilder::ComputeEmptySubobjectSizes(const CXXRecordDecl *RD) {
- // Check the bases.
- 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());
-
- uint64_t EmptySize = 0;
- const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
- if (BaseDecl->isEmpty()) {
- // If the class decl is empty, get its size.
- EmptySize = Layout.getSize();
- } else {
- // Otherwise, we get the largest empty subobject for the decl.
- EmptySize = Layout.getSizeOfLargestEmptySubobject();
- }
-
- SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
- EmptySize);
- }
-
- // Check the fields.
- for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
- I != E; ++I) {
- const FieldDecl *FD = *I;
-
- const RecordType *RT =
- Context.getBaseElementType(FD->getType())->getAs<RecordType>();
-
- // We only care about record types.
- if (!RT)
- continue;
-
- uint64_t EmptySize = 0;
- const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl());
- const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
- if (MemberDecl->isEmpty()) {
- // If the class decl is empty, get its size.
- EmptySize = Layout.getSize();
- } else {
- // Otherwise, we get the largest empty subobject for the decl.
- EmptySize = Layout.getSizeOfLargestEmptySubobject();
- }
-
- SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
- EmptySize);
- }
-}
-
void RecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
Context.getASTRecordLayout(RD).getPrimaryBaseInfo();
@@ -780,8 +786,6 @@ void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
InitializeLayout(RD);
- ComputeEmptySubobjectSizes(RD);
-
// Lay out the vtable and the non-virtual bases.
LayoutNonVirtualBases(RD);
@@ -1141,7 +1145,7 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
Builder.FieldOffsets.size(),
NonVirtualSize,
Builder.NonVirtualAlignment,
- Builder.SizeOfLargestEmptySubobject,
+ Builder.getSizeOfLargestEmptySubobject(),
Builder.PrimaryBase,
Builder.PrimaryBaseIsVirtual,
Builder.Bases, Builder.VBases);