From 0c54fc91322faaa78422c3aaec261a26e45d7f8c Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Wed, 26 May 2010 15:54:25 +0000 Subject: [PATCH] Move ComputeEmptySubobjectSizes to EmptySubobjectMap. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104702 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/RecordLayoutBuilder.cpp | 126 ++++++++++++++++---------------- 1 file 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(I->getType()->getAs()->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(); + + // We only care about record types. + if (!RT) + continue; + + uint64_t EmptySize = 0; + const CXXRecordDecl *MemberDecl = cast(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 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 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(I->getType()->getAs()->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(); - - // We only care about record types. - if (!RT) - continue; - - uint64_t EmptySize = 0; - const CXXRecordDecl *MemberDecl = cast(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); -- 2.40.0