[cfe-commits] r117877 - in /cfe/trunk: include/clang/AST/RecordLayout.h lib/AST/RecordLayout.cpp lib/AST/RecordLayoutBuilder.cpp

Anders Carlsson andersca at mac.com
Sun Oct 31 15:13:23 PDT 2010


Author: andersca
Date: Sun Oct 31 17:13:23 2010
New Revision: 117877

URL: http://llvm.org/viewvc/llvm-project?rev=117877&view=rev
Log:
EmptyObjectMap now uses CharUnits wherever possible.

Modified:
    cfe/trunk/include/clang/AST/RecordLayout.h
    cfe/trunk/lib/AST/RecordLayout.cpp
    cfe/trunk/lib/AST/RecordLayoutBuilder.cpp

Modified: cfe/trunk/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecordLayout.h?rev=117877&r1=117876&r2=117877&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Sun Oct 31 17:13:23 2010
@@ -113,7 +113,7 @@
     /// 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 @@
                   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 @@
       VBase->getASTContext().getCharWidth();
   }
 
-  uint64_t getSizeOfLargestEmptySubobject() const {
+  CharUnits getSizeOfLargestEmptySubobject() const {
     assert(CXXInfo && "Record layout does not have C++ specific info!");
     return CXXInfo->SizeOfLargestEmptySubobject;
   }

Modified: cfe/trunk/lib/AST/RecordLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayout.cpp?rev=117877&r1=117876&r2=117877&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayout.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayout.cpp Sun Oct 31 17:13:23 2010
@@ -46,7 +46,7 @@
                                  unsigned fieldcount,
                                  uint64_t nonvirtualsize,
                                  unsigned nonvirtualalign,
-                                 uint64_t SizeOfLargestEmptySubobject,
+                                 CharUnits SizeOfLargestEmptySubobject,
                                  const CXXRecordDecl *PrimaryBase,
                                  bool PrimaryBaseIsVirtual,
                                  const BaseOffsetsMapTy& BaseOffsets,

Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=117877&r1=117876&r2=117877&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Sun Oct 31 17:13:23 2010
@@ -78,12 +78,12 @@
   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 @@
     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 @@
   /// 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 @@
   /// 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 @@
     const CXXRecordDecl *BaseDecl =
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->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 @@
     if (!RT)
       continue;
 
-    uint64_t EmptySize = 0;
+    CharUnits EmptySize;
     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();
+      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 @@
 }
 
 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 @@
     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 @@
     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 @@
 }
 
 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 @@
     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 @@
     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 @@
     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::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 @@
     const CXXRecordDecl *BaseDecl =
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->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 @@
       const CXXRecordDecl *VBaseDecl =
         cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->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 @@
     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 @@
   QualType T = FD->getType();
   if (const RecordType *RT = T->getAs<RecordType>()) {
     const CXXRecordDecl *RD = cast<CXXRecordDecl>(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 @@
       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 @@
 }
 
 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 @@
 
 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 @@
   if (Offset >= SizeOfLargestEmptySubobject)
     return;
 
-  AddSubobjectAtOffset(RD, toCharUnits(Offset));
+  AddSubobjectAtOffset(RD, Offset);
 
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
@@ -479,7 +477,8 @@
     const CXXRecordDecl *BaseDecl =
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
 
-    uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl);
+    CharUnits BaseOffset = 
+      Offset + toCharUnits(Layout.getBaseClassOffset(BaseDecl));
     UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset);
   }
 
@@ -490,7 +489,8 @@
       const CXXRecordDecl *VBaseDecl =
       cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
       
-      uint64_t VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl);
+      CharUnits VBaseOffset = 
+        Offset + toCharUnits(Layout.getVBaseClassOffset(VBaseDecl));
       UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset);
     }
   }
@@ -501,15 +501,14 @@
        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<RecordType>()) {
     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
@@ -528,7 +527,7 @@
     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 @@
         return;
 
       UpdateEmptyFieldSubobjects(RD, RD, ElementOffset);
-      ElementOffset += Layout.getSize();
+      ElementOffset += toCharUnits(Layout.getSize());
     }
   }
 }
@@ -1146,7 +1145,7 @@
 
   // 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 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 @@
 
   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;
     }





More information about the cfe-commits mailing list