From 9beac787c17a51a3b1a9b75dcce45f85f057d67c Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Tue, 4 Aug 2009 21:58:42 +0000 Subject: [PATCH] vtable building for simple inheritance. Still in progress. llvm-svn: 78110 --- clang/lib/CodeGen/CGCXX.cpp | 19 ++++++++++++++++++- clang/test/CodeGenCXX/virt.cpp | 15 ++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 21fba1457155..97937ea89a13 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -169,7 +169,7 @@ GetNestedPaths(llvm::SmallVectorImpl &NestedBasePaths, if (i->isVirtual()) continue; const CXXRecordDecl *Base = - cast(i->getType()->getAs()->getDecl()); + cast(i->getType()->getAs()->getDecl()); if (Base == BaseClassDecl) { NestedBasePaths.push_back(BaseClassDecl); return true; @@ -543,6 +543,23 @@ llvm::Value *CodeGenFunction::GenerateVtable(const CXXRecordDecl *RD) { int64_t offset = 0; methods.push_back(m); offset += LLVMPointerWidth; methods.push_back(GenerateRtti(RD)); offset += LLVMPointerWidth; + + for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), + e = RD->bases_end(); i != e; ++i) { + if (i->isVirtual()) + continue; + const CXXRecordDecl *Base = + cast(i->getType()->getAs()->getDecl()); + for (meth_iter mi = Base->method_begin(), me = Base->method_end(); mi != me; + ++mi) { + if (mi->isVirtual()) { + m = CGM.GetAddrOfFunction(GlobalDecl(*mi)); + m = llvm::ConstantExpr::getBitCast(m, Ptr8Ty); + methods.push_back(m); + } + } + } + for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; ++mi) { if (mi->isVirtual()) { diff --git a/clang/test/CodeGenCXX/virt.cpp b/clang/test/CodeGenCXX/virt.cpp index fdca3f4a15b1..e77abaa6f565 100644 --- a/clang/test/CodeGenCXX/virt.cpp +++ b/clang/test/CodeGenCXX/virt.cpp @@ -4,15 +4,20 @@ // RUN: FileCheck -check-prefix LP32 -input-file=%t-32.s %s && // RUN: true -class A { +struct B { + virtual void bar1(); + virtual void bar2(); +}; + +static_assert (sizeof (B) == (sizeof(void *)), "vtable pointer layout"); + +class A : public B { public: virtual void foo1(); virtual void foo2(); A() { } } *a; -static_assert (sizeof (A) == (sizeof(void *)), "vtable pointer layout"); - int main() { A a; } @@ -20,11 +25,15 @@ int main() { // CHECK-LP64: __ZTV1A: // CHECK-LP64: .space 8 // CHECK-LP64: .space 8 +// CHECK-LP64: .quad __ZN1B4bar1Ev +// CHECK-LP64: .quad __ZN1B4bar2Ev // CHECK-LP64: .quad __ZN1A4foo1Ev // CHECK-LP64: .quad __ZN1A4foo2Ev // CHECK-LP32: __ZTV1A: // CHECK-LP32: .space 4 // CHECK-LP32: .space 4 +// CHECK-LP32: .long __ZN1B4bar1Ev +// CHECK-LP32: .long __ZN1B4bar2Ev // CHECK-LP32: .long __ZN1A4foo1Ev // CHECK-LP32: .long __ZN1A4foo2Ev