]> granicus.if.org Git - clang/commitdiff
Refine primary vbase selection ordering. WIP.
authorMike Stump <mrs@apple.com>
Wed, 12 Aug 2009 21:50:08 +0000 (21:50 +0000)
committerMike Stump <mrs@apple.com>
Wed, 12 Aug 2009 21:50:08 +0000 (21:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78844 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/RecordLayoutBuilder.cpp
lib/AST/RecordLayoutBuilder.h
test/CodeGenCXX/virt.cpp

index 8e09e9e65bbb8f3392af5ba7a7230dfafe639e12..2a7477c4493d9b1b5e7050ef26ffa809a3e46432 100644 (file)
@@ -93,6 +93,30 @@ void ASTRecordLayoutBuilder::SelectPrimaryForBase(const CXXRecordDecl *RD,
   }
 }
 
+void ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
+                                             const CXXRecordDecl *&FirstPrimary,
+                    llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) {
+  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
+         e = RD->bases_end(); i != e; ++i) {
+    const CXXRecordDecl *Base = 
+      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+    if (!i->isVirtual()) {
+      SelectPrimaryVBase(Base, FirstPrimary, IndirectPrimary);
+      if (PrimaryBase)
+        return;
+      continue;
+    }
+    if (IsNearlyEmpty(Base)) {
+      if (FirstPrimary==0)
+        FirstPrimary = Base;
+      if (!IndirectPrimary.count(Base)) {
+        setPrimaryBase(Base, true);
+        return;
+      }
+    }
+  }
+}
+
 /// SelectPrimaryBase - Selects the primary base for the given class and
 /// record that with setPrimaryBase.
 void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
@@ -110,6 +134,8 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
     }
   }
 
+  setPrimaryBase(0, false);
+
   // Otherwise, it is the first nearly empty virtual base that is not an
   // indirect primary virtual base class, if one exists.
 
@@ -117,7 +143,6 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
   // is expensive.
   // FIXME: audit indirect virtual bases
   if (RD->getNumVBases() == 0) {
-    setPrimaryBase(0, false);
     return;
   }
 
@@ -133,20 +158,7 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
   }
 
   // Then we can search for the first nearly empty virtual base itself.
-  // FIXME: audit indirect virtual bases and order (backwards?)
-  for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
-       e = RD->vbases_end(); i != e; ++i) {
-    const CXXRecordDecl *Base = 
-      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-    if (IsNearlyEmpty(Base)) {
-      if (FirstPrimary==0)
-        FirstPrimary = Base;
-      if (!IndirectPrimary.count(Base)) {
-        setPrimaryBase(Base, true);
-        return;
-      }
-    }
-  }
+  SelectPrimaryVBase(RD, FirstPrimary, IndirectPrimary);
 
   // Otherwise if is the first nearly empty virtual base, if one exists,
   // otherwise there is no primary base class.
