]> granicus.if.org Git - clang/commitdiff
More work on handling empty classes.
authorAnders Carlsson <andersca@mac.com>
Mon, 10 May 2010 15:26:14 +0000 (15:26 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 10 May 2010 15:26:14 +0000 (15:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103402 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/RecordLayoutBuilder.cpp
lib/AST/RecordLayoutBuilder.h

index 444c52b9426e9d5bff09f07b0fbefd392e302675..e444cf09b02e7498ff678a34f913e12947640c06 100644 (file)
@@ -375,7 +375,7 @@ uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
   // If we have an empty base class, try to place it at offset 0.
-  if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0)) {
+  if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0, /*CheckVBases=*/false)) {
     // We were able to place the class at offset 0.
     UpdateEmptyClassOffsets(RD, 0);
 
@@ -391,7 +391,7 @@ uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
 
   // Try to place the base.
   while (true) {
-    if (canPlaceRecordAtOffset(RD, Offset))
+    if (canPlaceRecordAtOffset(RD, Offset, /*CheckVBases=*/false))
       break;
 
     Offset += BaseAlign;
@@ -412,8 +412,10 @@ uint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
   return Offset;
 }
 
-bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
-                                                    uint64_t Offset) const {
+bool 
+ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
+                                               uint64_t Offset, 
+                                               bool CheckVBases) const {
   // Look for an empty class with the same type at the same offset.
   for (EmptyClassOffsetsTy::const_iterator I =
          EmptyClassOffsets.lower_bound(Offset),
@@ -438,7 +440,8 @@ bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
 
     uint64_t BaseOffset = Layout.getBaseClassOffset(BaseDecl);
 
-    if (!canPlaceRecordAtOffset(BaseDecl, Offset + BaseOffset))
+    if (!canPlaceRecordAtOffset(BaseDecl, Offset + BaseOffset,
+                                /*CheckVBases=*/false))
       return false;
   }
 
@@ -454,7 +457,10 @@ bool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
       return false;
   }
 
-  // FIXME: virtual bases.
+  if (CheckVBases) {
+    // FIXME: virtual bases.
+  }
+
   return true;
 }
 
@@ -463,7 +469,7 @@ bool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD,
   QualType T = FD->getType();
   if (const RecordType *RT = T->getAs<RecordType>()) {
     if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
-      return canPlaceRecordAtOffset(RD, Offset);
+      return canPlaceRecordAtOffset(RD, Offset, /*CheckVBases=*/true);
   }
 
   if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) {
@@ -480,7 +486,7 @@ bool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD,
     uint64_t NumElements = Context.getConstantArrayElementCount(AT);
     uint64_t ElementOffset = Offset;
     for (uint64_t I = 0; I != NumElements; ++I) {
-      if (!canPlaceRecordAtOffset(RD, ElementOffset))
+      if (!canPlaceRecordAtOffset(RD, ElementOffset, /*CheckVBases=*/true))
         return false;
 
       ElementOffset += Layout.getSize();
index f3da315ead886fd78d8d2cad5a62aa2cf148f3ca..f2e3506480c68988595afed58ff7ff76d5df24e4 100644 (file)
@@ -140,7 +140,8 @@ class ASTRecordLayoutBuilder {
   /// or a field) can be placed at the given offset. 
   /// Returns false if placing the record will result in two components 
   /// (direct or indirect) of the same type having the same offset.
-  bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset) const;
+  bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset,
+                              bool CheckVBases) const;
 
   /// canPlaceFieldAtOffset - Return whether a field can be placed at the given
   /// offset.