aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2011-05-08 17:25:05 +0000
committerAnders Carlsson <andersca@mac.com>2011-05-08 17:25:05 +0000
commit8e0397a39eaf9db83cbd9a3a459893fd12a3a05e (patch)
tree01384c6163ecaaa91d7354c7dcde4638e7f43f41
parent8db75a2b9c963a3bc0bf928e711353552f4fef79 (diff)
Don't emit complete constructors for abstract classes. Also, don't emit
complete destructors for abstract classes unless the destructor is virtual and thus needs to be in the vtable. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131068 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGCXX.cpp11
-rw-r--r--test/CodeGenCXX/abstract-class-ctors-dtors.cpp16
2 files changed, 25 insertions, 2 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 184147cb72..4390f3a3e3 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -187,7 +187,10 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
// The constructor used for constructing this as a complete class;
// constucts the virtual bases, then calls the base constructor.
- EmitGlobal(GlobalDecl(D, Ctor_Complete));
+ if (!D->getParent()->isAbstract()) {
+ // We don't need to emit the complete ctor if the class is abstract.
+ EmitGlobal(GlobalDecl(D, Ctor_Complete));
+ }
// The constructor used for constructing this as a base class;
// ignores virtual bases.
@@ -244,7 +247,11 @@ void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) {
// The destructor used for destructing this as a most-derived class;
// call the base destructor and then destructs any virtual bases.
- EmitGlobal(GlobalDecl(D, Dtor_Complete));
+ if (!D->getParent()->isAbstract() || D->isVirtual()) {
+ // We don't need to emit the complete ctor if the class is abstract,
+ // unless the destructor is virtual and needs to be in the vtable.
+ EmitGlobal(GlobalDecl(D, Dtor_Complete));
+ }
// The destructor used for destructing this as a base class; ignores
// virtual bases.
diff --git a/test/CodeGenCXX/abstract-class-ctors-dtors.cpp b/test/CodeGenCXX/abstract-class-ctors-dtors.cpp
new file mode 100644
index 0000000000..e1c1a75e47
--- /dev/null
+++ b/test/CodeGenCXX/abstract-class-ctors-dtors.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// Check that we dont emit the complete constructor/destructor for this class.
+struct A {
+ virtual void f() = 0;
+ A();
+ ~A();
+};
+
+// CHECK-NOT: define void @_ZN1AC1Ev
+// CHECK: define void @_ZN1AC2Ev
+// CHECK-NOT: define void @_ZN1AD1Ev
+// CHECK: define void @_ZN1AD2Ev
+A::A() { }
+
+A::~A() { }