]> granicus.if.org Git - clang/commitdiff
Finish off pure virtual function handling.
authorMike Stump <mrs@apple.com>
Wed, 28 Oct 2009 00:35:46 +0000 (00:35 +0000)
committerMike Stump <mrs@apple.com>
Wed, 28 Oct 2009 00:35:46 +0000 (00:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85354 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 0b81c2165ee7976ff079e25acb12c46d32c666d8..66f48c0e3d9c195f113c75bb6f2916647c8df3c0 100644 (file)
@@ -72,8 +72,13 @@ public:
       LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)),
       CurrentVBaseOffset(0) {
     Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
-    // FIXME: ___cxa_pure_virtual
-    cxa_pure = wrap((Index_t)0);
+
+    // Calculate pointer for ___cxa_pure_virtual.
+    const llvm::FunctionType *FTy;
+    std::vector<const llvm::Type*> ArgTys;
+    const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext);
+    FTy = llvm::FunctionType::get(ResultType, ArgTys, false);
+    cxa_pure = wrap(CGM.CreateRuntimeFunction(FTy, "__cxa_pure_virtual"));
   }
 
   llvm::DenseMap<const CXXMethodDecl *, Index_t> &getIndex() { return Index; }
@@ -183,6 +188,7 @@ public:
   bool OverrideMethod(const CXXMethodDecl *MD, llvm::Constant *m,
                       bool MorallyVirtual, Index_t OverrideOffset,
                       Index_t Offset) {
+    const bool isPure = MD->isPure();
     typedef CXXMethodDecl::method_iterator meth_iter;
     // FIXME: Should OverrideOffset's be Offset?
 
@@ -221,7 +227,9 @@ public:
         }
         Index[MD] = i;
         submethods[i] = m;
-
+        if (isPure)
+          Pures[MD] = 1;
+        Pures.erase(OMD);
         Thunks.erase(OMD);
         if (MorallyVirtual) {
           Index_t &idx = VCall[OMD];
@@ -243,7 +251,7 @@ public:
             CovariantThunks[MD] = std::make_pair(std::make_pair(ThisOffset,
                                                                 ReturnOffset),
                                                  oret);
-          else
+          else if (!isPure)
             Thunks[MD] = ThisOffset;
           return true;
         }
@@ -258,7 +266,7 @@ public:
             CovariantThunks[MD] = std::make_pair(std::make_pair(ThisOffset,
                                                                 ReturnOffset),
                                                  oret);
-          else
+          else if (!isPure)
             Thunks[MD] = ThisOffset;
         }
         return true;
@@ -272,6 +280,7 @@ public:
     for (Thunks_t::iterator i = Thunks.begin(), e = Thunks.end();
          i != e; ++i) {
       const CXXMethodDecl *MD = i->first;
+      assert(!MD->isPure() && "Trying to thunk a pure");
       Index_t idx = Index[MD];
       Index_t nv_O = i->second.first;
       Index_t v_O = i->second.second;
@@ -282,6 +291,8 @@ public:
            e = CovariantThunks.end();
          i != e; ++i) {
       const CXXMethodDecl *MD = i->first;
+      if (MD->isPure())
+        continue;
       Index_t idx = Index[MD];
       Index_t nv_t = i->second.first.first.first;
       Index_t v_t = i->second.first.first.second;
@@ -339,6 +350,8 @@ public:
     // else allocate a new slot.
     Index[MD] = submethods.size();
     submethods.push_back(m);
+    if (MD->isPure())
+      Pures[MD] = 1;
     if (MorallyVirtual) {
       VCallOffset[MD] = Offset/8;
       Index_t &idx = VCall[MD];
index 21fecac11e7b5c9657bacd7bca8c00d0dcef47ca..ffd87bd967ba8316356bc4ed0ba348e380aede6f 100644 (file)
@@ -1049,6 +1049,41 @@ struct test16_D : test16_NV1, virtual test16_B2 {
 // CHECK-LP32-NEXT: .long __ZN10test16_NV28foo_NV2bEv
 
 
+class test17_B1 {
+  virtual void foo() = 0;
+  virtual void bar() { }
+};
+
+class test17_B2 : public test17_B1 {
+  void foo() { }
+  virtual void bar() = 0;
+};
+
+class test17_D : public test17_B2 {
+  void bar() { }
+} test17_d;
+
+
+// CHECK-LP64:__ZTV8test17_D:
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI8test17_D
+// CHECK-LP64-NEXT: .quad __ZN9test17_B23fooEv
+// CHECK-LP64-NEXT: .quad __ZN8test17_D3barEv
+
+// CHECK-LP64:__ZTV9test17_B2:
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI9test17_B2
+// CHECK-LP64-NEXT: .quad __ZN9test17_B23fooEv
+// CHECK-LP64-NEXT: .quad ___cxa_pure_virtual
+
+// CHECK-LP64:__ZTV9test17_B1:
+// CHECK-LP64-NEXT: .space 8
+// CHECK-LP64-NEXT: .quad __ZTI9test17_B1
+// CHECK-LP64-NEXT: .quad ___cxa_pure_virtual
+// CHECK-LP64-NEXT: .quad __ZN9test17_B13barEv
+
+
+
 // CHECK-LP64: __ZTV1B:
 // CHECK-LP64-NEXT: .space 8
 // CHECK-LP64-NEXT: .quad __ZTI1B