From: Anders Carlsson Date: Wed, 10 Mar 2010 22:21:28 +0000 (+0000) Subject: More shuffling. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e239b9d5da3bdc722d29c276b261c136ca9f4eaa;p=clang More shuffling. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98197 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 68e54fd1df..666b1242d5 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -41,22 +41,6 @@ void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) { } } -void -ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { - for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), - e = RD->bases_end(); i != e; ++i) { - if (!i->isVirtual()) { - assert(!i->getType()->isDependentType() && - "Cannot layout class with dependent bases."); - const CXXRecordDecl *Base = - cast(i->getType()->getAs()->getDecl()); - // Skip the PrimaryBase here, as it is laid down first. - if (Base != PrimaryBase.getBase() || PrimaryBase.isVirtual()) - LayoutBaseNonVirtually(Base, false); - } - } -} - /// IsNearlyEmpty - Indicates when a class has a vtable pointer, but /// no other data. bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const { @@ -174,10 +158,6 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { setPrimaryBase(FirstPrimary, /*IsVirtual=*/true); } -void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) { - LayoutBaseNonVirtually(RD, true); -} - uint64_t ASTRecordLayoutBuilder::getBaseOffset(const CXXRecordDecl *Base) { for (size_t i = 0; i < Bases.size(); ++i) { if (Bases[i].first == Base) @@ -191,6 +171,25 @@ uint64_t ASTRecordLayoutBuilder::getBaseOffset(const CXXRecordDecl *Base) { return 0; } +void +ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { + for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), + e = RD->bases_end(); i != e; ++i) { + if (!i->isVirtual()) { + assert(!i->getType()->isDependentType() && + "Cannot layout class with dependent bases."); + const CXXRecordDecl *Base = + cast(i->getType()->getAs()->getDecl()); + // Skip the PrimaryBase here, as it is laid down first. + if (Base != PrimaryBase.getBase() || PrimaryBase.isVirtual()) + LayoutBaseNonVirtually(Base, false); + } + } +} + +void ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) { + LayoutBaseNonVirtually(RD, false); +} void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class, const CXXRecordDecl *RD, @@ -244,6 +243,51 @@ void ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class, } } +void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) { + LayoutBaseNonVirtually(RD, true); +} + +uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) { + const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD); + + // If we have an empty base class, try to place it at offset 0. + if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0)) { + // We were able to place the class at offset 0. + UpdateEmptyClassOffsets(RD, 0); + + Size = std::max(Size, BaseInfo.getSize()); + + return 0; + } + + unsigned BaseAlign = BaseInfo.getNonVirtualAlign(); + + // Round up the current record size to the base's alignment boundary. + uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign); + + // Try to place the base. + while (true) { + if (canPlaceRecordAtOffset(RD, Offset)) + break; + + Offset += BaseAlign; + } + + if (!RD->isEmpty()) { + // Update the data size. + DataSize = Offset + BaseInfo.getNonVirtualSize(); + + Size = std::max(Size, DataSize); + } else + Size = std::max(Size, Offset + BaseInfo.getSize()); + + // Remember max struct/class alignment. + UpdateAlignment(BaseAlign); + + UpdateEmptyClassOffsets(RD, Offset); + return Offset; +} + bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset) const { // Look for an empty class with the same type at the same offset. @@ -390,47 +434,6 @@ ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD, } } -uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) { - const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD); - - // If we have an empty base class, try to place it at offset 0. - if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0)) { - // We were able to place the class at offset 0. - UpdateEmptyClassOffsets(RD, 0); - - Size = std::max(Size, BaseInfo.getSize()); - - return 0; - } - - unsigned BaseAlign = BaseInfo.getNonVirtualAlign(); - - // Round up the current record size to the base's alignment boundary. - uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign); - - // Try to place the base. - while (true) { - if (canPlaceRecordAtOffset(RD, Offset)) - break; - - Offset += BaseAlign; - } - - if (!RD->isEmpty()) { - // Update the data size. - DataSize = Offset + BaseInfo.getNonVirtualSize(); - - Size = std::max(Size, DataSize); - } else - Size = std::max(Size, Offset + BaseInfo.getSize()); - - // Remember max struct/class alignment. - UpdateAlignment(BaseAlign); - - UpdateEmptyClassOffsets(RD, Offset); - return Offset; -} - void ASTRecordLayoutBuilder::LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVirtualBase) { // Layout the base. diff --git a/lib/AST/RecordLayoutBuilder.h b/lib/AST/RecordLayoutBuilder.h index ef22060b87..9a918b1c8a 100644 --- a/lib/AST/RecordLayoutBuilder.h +++ b/lib/AST/RecordLayoutBuilder.h @@ -101,10 +101,6 @@ class ASTRecordLayoutBuilder { bool IsNearlyEmpty(const CXXRecordDecl *RD) const; - /// LayoutBase - Will lay out a base and return the offset where it was - /// placed, in bits. - uint64_t LayoutBase(const CXXRecordDecl *RD); - /// LayoutNonVirtualBases - Determines the primary base class (if any) and /// lays it out. Will then proceed to lay out all non-virtual base clasess. void LayoutNonVirtualBases(const CXXRecordDecl *RD); @@ -121,6 +117,10 @@ class ASTRecordLayoutBuilder { /// LayoutVirtualBase - Lays out a single virtual base. void LayoutVirtualBase(const CXXRecordDecl *RD); + /// LayoutBase - Will lay out a base and return the offset where it was + /// placed, in bits. + uint64_t LayoutBase(const CXXRecordDecl *RD); + void LayoutVtable(const CXXRecordDecl *RD); void LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVBase);