diff options
| author | Mike Stump <mrs@apple.com> | 2009-10-28 00:35:46 +0000 |
|---|---|---|
| committer | Mike Stump <mrs@apple.com> | 2009-10-28 00:35:46 +0000 |
| commit | 375faa8dd7c45df30c66246405de1406afc62df2 (patch) | |
| tree | 6f734671e9e8fd62d7271c4b5b8242d1d0886bb3 | |
| parent | 3da3c0657830f9fd44cc1225d3e5c6bd3ff5fec7 (diff) | |
| download | bcm5719-llvm-375faa8dd7c45df30c66246405de1406afc62df2.tar.gz bcm5719-llvm-375faa8dd7c45df30c66246405de1406afc62df2.zip | |
Finish off pure virtual function handling.
llvm-svn: 85354
| -rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 23 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/virt.cpp | 35 |
2 files changed, 53 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 0b81c2165ee..66f48c0e3d9 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/lib/CodeGen/CGVtable.cpp @@ -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]; diff --git a/clang/test/CodeGenCXX/virt.cpp b/clang/test/CodeGenCXX/virt.cpp index 21fecac11e7..ffd87bd967b 100644 --- a/clang/test/CodeGenCXX/virt.cpp +++ b/clang/test/CodeGenCXX/virt.cpp @@ -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 |

