forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			201 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
	
// 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-LABEL: define void @_ZN5Test11AD2Ev
 | 
						|
// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
 | 
						|
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-LABEL: define void @_ZN5Test21AD2Ev
 | 
						|
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
 | 
						|
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-LABEL: define void @_ZN5Test31AD2Ev
 | 
						|
// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
 | 
						|
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-LABEL: define void @_ZN5Test41AD2Ev
 | 
						|
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
 | 
						|
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-LABEL: define void @_ZN5Test51AD2Ev
 | 
						|
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
 | 
						|
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-LABEL: define void @_ZN5Test61AD2Ev
 | 
						|
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
 | 
						|
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-LABEL: define void @_ZN5Test71AD2Ev
 | 
						|
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
 | 
						|
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-LABEL: define void @_ZN5Test81AD2Ev
 | 
						|
// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2) to i32 (...)**), i32 (...)***
 | 
						|
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() {}
 | 
						|
 | 
						|
}
 |