]> granicus.if.org Git - clang/commitdiff
Refine vcalls a little.
authorMike Stump <mrs@apple.com>
Wed, 19 Aug 2009 02:06:38 +0000 (02:06 +0000)
committerMike Stump <mrs@apple.com>
Wed, 19 Aug 2009 02:06:38 +0000 (02:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79400 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
test/CodeGenCXX/virt.cpp

index ecde2ad1928721da4b612b7906e1fc595861542d..f95aa289a35801ac107d6726158ebe947daaee99 100644 (file)
@@ -707,6 +707,7 @@ class ABIBuilder {
   std::vector<llvm::Constant *> &methods;
   llvm::Type *Ptr8Ty;
   const CXXRecordDecl *Class;
+  const ASTRecordLayout &BLayout;
   llvm::Constant *rtti;
   llvm::LLVMContext &VMContext;
   CodeGenModule &CGM;  // Per-module state.
@@ -716,21 +717,34 @@ public:
   ABIBuilder(std::vector<llvm::Constant *> &meth,
              const CXXRecordDecl *c,
              CodeGenModule &cgm)
-    : methods(meth), Class(c), rtti(cgm.GenerateRtti(c)),
-      VMContext(cgm.getModule().getContext()), CGM(cgm) {
+    : methods(meth), Class(c), BLayout(cgm.getContext().getASTRecordLayout(c)),
+      rtti(cgm.GenerateRtti(c)), VMContext(cgm.getModule().getContext()),
+      CGM(cgm) {
     Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
   }
 
-  void GenerateVcalls(const CXXRecordDecl *RD) {
+  llvm::Constant *GenerateVcall(const CXXMethodDecl *MD,
+                                const CXXRecordDecl *RD,
+                                bool VBoundary,
+                                bool SecondaryVirtual) {
+    llvm::Constant *m = 0;
+
+    // FIXME: vcall: offset for virtual base for this function
+    if (SecondaryVirtual || VBoundary)
+      m = llvm::Constant::getNullValue(Ptr8Ty);
+    return m;
+  }
+
+  void GenerateVcalls(const CXXRecordDecl *RD, bool VBoundary,
+                      bool SecondaryVirtual) {
     llvm::Constant *m;
 
-    // FIXME: audit order
     for (method_iter mi = RD->method_begin(),
            me = RD->method_end(); mi != me; ++mi) {
       if (mi->isVirtual()) {
-        // FIXME: vcall: offset for virtual base for this function
-        m = llvm::Constant::getNullValue(Ptr8Ty);
-        methods.push_back(m);
+        m = GenerateVcall(*mi, RD, VBoundary, SecondaryVirtual);
+        if (m)
+          methods.push_back(m);
       }
     }
   }
@@ -750,8 +764,8 @@ public:
 
   void GenerateVtableForBase(const CXXRecordDecl *RD,
                              bool forPrimary,
+                             bool VBoundary,
                              int64_t Offset,
-                             const CXXRecordDecl *Class,
                              bool ForVirtualBase,
                    llvm::SmallSet<const CXXRecordDecl *, 32> &IndirectPrimary) {
     llvm::Constant *m = llvm::Constant::getNullValue(Ptr8Ty);
@@ -763,6 +777,11 @@ public:
     const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 
     const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
 
+    if (VBoundary || forPrimary || ForVirtualBase) {
+      // then comes the the vcall offsets for all our functions...
+      GenerateVcalls(RD, VBoundary, !forPrimary && ForVirtualBase);
+    }
+
     // The virtual base offsets come first...
     // FIXME: Audit, is this right?
     if (forPrimary || !PrimaryBaseWasVirtual) {
@@ -774,11 +793,6 @@ public:
         methods.push_back(*i);
     }
 
-    if (forPrimary || ForVirtualBase) {
-      // then comes the the vcall offsets for all our functions...
-      GenerateVcalls(RD);
-    }
-
     bool Top = true;
 
     // vtables are composed from the chain of primaries.
@@ -786,15 +800,13 @@ public:
       if (PrimaryBaseWasVirtual)
         IndirectPrimary.insert(PrimaryBase);
       Top = false;
-      GenerateVtableForBase(PrimaryBase, true, Offset, Class,
-                            PrimaryBaseWasVirtual, IndirectPrimary);
+      GenerateVtableForBase(PrimaryBase, true, PrimaryBaseWasVirtual|VBoundary,
+                            Offset, PrimaryBaseWasVirtual, IndirectPrimary);
     }
 
     if (Top) {
       int64_t BaseOffset;
       if (ForVirtualBase) {
-        const ASTRecordLayout &BLayout = CGM.getContext()
-          .getASTRecordLayout(Class);
         BaseOffset = -(BLayout.getVBaseClassOffset(RD) / 8);
       } else
         BaseOffset = -Offset/8;
@@ -816,7 +828,7 @@ public:
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
       if (Base != PrimaryBase || PrimaryBaseWasVirtual) {
         uint64_t o = Offset + Layout.getBaseClassOffset(Base);
-        GenerateVtableForBase(Base, true, o, Class, false, IndirectPrimary);
+        GenerateVtableForBase(Base, true, false, o, false, IndirectPrimary);
       }
     }
   }
@@ -831,7 +843,7 @@ public:
       if (i->isVirtual() && !IndirectPrimary.count(Base)) {
         // Mark it so we don't output it twice.
         IndirectPrimary.insert(Base);
-        GenerateVtableForBase(Base, true, 0, Class, true, IndirectPrimary);
+        GenerateVtableForBase(Base, false, true, 0, true, IndirectPrimary);
       }
       if (Base->getNumVBases())
         GenerateVtableForVBases(Base, Class, IndirectPrimary);
@@ -880,7 +892,7 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) {
   ABIBuilder b(methods, RD, CGM);
 
   // First comes the vtables for all the non-virtual bases...
-  b.GenerateVtableForBase(RD, true, 0, RD, false, IndirectPrimary);
+  b.GenerateVtableForBase(RD, true, false, 0, false, IndirectPrimary);
 
   // then the vtables for all the virtual bases.
   b.GenerateVtableForVBases(RD, RD, IndirectPrimary);
index 25d47ccf8e70f6127024086fe17beb147e8283d9..95e98ac2fb35f6eee01b987a46043723d7d29f91 100644 (file)
@@ -228,16 +228,16 @@ struct test5_D  : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
 // CHECK-LP32-NEXT: .space 4
 // CHECK-LP32-NEXT: .space 4
 // CHECK-LP32-NEXT: .space 4
-// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT .space 4                                    FIXME
 // CHECK-LP32: .long 4294967292
 // CHECK-LP32-NEXT: .long __ZTI7test5_D
 // CHECK-LP32-NEXT: .long __ZN9test5_B237funcB23Ev
 // CHECK-LP32-NEXT: .long __ZN9test5_B227funcB22Ev
 // CHECK-LP32-NEXT: .long __ZN9test5_B217funcB21Ev
 // CHECK-LP32 .space 4
-// CHECK-LP32: .long 8
+// CHECK-LP32 .long 8                                          FIXME
 // CHECK-LP32: .space 4
-// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT .space 4                                    FIXME
 // CHECK-LP32: .long 4
 // CHECK-LP32-NEXT: .space 4
 // CHECK-LP32-NEXT: .space 4
@@ -280,16 +280,16 @@ struct test5_D  : virtual test5_B1, virtual test5_B21, virtual test5_B31 {
 // CHECK-LP64-NEXT: .space 8
 // CHECK-LP64-NEXT: .space 8
 // CHECK-LP64-NEXT: .space 8
-// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT .space 8                                    FIXME
 // CHECK-LP64: .quad 18446744073709551608
 // CHECK-LP64-NEXT: .quad __ZTI7test5_D
 // CHECK-LP64-NEXT: .quad __ZN9test5_B237funcB23Ev
 // CHECK-LP64-NEXT: .quad __ZN9test5_B227funcB22Ev
 // CHECK-LP64-NEXT: .quad __ZN9test5_B217funcB21Ev
 // CHECK-LP64 .space 8
-// CHECK-LP64: .quad 16
+// CHECK-LP64 .quad 16                                         FIXME
 // CHECK-LP64: .space 8
-// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT .space 8                                    FIXME
 // CHECK-LP64: .quad 8
 // CHECK-LP64-NEXT: .space 8
 // CHECK-LP64-NEXT: .space 8
@@ -337,7 +337,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
 // CHECK-LP32-NEXT: .long 24
 // CHECK-LP32-NEXT: .long 16
 // CHECK-LP32-NEXT: .space 4
-// CHECK-LP32: .long __ZTI7test8_D
+// CHECK-LP32-NEXT: .long __ZTI7test8_D
 // CHECK-LP32-NEXT: .long __ZN8test8_B19ftest8_B1Ev
 // CHECK-LP32-NEXT: .long 20
 // CHECK-LP32-NEXT: .long 12
@@ -345,10 +345,10 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
 // CHECK-LP32-NEXT: .long __ZTI7test8_D
 // CHECK-LP32-NEXT: .long __ZN9test8_B2a10ftest8_B2aEv
 // CHECK-LP32-NEXT: .long __ZN8test8_B29ftest8_B2Ev
-// CHECK-LP32: .long 4294967288
+// CHECK-LP32-NEXT: .long 4294967288
 // CHECK-LP32-NEXT: .long __ZTI7test8_D
 // CHECK-LP32-NEXT: .long __ZN9test8_B2b10ftest8_B2bEv
-// CHECK-LP32: .long 4294967284
+// CHECK-LP32-NEXT: .long 4294967284
 // CHECK-LP32-NEXT: .long __ZTI7test8_D
 // CHECK-LP32-NEXT: .long __ZN8test8_B39ftest8_B3Ev
 // CHECK-LP32-NEXT: .space 4
@@ -364,7 +364,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
 // CHECK-LP64-NEXT: .quad 48
 // CHECK-LP64-NEXT: .quad 32
 // CHECK-LP64-NEXT: .space 8
-// CHECK-LP64: .quad __ZTI7test8_D
+// CHECK-LP64-NEXT: .quad __ZTI7test8_D
 // CHECK-LP64-NEXT: .quad __ZN8test8_B19ftest8_B1Ev
 // CHECK-LP64-NEXT: .quad 40
 // CHECK-LP64-NEXT: .quad 24
@@ -372,10 +372,10 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
 // CHECK-LP64-NEXT: .quad __ZTI7test8_D
 // CHECK-LP64-NEXT: .quad __ZN9test8_B2a10ftest8_B2aEv
 // CHECK-LP64-NEXT: .quad __ZN8test8_B29ftest8_B2Ev
-// CHECK-LP64: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad 18446744073709551600
 // CHECK-LP64-NEXT: .quad __ZTI7test8_D
 // CHECK-LP64-NEXT: .quad __ZN9test8_B2b10ftest8_B2bEv
-// CHECK-LP64: .quad 18446744073709551592
+// CHECK-LP64-NEXT: .quad 18446744073709551592
 // CHECK-LP64-NEXT: .quad __ZTI7test8_D
 // CHECK-LP64-NEXT: .quad __ZN8test8_B39ftest8_B3Ev
 // CHECK-LP64-NEXT: .space 8
@@ -390,37 +390,37 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
 
 
 // CHECK-LP64: __ZTV1B:
-// CHECK-LP64: .space 8
-// CHECK-LP64: .quad __ZTI1B
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI1B
 // CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
 // CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
 
 // CHECK-LP32: __ZTV1B:
-// CHECK-LP32: .space 4
-// CHECK-LP32: .long __ZTI1B
+// CHECK-LP32-NEXT: .space 4
+// CHECK-LP32-NEXT: .long __ZTI1B
 // CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
 // CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
 
 // CHECK-LP64: __ZTV1A:
 // CHECK-LP64-NEXT: .space 8
-// CHECK-LP64: .quad __ZTI1A
+// CHECK-LP64-NEXT: .quad __ZTI1A
 // CHECK-LP64-NEXT: .quad __ZN1B4bar1Ev
 // CHECK-LP64-NEXT: .quad __ZN1B4bar2Ev
 // CHECK-LP64-NEXT: .quad __ZN1A4foo1Ev
 // CHECK-LP64-NEXT: .quad __ZN1A4foo2Ev
-// CHECK-LP64: .quad 18446744073709551600
+// CHECK-LP64-NEXT: .quad 18446744073709551600
 // CHECK-LP64-NEXT: .quad __ZTI1A
 // CHECK-LP64-NEXT: .quad __ZN1C4bee1Ev
 // CHECK-LP64-NEXT: .quad __ZN1C4bee2Ev
 
 // CHECK-LP32: __ZTV1A:
 // CHECK-LP32-NEXT: .space 4
-// CHECK-LP32: .long __ZTI1A
+// CHECK-LP32-NEXT: .long __ZTI1A
 // CHECK-LP32-NEXT: .long __ZN1B4bar1Ev
 // CHECK-LP32-NEXT: .long __ZN1B4bar2Ev
 // CHECK-LP32-NEXT: .long __ZN1A4foo1Ev
 // CHECK-LP32-NEXT: .long __ZN1A4foo2Ev
-// CHECK-LP32: .long 4294967284
+// CHECK-LP32-NEXT: .long 4294967284
 // CHECK-LP32-NEXT: .long __ZTI1A
 // CHECK-LP32-NEXT: .long __ZN1C4bee1Ev
 // CHECK-LP32-NEXT: .long __ZN1C4bee2Ev
@@ -430,7 +430,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
 // CHECK-LP32-NEXT: .long 8
 // CHECK-LP32-NEXT: .space 4
 // CHECK-LP32-NEXT: .space 4
-// CHECK-LP32: .long __ZTI1F
+// CHECK-LP32-NEXT: .long __ZTI1F
 // CHECK-LP32-NEXT: .long __ZN1D3booEv
 // CHECK-LP32-NEXT: .long __ZN1F3fooEv
 // CHECK-LP32-NEXT: .space 4
@@ -451,7 +451,7 @@ class test8_D : test8_B1, test8_B2, test8_B3 {
 // CHECK-LP64-NEXT: .quad 16
 // CHECK-LP64-NEXT: .space 8
 // CHECK-LP64-NEXT: .space 8
-// CHECK-LP64: .quad __ZTI1F
+// CHECK-LP64-NEXT: .quad __ZTI1F
 // CHECK-LP64-NEXT: .quad __ZN1D3booEv
 // CHECK-LP64-NEXT: .quad __ZN1F3fooEv
 // CHECK-LP64-NEXT: .space 8