summaryrefslogtreecommitdiff
path: root/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp')
-rw-r--r--clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
new file mode 100644
index 0000000..84697be
--- /dev/null
+++ b/clang/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp
@@ -0,0 +1,200 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// See Test9 for test description.
+// CHECK: @_ZTTN5Test91BE = linkonce_odr unnamed_addr constant
+namespace Test1 {
+
+// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial.
+struct A {
+ virtual void f();
+ ~A();
+};
+
+// CHECK: define void @_ZN5Test11AD2Ev
+// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test2 {
+
+// Check that we do initialize the vtable pointer in A::~A() since the destructor body isn't trivial.
+struct A {
+ virtual void f();
+ ~A();
+};
+
+// CHECK: define void @_ZN5Test21AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2), i8***
+A::~A() {
+ f();
+}
+
+}
+
+namespace Test3 {
+
+// Check that we don't initialize the vtable pointer in A::~A(), since the destructor body is trivial
+// and Field's destructor body is also trivial.
+struct Field {
+ ~Field() { }
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test31AD2Ev
+// CHECK-NOT: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2), i8***
+A::~A() {
+
+}
+
+}
+
+namespace Test4 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor body
+// isn't trivial.
+
+void f();
+
+struct Field {
+ ~Field() { f(); }
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test41AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test5 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field's destructor isn't
+// available in this translation unit.
+
+struct Field {
+ ~Field();
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test51AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test6 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a member
+// variable with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field {
+ NonTrivialDestructorBody nonTrivialDestructorBody;
+};
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test61AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test7 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a base
+// class with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field : NonTrivialDestructorBody { };
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test71AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test8 {
+
+// Check that we do initialize the vtable pointer in A::~A(), since Field has a virtual base
+// class with a non-trivial destructor body.
+
+struct NonTrivialDestructorBody {
+ ~NonTrivialDestructorBody();
+};
+
+struct Field : virtual NonTrivialDestructorBody { };
+
+struct A {
+ virtual void f();
+ ~A();
+
+ Field field;
+};
+
+// CHECK: define void @_ZN5Test81AD2Ev
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2), i8***
+A::~A()
+{
+}
+
+}
+
+namespace Test9 {
+
+// Check that we emit a VTT for B, even though we don't initialize the vtable pointer in the destructor.
+struct A { virtual ~A () { } };
+struct B : virtual A {};
+struct C : virtual B {
+ virtual ~C();
+};
+C::~C() {}
+
+}