From 28466ab8f4be93eae4d8aa82dd59da298b2ed268 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 31 Oct 2010 22:13:23 +0000 Subject: [PATCH] EmptyObjectMap now uses CharUnits wherever possible. llvm-svn: 117877 --- clang/include/clang/AST/RecordLayout.h | 6 +- clang/lib/AST/RecordLayout.cpp | 2 +- clang/lib/AST/RecordLayoutBuilder.cpp | 122 ++++++++++++------------- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/clang/include/clang/AST/RecordLayout.h b/clang/include/clang/AST/RecordLayout.h index 875e314063f1..1188e280fba7 100644 --- a/clang/include/clang/AST/RecordLayout.h +++ b/clang/include/clang/AST/RecordLayout.h @@ -113,7 +113,7 @@ private: /// SizeOfLargestEmptySubobject - The size of the largest empty subobject /// (either a base or a member). Will be zero if the class doesn't contain /// any empty subobjects. - uint64_t SizeOfLargestEmptySubobject; + CharUnits SizeOfLargestEmptySubobject; /// PrimaryBase - The primary base info for this record. PrimaryBaseInfo PrimaryBase; @@ -144,7 +144,7 @@ private: uint64_t size, unsigned alignment, uint64_t datasize, const uint64_t *fieldoffsets, unsigned fieldcount, uint64_t nonvirtualsize, unsigned nonvirtualalign, - uint64_t SizeOfLargestEmptySubobject, + CharUnits SizeOfLargestEmptySubobject, const CXXRecordDecl *PrimaryBase, bool PrimaryBaseIsVirtual, const BaseOffsetsMapTy& BaseOffsets, @@ -231,7 +231,7 @@ public: VBase->getASTContext().getCharWidth(); } - uint64_t getSizeOfLargestEmptySubobject() const { + CharUnits getSizeOfLargestEmptySubobject() const { assert(CXXInfo && "Record layout does not have C++ specific info!"); return CXXInfo->SizeOfLargestEmptySubobject; } diff --git a/clang/lib/AST/RecordLayout.cpp b/clang/lib/AST/RecordLayout.cpp index 4d9c51633626..2124c9cbcc78 100644 --- a/clang/lib/AST/RecordLayout.cpp +++ b/clang/lib/AST/RecordLayout.cpp @@ -46,7 +46,7 @@ ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, unsigned fieldcount, uint64_t nonvirtualsize, unsigned nonvirtualalign, - uint64_t SizeOfLargestEmptySubobject, + CharUnits SizeOfLargestEmptySubobject, const CXXRecordDecl *PrimaryBase, bool PrimaryBaseIsVirtual, const BaseOffsetsMapTy& BaseOffsets, diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index d0a48fd891ab..d6af3eed4a7f 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -78,12 +78,12 @@ class EmptySubobjectMap { void AddSubobjectAtOffset(const CXXRecordDecl *RD, CharUnits Offset); void UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, - uint64_t Offset, bool PlacingEmptyBase); + CharUnits Offset, bool PlacingEmptyBase); void UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, const CXXRecordDecl *Class, - uint64_t Offset); - void UpdateEmptyFieldSubobjects(const FieldDecl *FD, uint64_t Offset); + CharUnits Offset); + void UpdateEmptyFieldSubobjects(const FieldDecl *FD, CharUnits Offset); /// AnyEmptySubobjectsBeyondOffset - Returns whether there are any empty /// subobjects beyond the given offset. @@ -100,24 +100,21 @@ class EmptySubobjectMap { return CharUnits::fromQuantity(FieldOffset / CharWidth); } - // FIXME: Remove these. + // FIXME: Remove this. CharUnits toCharUnits(uint64_t Offset) const { return CharUnits::fromQuantity(Offset / CharWidth); } - uint64_t toOffset(CharUnits Offset) const { - return Offset.getQuantity() * CharWidth; - } protected: bool CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, CharUnits Offset) const; bool CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, - uint64_t Offset); + CharUnits Offset); bool CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, const CXXRecordDecl *Class, - uint64_t Offset) const; + CharUnits Offset) const; bool CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, CharUnits Offset) const; @@ -125,11 +122,10 @@ 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; + CharUnits SizeOfLargestEmptySubobject; EmptySubobjectMap(ASTContext &Context, const CXXRecordDecl *Class) - : Context(Context), CharWidth(Context.getCharWidth()), Class(Class), - SizeOfLargestEmptySubobject(0) { + : Context(Context), CharWidth(Context.getCharWidth()), Class(Class) { ComputeEmptySubobjectSizes(); } @@ -138,11 +134,11 @@ public: /// Returns false if placing the record will result in two components /// (direct or indirect) of the same type having the same offset. bool CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, - uint64_t Offset); + CharUnits Offset); /// CanPlaceFieldAtOffset - Return whether a field can be placed at the given /// offset. - bool CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset); + bool CanPlaceFieldAtOffset(const FieldDecl *FD, CharUnits Offset); }; void EmptySubobjectMap::ComputeEmptySubobjectSizes() { @@ -152,18 +148,18 @@ void EmptySubobjectMap::ComputeEmptySubobjectSizes() { const CXXRecordDecl *BaseDecl = cast(I->getType()->getAs()->getDecl()); - uint64_t EmptySize = 0; + CharUnits EmptySize; const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); if (BaseDecl->isEmpty()) { // If the class decl is empty, get its size. - EmptySize = Layout.getSize(); + EmptySize = toCharUnits(Layout.getSize()); } else { // Otherwise, we get the largest empty subobject for the decl. EmptySize = Layout.getSizeOfLargestEmptySubobject(); } - SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject, - EmptySize); + if (EmptySize > SizeOfLargestEmptySubobject) + SizeOfLargestEmptySubobject = EmptySize; } // Check the fields. @@ -178,19 +174,19 @@ void EmptySubobjectMap::ComputeEmptySubobjectSizes() { if (!RT) continue; - uint64_t EmptySize = 0; + CharUnits EmptySize; 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(); + EmptySize = toCharUnits(Layout.getSize()); } else { // Otherwise, we get the largest empty subobject for the decl. EmptySize = Layout.getSizeOfLargestEmptySubobject(); } - SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject, - EmptySize); + if (EmptySize > SizeOfLargestEmptySubobject) + SizeOfLargestEmptySubobject = EmptySize; } } @@ -231,14 +227,14 @@ void EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD, } bool -EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, - uint64_t Offset) { +EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, + CharUnits Offset) { // We don't have to keep looking past the maximum offset that's known to // contain an empty class. - if (!AnyEmptySubobjectsBeyondOffset(toCharUnits(Offset))) + if (!AnyEmptySubobjectsBeyondOffset(Offset)) return true; - if (!CanPlaceSubobjectAtOffset(Info->Class, toCharUnits(Offset))) + if (!CanPlaceSubobjectAtOffset(Info->Class, Offset)) return false; // Traverse all non-virtual bases. @@ -248,7 +244,8 @@ EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, if (Base->IsVirtual) continue; - uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); + CharUnits BaseOffset = + Offset + toCharUnits(Layout.getBaseClassOffset(Base->Class)); if (!CanPlaceBaseSubobjectAtOffset(Base, BaseOffset)) return false; @@ -271,8 +268,7 @@ EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, if (FD->isBitField()) continue; - CharUnits FieldOffset = - toCharUnits(Offset) + getFieldOffset(Layout, FieldNo); + CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset)) return false; } @@ -281,7 +277,7 @@ EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, } void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, - uint64_t Offset, + CharUnits Offset, bool PlacingEmptyBase) { if (!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) { // We know that the only empty subobjects that can conflict with empty @@ -292,7 +288,7 @@ void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, return; } - AddSubobjectAtOffset(Info->Class, toCharUnits(Offset)); + AddSubobjectAtOffset(Info->Class, Offset); // Traverse all non-virtual bases. const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); @@ -301,7 +297,8 @@ void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, if (Base->IsVirtual) continue; - uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); + CharUnits BaseOffset = + Offset + toCharUnits(Layout.getBaseClassOffset(Base->Class)); UpdateEmptyBaseSubobjects(Base, BaseOffset, PlacingEmptyBase); } @@ -321,17 +318,16 @@ void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, if (FD->isBitField()) continue; - CharUnits FieldOffset = - toCharUnits(Offset) + getFieldOffset(Layout, FieldNo); - UpdateEmptyFieldSubobjects(FD, toOffset(FieldOffset)); + CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); + UpdateEmptyFieldSubobjects(FD, FieldOffset); } } bool EmptySubobjectMap::CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, - uint64_t Offset) { + CharUnits Offset) { // If we know this class doesn't have any empty subobjects we don't need to // bother checking. - if (!SizeOfLargestEmptySubobject) + if (SizeOfLargestEmptySubobject.isZero()) return true; if (!CanPlaceBaseSubobjectAtOffset(Info, Offset)) @@ -346,13 +342,13 @@ bool EmptySubobjectMap::CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, bool EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, const CXXRecordDecl *Class, - uint64_t Offset) const { + CharUnits Offset) const { // We don't have to keep looking past the maximum offset that's known to // contain an empty class. - if (!AnyEmptySubobjectsBeyondOffset(toCharUnits(Offset))) + if (!AnyEmptySubobjectsBeyondOffset(Offset)) return true; - if (!CanPlaceSubobjectAtOffset(RD, toCharUnits(Offset))) + if (!CanPlaceSubobjectAtOffset(RD, Offset)) return false; const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); @@ -366,7 +362,8 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl = cast(I->getType()->getAs()->getDecl()); - uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); + CharUnits BaseOffset = + Offset + toCharUnits(Layout.getBaseClassOffset(BaseDecl)); if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset)) return false; } @@ -378,7 +375,8 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBaseDecl = cast(I->getType()->getAs()->getDecl()); - uint64_t VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); + CharUnits VBaseOffset = Offset + + toCharUnits(Layout.getVBaseClassOffset(VBaseDecl)); if (!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset)) return false; } @@ -392,8 +390,7 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, if (FD->isBitField()) continue; - CharUnits FieldOffset = - toCharUnits(Offset) + getFieldOffset(Layout, FieldNo); + CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset)) return false; @@ -413,7 +410,7 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, QualType T = FD->getType(); if (const RecordType *RT = T->getAs()) { const CXXRecordDecl *RD = cast(RT->getDecl()); - return CanPlaceFieldSubobjectAtOffset(RD, RD, toOffset(Offset)); + return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset); } // If we have an array type we need to look at every element. @@ -434,7 +431,7 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, if (!AnyEmptySubobjectsBeyondOffset(ElementOffset)) return true; - if (!CanPlaceFieldSubobjectAtOffset(RD, RD, toOffset(ElementOffset))) + if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset)) return false; ElementOffset += toCharUnits(Layout.getSize()); @@ -445,8 +442,9 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, } bool -EmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) { - if (!CanPlaceFieldSubobjectAtOffset(FD, toCharUnits(Offset))) +EmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, + CharUnits Offset) { + if (!CanPlaceFieldSubobjectAtOffset(FD, Offset)) return false; // We are able to place the member variable at this offset. @@ -457,7 +455,7 @@ EmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) { void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, const CXXRecordDecl *Class, - uint64_t Offset) { + CharUnits Offset) { // We know that the only empty subobjects that can conflict with empty // field subobjects are subobjects of empty bases that can be placed at offset // zero. Because of this, we only need to keep track of empty field @@ -466,7 +464,7 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, if (Offset >= SizeOfLargestEmptySubobject) return; - AddSubobjectAtOffset(RD, toCharUnits(Offset)); + AddSubobjectAtOffset(RD, Offset); const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); @@ -479,7 +477,8 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl = cast(I->getType()->getAs()->getDecl()); - uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); + CharUnits BaseOffset = + Offset + toCharUnits(Layout.getBaseClassOffset(BaseDecl)); UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset); } @@ -490,7 +489,8 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, const CXXRecordDecl *VBaseDecl = cast(I->getType()->getAs()->getDecl()); - uint64_t VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); + CharUnits VBaseOffset = + Offset + toCharUnits(Layout.getVBaseClassOffset(VBaseDecl)); UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset); } } @@ -501,15 +501,14 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, I != E; ++I, ++FieldNo) { const FieldDecl *FD = *I; - CharUnits FieldOffset = - toCharUnits(Offset) + getFieldOffset(Layout, FieldNo); + CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); - UpdateEmptyFieldSubobjects(FD, toOffset(FieldOffset)); + UpdateEmptyFieldSubobjects(FD, FieldOffset); } } void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD, - uint64_t Offset) { + CharUnits Offset) { QualType T = FD->getType(); if (const RecordType *RT = T->getAs()) { const CXXRecordDecl *RD = cast(RT->getDecl()); @@ -528,7 +527,7 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD, const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); uint64_t NumElements = Context.getConstantArrayElementCount(AT); - uint64_t ElementOffset = Offset; + CharUnits ElementOffset = Offset; for (uint64_t I = 0; I != NumElements; ++I) { // We know that the only empty subobjects that can conflict with empty @@ -540,7 +539,7 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD, return; UpdateEmptyFieldSubobjects(RD, RD, ElementOffset); - ElementOffset += Layout.getSize(); + ElementOffset += toCharUnits(Layout.getSize()); } } } @@ -1146,7 +1145,7 @@ uint64_t RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { // If we have an empty base class, try to place it at offset 0. if (Base->Class->isEmpty() && - EmptySubobjects->CanPlaceBaseAtOffset(Base, 0)) { + EmptySubobjects->CanPlaceBaseAtOffset(Base, CharUnits::Zero())) { Size = std::max(Size, Layout.getSize()); return 0; @@ -1158,7 +1157,7 @@ uint64_t RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign); // Try to place the base. - while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset)) + while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, toCharUnits(Offset))) Offset += BaseAlign; if (!Base->Class->isEmpty()) { @@ -1474,7 +1473,8 @@ void RecordLayoutBuilder::LayoutField(const FieldDecl *D) { if (!IsUnion && EmptySubobjects) { // Check if we can place the field at this offset. - while (!EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset)) { + while (!EmptySubobjects->CanPlaceFieldAtOffset(D, + toCharUnits(FieldOffset))) { // We couldn't place the field at the offset. Try again at a new offset. FieldOffset += FieldAlign; }