index 488f6662c00f50f40acc1a8aeba037390d42a09a..31bbdd7530302fb01dec96ca61193be4b97d6396 100644 (file)
@@ -54,6 +54,9 @@ class ASTRecordLayoutBuilder {
   void LayoutField(const FieldDecl *D);
 
   void SelectPrimaryBase(const CXXRecordDecl *RD);
+  void SelectPrimaryVBase(const CXXRecordDecl *RD,
+                          const CXXRecordDecl *&FirstPrimary,
+                     llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
   void SelectPrimaryForBase(const CXXRecordDecl *RD,
                      llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
   void setPrimaryBase(const CXXRecordDecl *PB, bool Virtual) {
index d9e8664460cc0a79d7628213a8b6c2d4c9bb252b..7a1e2c31edf21e3039c5c2247793cb308943d306 100644 (file)
@@ -164,6 +164,131 @@ struct test4_D : virtual B, virtual C {
 // CHECK-LP64: .quad __ZN1B4bar2Ev
 
 
+struct test5_B3 { virtual void funcB3(); };
+struct test5_B2 : virtual test5_B3 { virtual void funcB2(); };
+struct test5_B1 : virtual test5_B2 { virtual void funcB1(); };
+
+struct test5_B23 { virtual void funcB23(); };
+struct test5_B22 : virtual test5_B23 { virtual void funcB22(); };
+struct test5_B21 : virtual test5_B22 { virtual void funcB21(); };
+
+
+struct B232 { virtual void funcB232(); };
+struct B231 { virtual void funcB231(); };
+
+struct test5_B33 { virtual void funcB33(); };
+struct test5_B32 : virtual test5_B33, virtual B232 { virtual void funcB32(); };
+struct test5_B31 : virtual test5_B32, virtual B231 { virtual void funcB31(); };
+
+struct test5_D  : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
+  virtual void funcD() { }
+};
+
+// CHECK-LP32:__ZTV7test5_D:
+// CHECK-LP32 .long 16
+// CHECK-LP32 .long 12
+// CHECK-LP32 .long 8
+// CHECK-LP32 .long 8
+// CHECK-LP32 .long 8
+// CHECK-LP32 .long 4
+// CHECK-LP32 .long 4
+// CHECK-LP32 .long 4
+// CHECK-LP32: .space 4
+// CHECK-LP32: .space 4
+// CHECK-LP32: .space 4
+// CHECK-LP32: .space 4
+// CHECK-LP32: .space 4
+// CHECK-LP32: .space 4
+// CHECK-LP32: .space 4
+// CHECK-LP32: .long __ZTI7test5_D
+// CHECK-LP32: .long __ZN8test5_B36funcB3Ev
+// CHECK-LP32: .long __ZN8test5_B26funcB2Ev
+// CHECK-LP32: .long __ZN8test5_B16funcB1Ev
+// CHECK-LP32: .long __ZN7test5_D5funcDEv
+// CHECK-LP32 .space 4
+// CHECK-LP32 .space 4
+// CHECK-LP32 .space 4
+// CHECK-LP32 .space 4
+// CHECK-LP32: .space 4
+// CHECK-LP32 .long -4
+// CHECK-LP32: .long __ZTI7test5_D
+// CHECK-LP32: .long __ZN9test5_B237funcB23Ev
+// CHECK-LP32: .long __ZN9test5_B227funcB22Ev
+// CHECK-LP32 .long __ZN9test5_B217funcB21Ev
+// CHECK-LP32 .space 4
+// CHECK-LP32 .long 8
+// CHECK-LP32 .space 4
+// CHECK-LP32 .space 4
+// CHECK-LP32 .long 4
+// CHECK-LP32 .space 4
+// CHECK-LP32: .space 4
+// CHECK-LP32 .long -8
+// CHECK-LP32 .long __ZTI7test5_D
+// CHECK-LP32 .long __ZN9test5_B337funcB33Ev
+// CHECK-LP32 .long __ZN9test5_B327funcB32Ev
+// CHECK-LP32 .long __ZN9test5_B317funcB31Ev
+// CHECK-LP32: .space 4
+// CHECK-LP32 .long -12
+// CHECK-LP32: .long __ZTI7test5_D
+// CHECK-LP32: .long __ZN4B2328funcB232Ev
+// CHECK-LP32: .space 4
+// CHECK-LP32 .long -16
+// CHECK-LP32: .long __ZTI7test5_D
+// CHECK-LP32: .long __ZN4B2318funcB231Ev
+
+// CHECK-LP64:__ZTV7test5_D:
+// CHECK-LP64 .quad 32
+// CHECK-LP64 .quad 24
+// CHECK-LP64 .quad 16
+// CHECK-LP64 .quad 16
+// CHECK-LP64 .quad 16
+// CHECK-LP64 .quad 8
+// CHECK-LP64 .quad 8
+// CHECK-LP64 .quad 8
+// CHECK-LP64: .space 8
+// CHECK-LP64: .space 8
+// CHECK-LP64: .space 8
+// CHECK-LP64: .space 8
+// CHECK-LP64: .space 8
+// CHECK-LP64: .space 8
+// CHECK-LP64: .space 8
+// CHECK-LP64: .quad __ZTI7test5_D
+// CHECK-LP64: .quad __ZN8test5_B36funcB3Ev
+// CHECK-LP64: .quad __ZN8test5_B26funcB2Ev
+// CHECK-LP64: .quad __ZN8test5_B16funcB1Ev
+// CHECK-LP64: .quad __ZN7test5_D5funcDEv
+// CHECK-LP64 .space 8
+// CHECK-LP64 .space 8
+// CHECK-LP64 .space 8
+// CHECK-LP64 .space 8
+// CHECK-LP64: .space 8
+// CHECK-LP64 .quad 18446744073709551608
+// CHECK-LP64: .quad __ZTI7test5_D
+// CHECK-LP64: .quad __ZN9test5_B237funcB23Ev
+// CHECK-LP64: .quad __ZN9test5_B227funcB22Ev
+// CHECK-LP64 .quad __ZN9test5_B217funcB21Ev
+// CHECK-LP64 .space 8
+// CHECK-LP64 .quad 16
+// CHECK-LP64 .space 8
+// CHECK-LP64 .space 8
+// CHECK-LP64 .quad 8
+// CHECK-LP64 .space 8
+// CHECK-LP64: .space 8
+// CHECK-LP64 .quad 18446744073709551600
+// CHECK-LP64 .quad __ZTI7test5_D
+// CHECK-LP64 .quad __ZN9test5_B337funcB33Ev
+// CHECK-LP64 .quad __ZN9test5_B327funcB32Ev
+// CHECK-LP64 .quad __ZN9test5_B317funcB31Ev
+// CHECK-LP64: .space 8
+// CHECK-LP64 .quad 18446744073709551592
+// CHECK-LP64: .quad __ZTI7test5_D
+// CHECK-LP64: .quad __ZN4B2328funcB232Ev
+// CHECK-LP64: .space 8
+// CHECK-LP64 .quad 18446744073709551584
+// CHECK-LP64: .quad __ZTI7test5_D
+// CHECK-LP64: .quad __ZN4B2318funcB231Ev
+
+
 
 
 // CHECK-LP64: __ZTV1B:
@@ -245,5 +370,6 @@ struct test4_D : virtual B, virtual C {
 // CHECK-LP64: .quad __ZN2D14bar5Ev
 
 
+test5_D d5;
 test4_D d4;
 test3_D d3;