diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-04 16:12:48 +0000 |
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-05-04 16:12:48 +0000 |
| commit | 0883ccd9eac3b974df00e6548ee319a7dd3646f4 (patch) | |
| tree | d6a70c3518b8dea8be7062438d7e8676820ed17f /test/CodeGenCXX | |
| parent | 60bfabcd8ce617297c0d231f77d14ab507e98796 (diff) | |
Notes
Diffstat (limited to 'test/CodeGenCXX')
41 files changed, 1041 insertions, 758 deletions
diff --git a/test/CodeGenCXX/PR6747.cpp b/test/CodeGenCXX/PR6747.cpp new file mode 100644 index 0000000000000..5a07ce6220136 --- /dev/null +++ b/test/CodeGenCXX/PR6747.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +struct foo { + virtual void bar(); +// CHECK: define available_externally void @_ZN3foo3bazEv + virtual void baz() {} +}; +void zed() { + foo b; + b.baz(); +} diff --git a/test/CodeGenCXX/address-of-fntemplate.cpp b/test/CodeGenCXX/address-of-fntemplate.cpp index c5fa89d86d41b..162c6e5754f35 100644 --- a/test/CodeGenCXX/address-of-fntemplate.cpp +++ b/test/CodeGenCXX/address-of-fntemplate.cpp @@ -11,3 +11,17 @@ void test() { } // CHECK: define linkonce_odr void @_Z1fIiEvT_ // CHECK: define linkonce_odr void @_Z1fIiEvv + +namespace PR6973 { + template<typename T> + struct X { + void f(const T&); + }; + + template<typename T> + int g(); + + void h(X<int (*)()> xf) { + xf.f(&g<int>); + } +} diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp index ea3eafc995532..adb395021e73e 100644 --- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp +++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s struct A { union { @@ -10,3 +10,27 @@ struct A { }; A a; + +namespace PR7021 { + struct X + { + union { long l; }; + }; + + // CHECK: define void @_ZN6PR70211fENS_1XES0_ + void f(X x, X z) { + X x1; + + // CHECK: store i64 1, i64 + x1.l = 1; + + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + X x2(x1); + + X x3; + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 + x3 = x1; + + // CHECK: ret void + } +} diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp new file mode 100644 index 0000000000000..5cca7885b7d72 --- /dev/null +++ b/test/CodeGenCXX/arm.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 %s -triple=thumbv7-apple-darwin3.0.0-iphoneos -fno-use-cxa-atexit -target-abi apcs-gnu -emit-llvm -o - | FileCheck %s + +class foo { +public: + foo(); + virtual ~foo(); +}; + +class bar : public foo { +public: + bar(); +}; + +// The global dtor needs the right calling conv with -fno-use-cxa-atexit +// rdar://7817590 +bar baz; + +// CHECK: @_GLOBAL__D_a() +// CHECK: call arm_apcscc void @_ZN3barD1Ev(%class.bar* @baz) + diff --git a/test/CodeGenCXX/assign-operator.cpp b/test/CodeGenCXX/assign-operator.cpp index cb8867f2f6a3d..c4b64e6e51add 100644 --- a/test/CodeGenCXX/assign-operator.cpp +++ b/test/CodeGenCXX/assign-operator.cpp @@ -1,9 +1,19 @@ -// RUN: %clang_cc1 %s -emit-llvm-only -verify +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -verify -o - |FileCheck %s class x { -int operator=(int); +public: int operator=(int); }; void a() { x a; a = 1u; } + +void f(int i, int j) { + // CHECK: load i32 + // CHECK: load i32 + // CHECK: add nsw i32 + // CHECK: store i32 + // CHECK: store i32 17, i32 + // CHECK: ret + (i += j) = 17; +} diff --git a/test/CodeGenCXX/bitfield-layout.cpp b/test/CodeGenCXX/bitfield-layout.cpp new file mode 100644 index 0000000000000..15f33d27658d5 --- /dev/null +++ b/test/CodeGenCXX/bitfield-layout.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix LP64 %s +// RUN: %clang_cc1 %s -triple=i386-apple-darwin10 -emit-llvm -o - -O3 | FileCheck -check-prefix LP32 %s + +// CHECK-LP64: %union.Test1 = type { i32, [4 x i8] } +union Test1 { + int a; + int b: 39; +} t1; + +// CHECK-LP64: %union.Test2 = type { i8 } +union Test2 { + int : 6; +} t2; + +// CHECK-LP64: %union.Test3 = type { [2 x i8] } +union Test3 { + int : 9; +} t3; + + +#define CHECK(x) if (!(x)) return __LINE__ + +int f() { + struct { + int a; + + unsigned long long b : 65; + + int c; + } c; + + c.a = 0; + c.b = (unsigned long long)-1; + c.c = 0; + + CHECK(c.a == 0); + CHECK(c.b == (unsigned long long)-1); + CHECK(c.c == 0); + +// CHECK-LP64: ret i32 0 +// CHECK-LP32: ret i32 0 + return 0; +} diff --git a/test/CodeGenCXX/block-destruct.cpp b/test/CodeGenCXX/block-destruct.cpp new file mode 100644 index 0000000000000..f809ca2699dea --- /dev/null +++ b/test/CodeGenCXX/block-destruct.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s + +struct A { ~A(); }; + +void f() { + __block A a; +} + +// CHECK: call void @_ZN1AD1Ev diff --git a/test/CodeGenCXX/c-linkage.cpp b/test/CodeGenCXX/c-linkage.cpp new file mode 100644 index 0000000000000..b1f07b7b75621 --- /dev/null +++ b/test/CodeGenCXX/c-linkage.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s +// pr6644 + +extern "C" { + namespace N { + struct X { + virtual void f(); + }; + void X::f() { } + } +} + +// CHECK: define void @_ZN1N1X1fEv diff --git a/test/CodeGenCXX/constructor-init-reference.cpp b/test/CodeGenCXX/constructor-init-reference.cpp index c2f41e1f0cbf3..5e75159765188 100644 --- a/test/CodeGenCXX/constructor-init-reference.cpp +++ b/test/CodeGenCXX/constructor-init-reference.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -emit-llvm -o - %s | grep "store i32\* @x, i32\*\*" int x; -class A { +struct A { int& y; A() : y(x) {} }; diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp index 2c95c91e11140..a8dc7fcec703d 100644 --- a/test/CodeGenCXX/constructors.cpp +++ b/test/CodeGenCXX/constructors.cpp @@ -12,7 +12,7 @@ struct ValueClass { /* Test basic functionality. */ -class A { +struct A { A(struct Undeclared &); A(ValueClass); Member mem; @@ -92,3 +92,15 @@ D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {} // CHECK: call void @_ZN10ValueClassC1Eii( // CHECK: call void @_ZN1AC2E10ValueClass( // CHECK: call void @_ZN6MemberC1Ei( + + +// PR6622: this shouldn't crash +namespace test0 { + struct A {}; + struct B : virtual A { int x; }; + struct C : B {}; + + void test(C &in) { + C tmp = in; + } +} diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp index e523eb0cfd233..e4a06770cd9bb 100644 --- a/test/CodeGenCXX/default-arg-temps.cpp +++ b/test/CodeGenCXX/default-arg-temps.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -o %t -triple=x86_64-apple-darwin9 +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s struct T { T(); @@ -13,20 +13,62 @@ public: X(const X&, const T& t = T()); }; +// CHECK: define void @_Z1gv() void g() { - // RUN: grep "call void @_ZN1TC1Ev" %t | count 4 - // RUN: grep "call void @_ZN1TD1Ev" %t | count 4 + // CHECK: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG1:%.*]]) + // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG1]]) + // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG1]]) f(); + + // CHECK-NEXT: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG2:%.*]]) + // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG2]]) + // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG2]]) f(); + // CHECK-NEXT: call void @_ZN1XC1Ev( X a; + + // CHECK-NEXT: call void @_ZN1TC1Ev( + // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T( + // CHECK-NEXT: call void @_ZN1TD1Ev( X b(a); + + // CHECK-NEXT: call void @_ZN1TC1Ev( + // CHECK-NEXT: call void @_ZN1XC1ERKS_RK1T( + // CHECK-NEXT: call void @_ZN1TD1Ev( X c = a; } -// RUN: grep memset %t class obj{ int a; float b; double d; }; +// CHECK: define void @_Z1hv() void h() { + // CHECK: call void @llvm.memset.p0i8.i64( + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64( obj o = obj(); } + +// PR7028 - mostly this shouldn't crash +namespace test1 { + struct A { A(); }; + struct B { B(); ~B(); }; + + struct C { + C(const B &file = B()); + }; + C::C(const B &file) {} + + struct D { + C c; + A a; + + // CHECK: define linkonce_odr void @_ZN5test11DC2Ev( + // CHECK: call void @_ZN5test11BC1Ev( + // CHECK-NEXT: call void @_ZN5test11CC1ERKNS_1BE( + // CHECK-NEXT: call void @_ZN5test11BD1Ev( + // CHECK: call void @_ZN5test11AC1Ev( + D() : c(), a() {} + }; + + D d; +} diff --git a/test/CodeGenCXX/default-destructor-nested.cpp b/test/CodeGenCXX/default-destructor-nested.cpp index 86942743d4e17..565a7279c56ee 100644 --- a/test/CodeGenCXX/default-destructor-nested.cpp +++ b/test/CodeGenCXX/default-destructor-nested.cpp @@ -2,7 +2,7 @@ // PR6294 class A { - virtual ~A(); +public: virtual ~A(); }; class B { class C; diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp index 7cc264f5c5f5e..87f8698b84c3a 100644 --- a/test/CodeGenCXX/delete.cpp +++ b/test/CodeGenCXX/delete.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o %t +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s void t1(int *a) { delete a; @@ -19,8 +19,11 @@ struct T { int a; }; +// CHECK: define void @_Z2t4P1T void t4(T *t) { - // RUN: grep "call void @_ZN1TD1Ev" %t | count 1 + // CHECK: call void @_ZN1TD1Ev + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @_ZdlPv delete t; } @@ -35,3 +38,22 @@ void f() { delete a; } + +namespace test0 { + struct A { + void *operator new(__SIZE_TYPE__ sz); + void operator delete(void *p) { ::operator delete(p); } + ~A() {} + }; + + // CHECK: define void @_ZN5test04testEPNS_1AE( + void test(A *a) { + // CHECK: call void @_ZN5test01AD1Ev + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @_ZN5test01AdlEPv + delete a; + } + + // CHECK: define linkonce_odr void @_ZN5test01AD1Ev + // CHECK: define linkonce_odr void @_ZN5test01AdlEPv +} diff --git a/test/CodeGenCXX/destructor-debug-info.cpp b/test/CodeGenCXX/destructor-debug-info.cpp new file mode 100644 index 0000000000000..9e32275d33949 --- /dev/null +++ b/test/CodeGenCXX/destructor-debug-info.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -g -S -emit-llvm -o %t %s +// RUN: grep "i32 20, i32 3, metadata" %t | count 1 +// Check there is a line number entry for line 20 where b1 is destructed. +class A { int a; }; +class B { +public: + B() { a = new A; } + ~B() { delete a; } +private: + A *a; +}; + +void fn(B b); + +int i; +void foo() { + if (i) { + B b1; + fn (b1); + } +} diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index afd9da6986462..f2629d19d9022 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll +// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s struct test1_D { @@ -9,14 +9,18 @@ void test1() { throw d1; } -// CHECK: define void @_Z5test1v() nounwind { -// CHECK: %{{exception.ptr|1}} = alloca i8* -// CHECK-NEXT: %{{exception|2}} = call i8* @__cxa_allocate_exception(i64 8) -// CHECK-NEXT: store i8* %{{exception|2}}, i8** %{{exception.ptr|1}} -// CHECK-NEXT: %{{0|3}} = bitcast i8* %{{exception|2}} to %struct.test1_D* -// CHECK-NEXT: %{{tmp|4}} = bitcast %struct.test1_D* %{{0|3}} to i8* -// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{tmp|4}}, i8* bitcast (%struct.test1_D* @d1 to i8*), i64 8, i32 8, i1 false) -// CHECK-NEXT: call void @__cxa_throw(i8* %{{exception|2}}, i8* bitcast (%0* @_ZTI7test1_D to i8*), i8* null) noreturn +// CHECK: define void @_Z5test1v() +// CHECK: [[FREEVAR:%.*]] = alloca i1 +// CHECK-NEXT: [[EXNOBJVAR:%.*]] = alloca i8* +// CHECK-NEXT: store i1 false, i1* [[FREEVAR]] +// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8) +// CHECK-NEXT: store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]] +// CHECK-NEXT: store i1 true, i1* [[FREEVAR]] +// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]] +// CHECK-NEXT: [[EXN2:%.*]] = bitcast [[DSTAR]] [[EXN]] to i8* +// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[EXN2]], i8* bitcast ([[DSTAR]] @d1 to i8*), i64 8, i32 8, i1 false) +// CHECK-NEXT: store i1 false, i1* [[FREEVAR]] +// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%0* @_ZTI7test1_D to i8*), i8* null) noreturn // CHECK-NEXT: unreachable @@ -31,14 +35,19 @@ void test2() { throw d2; } -// CHECK: define void @_Z5test2v() nounwind { -// CHECK: %{{exception.ptr|1}} = alloca i8* -// CHECK-NEXT: %{{exception|2}} = call i8* @__cxa_allocate_exception(i64 16) -// CHECK-NEXT: store i8* %{{exception|2}}, i8** %{{\1}} -// CHECK-NEXT: %{{0|3}} = bitcast i8* %{{exception|2}} to %struct.test2_D* -// CHECK: invoke void @_ZN7test2_DC1ERKS_(%struct.test2_D* %{{0|3}}, %struct.test2_D* @d2) -// CHECK-NEXT: to label %{{invoke.cont|8}} unwind label %{{terminate.handler|4}} -// CHECK: call void @__cxa_throw(i8* %{{exception|2}}, i8* bitcast (%{{0|3}}* @_ZTI7test2_D to i8*), i8* null) noreturn +// CHECK: define void @_Z5test2v() +// CHECK: [[FREEVAR:%.*]] = alloca i1 +// CHECK-NEXT: [[EXNOBJVAR:%.*]] = alloca i8* +// CHECK-NEXT: store i1 false, i1* [[FREEVAR]] +// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16) +// CHECK-NEXT: store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]] +// CHECK-NEXT: store i1 true, i1* [[FREEVAR]] +// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]] +// CHECK-NEXT: invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2) +// CHECK-NEXT: to label %[[CONT:.*]] unwind label %{{.*}} +// : [[CONT]]: (can't check this in Release-Asserts builds) +// CHECK: store i1 false, i1* [[FREEVAR]] +// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%{{.*}}* @_ZTI7test2_D to i8*), i8* null) noreturn // CHECK-NEXT: unreachable @@ -52,20 +61,46 @@ void test3() { throw (volatile test3_D *)0; } -// CHECK: define void @_Z5test3v() nounwind { -// CHECK: %{{exception.ptr|1}} = alloca i8* -// CHECK-NEXT: %{{exception|2}} = call i8* @__cxa_allocate_exception(i64 8) -// CHECK-NEXT: store i8* %{{exception|2}}, i8** %{{exception.ptr|1}} -// CHECK-NEXT: %{{0|3}} = bitcast i8* %{{exception|2}} to %struct.test3_D** -// CHECK-NEXT: store %struct.test3_D* null, %struct.test3_D** -// CHECK-NEXT: call void @__cxa_throw(i8* %{{exception|2}}, i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn -// CHECK-NEXT: unreachable +// CHECK: define void @_Z5test3v() +// CHECK: [[FREEVAR:%.*]] = alloca i1 +// CHECK-NEXT: [[EXNOBJVAR:%.*]] = alloca i8* +// CHECK-NEXT: store i1 false, i1* [[FREEVAR]] +// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 8) +// CHECK-NEXT: store i8* [[EXNOBJ]], i8** [[EXNOBJVAR]] +// CHECK-NEXT: store i1 true, i1* [[FREEVAR]] +// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSS:%[^*]*\*]]* +// CHECK-NEXT: store [[DSS]] null, [[DSS]]* [[EXN]] +// CHECK-NEXT: store i1 false, i1* [[FREEVAR]] +// CHECK-NEXT: call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast (%1* @_ZTIPV7test3_D to i8*), i8* null) noreturn +// CHECK-NEXT: unreachable void test4() { throw; } -// CHECK: define void @_Z5test4v() nounwind { +// CHECK: define void @_Z5test4v() // CHECK: call void @__cxa_rethrow() noreturn // CHECK-NEXT: unreachable + + +// rdar://problem/7696549 +namespace test5 { + struct A { + A(); + A(const A&); + ~A(); + }; + + void test() { + try { throw A(); } catch (A &x) {} + } +// CHECK: define void @_ZN5test54testEv() +// CHECK: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 1) +// CHECK: [[EXNCAST:%.*]] = bitcast i8* [[EXNOBJ]] to [[A:%[^*]*]]* +// CHECK-NEXT: invoke void @_ZN5test51AC1Ev([[A]]* [[EXNCAST]]) +// CHECK: invoke void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*), i8* bitcast (void ([[A]]*)* @_ZN5test51AD1Ev to i8*)) noreturn +// CHECK-NEXT: to label {{%.*}} unwind label %[[HANDLER:[^ ]*]] +// : [[HANDLER]]: (can't check this in Release-Asserts builds) +// CHECK: {{%.*}} = call i32 @llvm.eh.typeid.for(i8* bitcast ({{%.*}}* @_ZTIN5test51AE to i8*)) +} diff --git a/test/CodeGenCXX/empty-classes.cpp b/test/CodeGenCXX/empty-classes.cpp new file mode 100644 index 0000000000000..59124e3d55b25 --- /dev/null +++ b/test/CodeGenCXX/empty-classes.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s + +struct Empty { }; + +struct A { + explicit A(unsigned a = 0xffffffff) : a(a) { } + + unsigned a; +}; + +struct B : A, Empty { + B() : A(), Empty() { } +}; + +struct C : A, Empty { + C() : A(), Empty() { } + C(const C& other) : A(0x12345678), Empty(other) { } +}; + +struct D : A, Empty { + D& operator=(const D& other) { + a = 0x87654321; + Empty::operator=(other); + + return *this; + } +}; + +#define CHECK(x) if (!(x)) return __LINE__ + +// PR7012 +// CHECK: define i32 @_Z1fv() +int f() { + B b1; + + // Check that A::a is not overwritten by the Empty default constructor. + CHECK(b1.a == 0xffffffff); + + C c1; + C c2(c1); + + // Check that A::a has the value set in the C::C copy constructor. + CHECK(c2.a == 0x12345678); + + D d1, d2; + d2 = d1; + + // Check that A::as has the value set in the D copy assignment operator. + CHECK(d2.a == 0x87654321); + + // Success! + // CHECK: ret i32 0 + return 0; +} + +#ifdef HARNESS +extern "C" void printf(const char *, ...); + +int main() { + int result = f(); + + if (result == 0) + printf("success!\n"); + else + printf("test on line %d failed!\n", result); + + return result; +} +#endif diff --git a/test/CodeGenCXX/exceptions-no-rtti.cpp b/test/CodeGenCXX/exceptions-no-rtti.cpp new file mode 100644 index 0000000000000..c26abb26af9c8 --- /dev/null +++ b/test/CodeGenCXX/exceptions-no-rtti.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -fno-rtti -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s + +// CHECK: @_ZTIN5test11AE = weak_odr constant +// CHECK: @_ZTIN5test11BE = weak_odr constant +// CHECK: @_ZTIN5test11CE = weak_odr constant +// CHECK: @_ZTIN5test11DE = weak_odr constant +// CHECK: @_ZTIPN5test11DE = weak_odr constant {{.*}} @_ZTIN5test11DE + +// PR6974: this shouldn't crash +namespace test0 { + class err {}; + + void f(void) { + try { + } catch (err &) { + } + } +} + +namespace test1 { + // These classes have key functions defined out-of-line. + // Under normal circumstances, we wouldn't generate RTTI for them; + // under -fno-rtti, we generate RTTI only when required by EH. + class A { virtual void foo(); }; + class B { virtual void foo(); }; + class C { virtual void foo(); }; + class D { virtual void foo(); }; + + void opaque(); + + void test0() { + throw A(); + } + + void test1() throw(B) { + opaque(); + } + + void test2() { + try { + opaque(); + } catch (C&) {} + } + + void test3(D *ptr) { + throw ptr; + }; +} diff --git a/test/CodeGenCXX/field-access-debug-info.cpp b/test/CodeGenCXX/field-access-debug-info.cpp new file mode 100644 index 0000000000000..907fe04be57db --- /dev/null +++ b/test/CodeGenCXX/field-access-debug-info.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -g -S -masm-verbose -o %t %s +// RUN: grep DW_AT_accessibility %t + +class A { +public: + int p; +private: + int pr; +}; + +A a; diff --git a/test/CodeGenCXX/implicit-copy-assign-operator.cpp b/test/CodeGenCXX/implicit-copy-assign-operator.cpp new file mode 100644 index 0000000000000..0ec89fceec5ba --- /dev/null +++ b/test/CodeGenCXX/implicit-copy-assign-operator.cpp @@ -0,0 +1,56 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10.0.0 -o - %s | FileCheck %s +struct A { + A &operator=(const A&); + A &operator=(A&); +}; + +struct B { + B &operator=(B&); +}; + +struct C { + virtual C& operator=(const C&); +}; + +struct POD { + int array[3][4]; +}; + +struct CopyByValue { + CopyByValue(const CopyByValue&); + CopyByValue &operator=(CopyByValue); +}; + +struct D : A, B, virtual C { + int scalar; + int scalar_array[2][3]; + B class_member; + C class_member_array[2][3]; + POD pod_array[2][3]; + + union { + int x; + float f[3]; + }; + + CopyByValue by_value; +}; + +void test_D(D d1, D d2) { + d1 = d2; +} + +// CHECK: define linkonce_odr %struct.D* @_ZN1DaSERS_ +// CHECK: {{call.*_ZN1AaSERS_}} +// CHECK: {{call.*_ZN1BaSERS_}} +// CHECK: {{call.*_ZN1CaSERKS_}} +// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 24}} +// CHECK: {{call.*_ZN1BaSERS_}} +// CHECK: br +// CHECK: {{call.*_ZN1CaSERKS_}} +// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 288}} +// CHECK: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}} +// CHECK: call void @_ZN11CopyByValueC1ERKS_ +// CHECK: {{call.*_ZN11CopyByValueaSES_}} +// CHECK: ret + diff --git a/test/CodeGenCXX/instantiate-init-list.cpp b/test/CodeGenCXX/instantiate-init-list.cpp index 676d2994e7ed4..49c6f51c77510 100644 --- a/test/CodeGenCXX/instantiate-init-list.cpp +++ b/test/CodeGenCXX/instantiate-init-list.cpp @@ -5,7 +5,7 @@ struct F { }; void G(); template<class T> class A { - A(); +public: A(); }; template<class T> A<T>::A() { static F f = { G }; diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp index 22949da64ad86..6a2994407167e 100644 --- a/test/CodeGenCXX/mangle-template.cpp +++ b/test/CodeGenCXX/mangle-template.cpp @@ -104,3 +104,43 @@ namespace test8 { // CHECK: define weak_odr void @_ZN5test81fIiEEvNS_5int_cIXsrNS_4metaIT_E4typeE5valueEEE template void f<int>(int_c<sizeof(int)>); } + +namespace test9 { + template<typename T> + struct supermeta { + template<typename U> + struct apply { + typedef T U::*type; + }; + }; + + struct X { }; + + template<typename T, typename U> + typename supermeta<T>::template apply<U>::type f(); + + void test_f() { + // CHECK: @_ZN5test91fIiNS_1XEEENS_9supermetaIT_E5applyIT0_E4typeEv() + // Note: GCC incorrectly mangles this as + // _ZN5test91fIiNS_1XEEENS_9supermetaIT_E5apply4typeEv, while EDG + // gets it right. + f<int, X>(); + } +} + +namespace test10 { + template<typename T> + struct X { + template<typename U> + struct definition { + }; + }; + + // CHECK: _ZN6test101fIidEENS_1XIT_E10definitionIT0_EES2_S5_ + template<typename T, typename U> + typename X<T>::template definition<U> f(T, U) { } + + void g(int i, double d) { + f(i, d); + } +} diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index ec9c08c0ccaad..8f3d356848843 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -450,7 +450,7 @@ namespace test7 { // CHECK: define weak_odr void @_ZN5test81AILZNS_1B5valueEEE3incEv namespace test8 { template <int &counter> class A { void inc() { counter++; } }; - class B { static int value; }; + class B { public: static int value; }; template class A<B::value>; } // CHECK: declare void @_ZN5test91fIiNS_3barEEEvRKNT0_3baz1XE @@ -468,3 +468,12 @@ namespace test9 { f<int, bar>( 0); } } + +// <rdar://problem/7825453> +namespace test10 { + template <char P1> struct S {}; + template <char P2> void f(struct S<false ? 'a' : P2> ) {} + + // CHECK: define weak_odr void @_ZN6test101fILc3EEEvNS_1SIXquLb0ELc97ET_EEE( + template void f<(char) 3>(struct S<3>); +} diff --git a/test/CodeGenCXX/member-function-pointer-calls.cpp b/test/CodeGenCXX/member-function-pointer-calls.cpp index e1f2eb78d4143..6f0ef81fe35dc 100644 --- a/test/CodeGenCXX/member-function-pointer-calls.cpp +++ b/test/CodeGenCXX/member-function-pointer-calls.cpp @@ -9,18 +9,17 @@ int f(A* a, int (A::*fp)()) { } // CHECK: define i32 @_Z2g1v() +// CHECK-NEXT: {{.*}}: +// CHECK-NEXT: ret i32 1 int g1() { A a; - - // CHECK: call i32 @_ZN1A3vf1Ev - // CHECK-NEXT: ret i32 return f(&a, &A::vf1); } +// CHECK: define i32 @_Z2g2v() +// CHECK-NEXT: {{.*}}: +// CHECK-NEXT: ret i32 2 int g2() { A a; - - // CHECK: call i32 @_ZN1A3vf2Ev - // CHECK-NEXT: ret i32 return f(&a, &A::vf2); } diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp index f7c445b1cb108..e4beee15bb178 100644 --- a/test/CodeGenCXX/member-function-pointers.cpp +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s +// RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-apple-darwin9 | FileCheck -check-prefix LP32 %s struct A { int a; void f(); virtual void vf1(); virtual void vf2(); }; struct B { int b; virtual void g(); }; @@ -12,10 +13,12 @@ void (C::*pc)(); // CHECK: @pa2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 0 }, align 8 void (A::*pa2)() = &A::f; -// CHECK: @pa3 = global %0 { i64 1, i64 0 }, align 8 +// CHECK: @pa3 = global %0 { i64 1, i64 0 }, align 8 +// CHECK-LP32: @pa3 = global %0 { i32 1, i32 0 }, align 4 void (A::*pa3)() = &A::vf1; -// CHECK: @pa4 = global %0 { i64 9, i64 0 }, align 8 +// CHECK: @pa4 = global %0 { i64 9, i64 0 }, align 8 +// CHECK-LP32: @pa4 = global %0 { i32 5, i32 0 }, align 4 void (A::*pa4)() = &A::vf2; // CHECK: @pc2 = global %0 { i64 ptrtoint (void (%struct.A*)* @_ZN1A1fEv to i64), i64 16 }, align 8 @@ -51,16 +54,24 @@ void f2() { // CHECK: store i64 0, i64* [[pa2adj]] void (A::*pa2)() = &A::f; - // CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 - // CHECK: store i64 1, i64* [[pa3ptr]] - // CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1 - // CHECK: store i64 0, i64* [[pa3adj]] + // CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 + // CHECK: store i64 1, i64* [[pa3ptr]] + // CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1 + // CHECK: store i64 0, i64* [[pa3adj]] + // CHECK-LP32: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0 + // CHECK-LP32: store i32 1, i32* [[pa3ptr]] + // CHECK-LP32: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1 + // CHECK-LP32: store i32 0, i32* [[pa3adj]] void (A::*pa3)() = &A::vf1; - // CHECK: [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0 - // CHECK: store i64 9, i64* [[pa4ptr]] - // CHECK: [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1 - // CHECK: store i64 0, i64* [[pa4adj]] + // CHECK: [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0 + // CHECK: store i64 9, i64* [[pa4ptr]] + // CHECK: [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1 + // CHECK: store i64 0, i64* [[pa4adj]] + // CHECK-LP32: [[pa4ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 0 + // CHECK-LP32: store i32 5, i32* [[pa4ptr]] + // CHECK-LP32: [[pa4adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa4, i32 0, i32 1 + // CHECK-LP32: store i32 0, i32* [[pa4adj]] void (A::*pa4)() = &A::vf2; } @@ -173,3 +184,9 @@ namespace PR6258 { void (A::*pf)(bool) = &A::f; } } + +// PR7027 +namespace PR7027 { + struct X { void test( ); }; + void testX() { &X::test; } +} diff --git a/test/CodeGenCXX/member-initializers.cpp b/test/CodeGenCXX/member-initializers.cpp index 81dcee7e407a0..244a164b9fe2d 100644 --- a/test/CodeGenCXX/member-initializers.cpp +++ b/test/CodeGenCXX/member-initializers.cpp @@ -16,7 +16,7 @@ struct B : A { int f() { B b; - // CHECK: call i32 @_ZN1B1fEv + // CHECK: ret i32 2 return b.i; } diff --git a/test/CodeGenCXX/namespace-aliases.cpp b/test/CodeGenCXX/namespace-aliases.cpp index 74b8ebab4a54d..8624eb75bf29a 100644 --- a/test/CodeGenCXX/namespace-aliases.cpp +++ b/test/CodeGenCXX/namespace-aliases.cpp @@ -1,3 +1,9 @@ // RUN: %clang_cc1 -emit-llvm-only %s namespace A { } namespace B = A; + +namespace b {} + +void foo() { + namespace a = b; +} diff --git a/test/CodeGenCXX/new-operator-phi.cpp b/test/CodeGenCXX/new-operator-phi.cpp index 38467ad31f9bc..49859acf4fa60 100644 --- a/test/CodeGenCXX/new-operator-phi.cpp +++ b/test/CodeGenCXX/new-operator-phi.cpp @@ -2,7 +2,7 @@ // PR5454 #include <stddef.h> -class X {static void * operator new(size_t size) throw(); X(int); }; +struct X {static void * operator new(size_t size) throw(); X(int); }; int a(), b(); void b(int x) { diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp index ca7c52f2cc0d7..885158f8a0548 100644 --- a/test/CodeGenCXX/new.cpp +++ b/test/CodeGenCXX/new.cpp @@ -90,9 +90,19 @@ A* t10() { return new(1, 2, 3.45, 100) A; } -struct B { }; +struct B { int a; }; void t11() { // CHECK: call noalias i8* @_Znwm // CHECK: call void @llvm.memset.p0i8.i64( B* b = new B(); } + +struct Empty { }; + +// We don't need to initialize an empty class. +void t12() { + // CHECK: define void @_Z3t12v + // CHECK-NOT: br label + // CHECK: ret void + (void)new Empty[10]; +} diff --git a/test/CodeGenCXX/operator-new.cpp b/test/CodeGenCXX/operator-new.cpp index da64fc1b2d4e0..f718faebef000 100644 --- a/test/CodeGenCXX/operator-new.cpp +++ b/test/CodeGenCXX/operator-new.cpp @@ -6,6 +6,7 @@ class teste { int A; +public: teste() : A(2) {} }; diff --git a/test/CodeGenCXX/reference-in-blocks.cpp b/test/CodeGenCXX/reference-in-blocks.cpp new file mode 100644 index 0000000000000..c020bab0f778c --- /dev/null +++ b/test/CodeGenCXX/reference-in-blocks.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fblocks %s -emit-llvm -o %t + +extern "C" int printf(const char*, ...); + +template<typename T> class range { +public: +T _i; + range(T i) {_i = i;}; + T get() {return _i;}; +}; + +int main() { + + // works + void (^bl)(range<int> ) = ^(range<int> i){printf("Hello Blocks %d\n", i.get()); }; + + //crashes in godegen? + void (^bl2)(range<int>& ) = ^(range<int>& i){printf("Hello Blocks %d\n", i.get()); }; + return 0; +} + diff --git a/test/CodeGenCXX/rtti-fundamental.cpp b/test/CodeGenCXX/rtti-fundamental.cpp index 473f48db67add..6826321cd5ebd 100644 --- a/test/CodeGenCXX/rtti-fundamental.cpp +++ b/test/CodeGenCXX/rtti-fundamental.cpp @@ -8,8 +8,10 @@ std::type_info foo() { namespace __cxxabiv1 { struct __fundamental_type_info { - virtual ~__fundamental_type_info() {} + virtual ~__fundamental_type_info(); }; + + __fundamental_type_info::~__fundamental_type_info() { } } // CHECK: @_ZTIv = weak_odr constant diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp index a67d137d6a1d8..750da02603b3a 100644 --- a/test/CodeGenCXX/static-init.cpp +++ b/test/CodeGenCXX/static-init.cpp @@ -34,3 +34,14 @@ inline void h2() { void h3() { h2(); } + +// PR6980: this shouldn't crash +namespace test0 { + struct A { A(); }; + __attribute__((noreturn)) int throw_exception(); + + void test() { + throw_exception(); + static A r; + } +} diff --git a/test/CodeGenCXX/static-local-in-local-class.cpp b/test/CodeGenCXX/static-local-in-local-class.cpp new file mode 100644 index 0000000000000..d9e044ce9d97d --- /dev/null +++ b/test/CodeGenCXX/static-local-in-local-class.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -emit-llvm -o %t %s +// PR6769 + +struct X { + static void f(); +}; + +void X::f() { + static int *i; + { + struct Y { + static void g() { + i = new int(); + *i = 100; + (*i) = (*i) +1; + } + }; + (void)Y::g(); + } + (void)i; +} diff --git a/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp b/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp index 921113a148414..41ae08470a3de 100644 --- a/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp +++ b/test/CodeGenCXX/template-anonymous-union-member-initializer.cpp @@ -4,6 +4,7 @@ class A { union { void *d; }; +public: A() : d(0) { } }; diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp index 416c0a1a20729..4a3857542d06d 100644 --- a/test/CodeGenCXX/template-instantiation.cpp +++ b/test/CodeGenCXX/template-instantiation.cpp @@ -40,6 +40,7 @@ namespace test1 { namespace test2 { template<typename T1> class C { + public: virtual ~C(); void zedbar(double) { } diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp index 4aad3c0056ca0..eb543cb545525 100644 --- a/test/CodeGenCXX/temporaries.cpp +++ b/test/CodeGenCXX/temporaries.cpp @@ -301,3 +301,22 @@ namespace PR6648 { zed(foo); } } + +namespace UserConvertToValue { + struct X { + X(int); + X(const X&); + ~X(); + }; + + void f(X); + + // CHECK: void @_ZN18UserConvertToValue1gEv() + void g() { + // CHECK: call void @_ZN18UserConvertToValue1XC1Ei + // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE + // CHECK: call void @_ZN18UserConvertToValue1XD1Ev + // CHECK: ret void + f(1); + } +} diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp index 37891bd6af67e..35be159aac9d4 100644 --- a/test/CodeGenCXX/value-init.cpp +++ b/test/CodeGenCXX/value-init.cpp @@ -23,3 +23,29 @@ void test_value_init() { C c = { 17 } ; // CHECK: call void @_ZN1CD1Ev } + +enum enum_type { negative_number = -1, magic_number = 42 }; + +class enum_holder +{ + enum_type m_enum; + +public: + enum_holder() : m_enum(magic_number) { } +}; + +struct enum_holder_and_int +{ + enum_holder e; + int i; +}; + +// CHECK: _Z24test_enum_holder_and_intv() +void test_enum_holder_and_int() { + // CHECK: alloca + // CHECK-NEXT: bitcast + // CHECK-NEXT: call void @llvm.memset + // CHECK-NEXT: call void @_ZN19enum_holder_and_intC1Ev + enum_holder_and_int(); + // CHECK-NEXT: ret void +} diff --git a/test/CodeGenCXX/virt-template-vtable.cpp b/test/CodeGenCXX/virt-template-vtable.cpp index 76a1240731b2c..b968f38c82636 100644 --- a/test/CodeGenCXX/virt-template-vtable.cpp +++ b/test/CodeGenCXX/virt-template-vtable.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s template<class T> class A { +public: A() {} virtual void a() {} }; diff --git a/test/CodeGenCXX/virt.cpp b/test/CodeGenCXX/virt.cpp deleted file mode 100644 index 874ffb1ddf29f..0000000000000 --- a/test/CodeGenCXX/virt.cpp +++ /dev/null @@ -1,696 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -O0 -S %s -o %t-64.s -// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s - -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t-64.ll -// RUN: FileCheck -check-prefix LPLL64 --input-file=%t-64.ll %s - - -// CHECK-LP64: main: -// CHECK-LP64: movl $1, 12(%rax) -// CHECK-LP64: movl $2, 8(%rax) - -struct B { - virtual void bar1(); - virtual void bar2(); - int b; -}; -void B::bar1() { } -void B::bar2() { } - -// CHECK-LPLL64:@_ZTV1B = constant [4 x i8*] [i8* null, i8* bitcast (%0* @_ZTI1B to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar1Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar2Ev to i8*)] - -struct C { - virtual void bee1(); - virtual void bee2(); -}; -void C::bee1() { } -void C::bee2() { } - -struct D { - virtual void boo(); -}; -void D::boo() { } - -struct D1 { - virtual void bar(); - virtual void bar2(); - virtual void bar3(); - virtual void bar4(); - virtual void bar5(); - void *d1; -}; -void D1::bar() { } - -class F : virtual public D1, virtual public D { -public: - virtual void foo(); - void *f; -}; -void F::foo() { } - -// CHECK-LPLL64:@_ZTV1F = constant [19 x i8*] [i8* null, i8* inttoptr (i64 16 to i8*), i8* null, i8* null, i8* bitcast (%1* @_ZTI1F to i8*), i8* bitcast (void (%class.test14*)* @_ZN1D3booEv to i8*), i8* bitcast (void (%class.F*)* @_ZN1F3fooEv to i8*), i8* null, i8* null, i8* null, i8* null, i8* null, i8* inttoptr (i64 -16 to i8*), i8* bitcast (%1* @_ZTI1F to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D13barEv to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D14bar2Ev to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D14bar3Ev to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D14bar4Ev to i8*), i8* bitcast (void (%struct.D1*)* @_ZN2D14bar5Ev to i8*)] - - -struct E { - int e; -}; - -static_assert (sizeof (C) == (sizeof(void *)), "vtable pointer layout"); - -class A : public E, public B, public C { -public: - virtual void foo1(); - virtual void foo2(); - A() { } - int a; -} *ap; -void A::foo1() { } -void A::foo2() { } - -// CHECK-LPLL64:@_ZTV1A = constant [10 x i8*] [i8* null, i8* bitcast (%2* @_ZTI1A to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar1Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar2Ev to i8*), i8* bitcast (void (%class.A*)* @_ZN1A4foo1Ev to i8*), i8* bitcast (void (%class.A*)* @_ZN1A4foo2Ev to i8*), i8* inttoptr (i64 -16 to i8*), i8* bitcast (%2* @_ZTI1A to i8*), i8* bitcast (void (%class.test14*)* @_ZN1C4bee1Ev to i8*), i8* bitcast (void (%class.test14*)* @_ZN1C4bee2Ev to i8*)] - -int main() { - A a; - B b; - ap->e = 1; - ap->b = 2; -} - - -struct test12_A { - virtual void foo0() { } - virtual void foo(); -} *test12_pa; - -struct test12_B : public test12_A { - virtual void foo() { } -} *test12_pb; - -struct test12_D : public test12_B { -} *test12_pd; - - -struct test6_B2 { virtual void funcB2(); char b[1000]; }; -struct test6_B1 : virtual test6_B2 { virtual void funcB1(); }; - -struct test6_D : test6_B2, virtual test6_B1 { -}; - -// CHECK-LP64: .zerofill __DATA,__common,_d6,2024,4 - -struct test7_B2 { virtual void funcB2(); }; -struct test7_B1 : virtual test7_B2 { virtual void funcB1(); }; - -struct test7_D : test7_B2, virtual test7_B1 { -}; - -// FIXME: we were checking for an alignment of 3 (?) -// CHECK-LP64: .zerofill __DATA,__common,_d7,16, - - -struct test3_B3 { virtual void funcB3(); }; -struct test3_B2 : virtual test3_B3 { virtual void funcB2(); }; -struct test3_B1 : virtual test3_B2 { virtual void funcB1(); }; - -struct test3_D : virtual test3_B1 { - virtual void funcD() { } -}; - -// CHECK-LPLL64:@_ZTV7test3_D = weak_odr constant [12 x i8*] [i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI7test3_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test3_B36funcB3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test3_B26funcB2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test3_B16funcB1Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN7test3_D5funcDEv to i8*)] - - -struct test4_D : virtual B, virtual C { -}; - -// CHECK-LPLL64:@_ZTV7test4_D = weak_odr constant [14 x i8*] [i8* null, i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* null, i8* bitcast (%1* @_ZTI7test4_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN1C4bee1Ev to i8*), i8* bitcast (void (%class.test14*)* @_ZN1C4bee2Ev to i8*), i8* null, i8* null, i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI7test4_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar1Ev to i8*), i8* bitcast (void (%struct.B*)* @_ZN1B4bar2Ev to i8*)] - - -struct test5_B3 { virtual void funcB3(); }; -struct test5_B2 : virtual test5_B3 { virtual void funcB2(); }; -struct test5_B1 : virtual test5_B2 { virtual void funcB1(); }; - -struct test5_B23 { virtual void funcB23(); }; -struct test5_B22 : virtual test5_B23 { virtual void funcB22(); }; -struct test5_B21 : virtual test5_B22 { virtual void funcB21(); }; - - -struct B232 { virtual void funcB232(); }; -struct B231 { virtual void funcB231(); }; - -struct test5_B33 { virtual void funcB33(); }; -struct test5_B32 : virtual test5_B33, virtual B232 { virtual void funcB32(); }; -struct test5_B31 : virtual test5_B32, virtual B231 { virtual void funcB31(); }; - -struct test5_D : virtual test5_B1, virtual test5_B21, virtual test5_B31 { - virtual void funcD() { } -}; - -// CHECK-LPLL64:@_ZTV7test5_D = weak_odr constant [50 x i8*] [i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test5_B36funcB3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test5_B26funcB2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test5_B16funcB1Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN7test5_D5funcDEv to i8*), i8* null, i8* null, i8* null, i8* null, i8* null, i8* inttoptr (i64 -8 to i8*), i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test5_B237funcB23Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test5_B227funcB22Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test5_B217funcB21Ev to i8*), i8* null, i8* inttoptr (i64 16 to i8*), i8* null, i8* null, i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* inttoptr (i64 -16 to i8*), i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test5_B337funcB33Ev to i8*), i8* bitcast (void (%class.test20_D*)* @_ZN9test5_B327funcB32Ev to i8*), i8* bitcast (void (%class.test23_D*)* @_ZN9test5_B317funcB31Ev to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN4B2328funcB232Ev to i8*), i8* null, i8* inttoptr (i64 -32 to i8*), i8* bitcast (%2* @_ZTI7test5_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN4B2318funcB231Ev to i8*)] - -struct test8_B1 { - virtual void ftest8_B1() { } -}; -struct test8_B2aa { - virtual void ftest8_B2aa() { } - int i; -}; -struct test8_B2ab { - virtual void ftest8_B2ab() { } - int i; -}; -struct test8_B2a : virtual test8_B2aa, virtual test8_B2ab { - virtual void ftest8_B2a() { } -}; -struct test8_B2b { - virtual void ftest8_B2b() { } -}; -struct test8_B2 : test8_B2a, test8_B2b { - virtual void ftest8_B2() { } -}; -struct test8_B3 { - virtual void ftest8_B3() { } -}; -class test8_D : test8_B1, test8_B2, test8_B3 { -}; - -// CHECK-LPLL64:@_ZTV7test8_D = weak_odr constant [25 x i8*] [i8* inttoptr (i64 48 to i8*), i8* inttoptr (i64 32 to i8*), i8* null, i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test8_B19ftest8_B1Ev to i8*), i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%struct.test10_B2a*)* @_ZN9test8_B2a10ftest8_B2aEv to i8*), i8* bitcast (void (%struct.test15_D*)* @_ZN8test8_B29ftest8_B2Ev to i8*), i8* inttoptr (i64 -16 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test8_B2b10ftest8_B2bEv to i8*), i8* inttoptr (i64 -24 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test8_B39ftest8_B3Ev to i8*), i8* null, i8* inttoptr (i64 -32 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2aa11ftest8_B2aaEv to i8*), i8* null, i8* inttoptr (i64 -48 to i8*), i8* bitcast (%2* @_ZTI7test8_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2ab11ftest8_B2abEv to i8*)] - -// CHECK-LPLL64:@_ZTC7test8_D8_8test8_B2 = internal constant [14 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* null, i8* bitcast (%1* @_ZTI8test8_B2 to i8*), i8* bitcast (void (%struct.test10_B2a*)* @_ZN9test8_B2a10ftest8_B2aEv to i8*), i8* bitcast (void (%struct.test15_D*)* @_ZN8test8_B29ftest8_B2Ev to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* bitcast (%1* @_ZTI8test8_B2 to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2aa11ftest8_B2aaEv to i8*), i8* null, i8* inttoptr (i64 -40 to i8*), i8* bitcast (%1* @_ZTI8test8_B2 to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2ab11ftest8_B2abEv to i8*)] ; <[14 x i8*]*> [#uses=3] - -// CHECK-LPLL64:@_ZTC7test8_D8_9test8_B2a = internal constant [13 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* null, i8* bitcast (%1* @_ZTI9test8_B2a to i8*), i8* bitcast (void (%struct.test10_B2a*)* @_ZN9test8_B2a10ftest8_B2aEv to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* bitcast (%1* @_ZTI9test8_B2a to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2aa11ftest8_B2aaEv to i8*), i8* null, i8* inttoptr (i64 -40 to i8*), i8* bitcast (%1* @_ZTI9test8_B2a to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test8_B2ab11ftest8_B2abEv to i8*)] ; <[13 x i8*]*> [#uses=3] - -// CHECK-LPLL64:@_ZTT7test8_D = weak_odr constant [10 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTV7test8_D, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTC7test8_D8_8test8_B2, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([13 x i8*]* @_ZTC7test8_D8_9test8_B2a, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([13 x i8*]* @_ZTC7test8_D8_9test8_B2a, i64 0, i64 8) to i8*), i8* bitcast (i8** getelementptr inbounds ([13 x i8*]* @_ZTC7test8_D8_9test8_B2a, i64 0, i64 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTC7test8_D8_8test8_B2, i64 0, i64 9) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTC7test8_D8_8test8_B2, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTV7test8_D, i64 0, i64 9) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTV7test8_D, i64 0, i64 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTV7test8_D, i64 0, i64 24) to i8*)] - - -struct test9_B3 { virtual void funcB3(); int i; }; -struct test9_B2 : virtual test9_B3 { virtual void funcB2(); int i; }; -struct test9_B1 : virtual test9_B2 { virtual void funcB1(); int i; }; - -struct test9_B23 { virtual void funcB23(); int i; }; -struct test9_B22 : virtual test9_B23 { virtual void funcB22(); int i; }; -struct test9_B21 : virtual test9_B22 { virtual void funcB21(); int i; }; - - -struct test9_B232 { virtual void funcB232(); int i; }; -struct test9_B231 { virtual void funcB231(); int i; }; - -struct test9_B33 { virtual void funcB33(); int i; }; -struct test9_B32 : virtual test9_B33, virtual test9_B232 { virtual void funcB32(); int i; }; -struct test9_B31 : virtual test9_B32, virtual test9_B231 { virtual void funcB31(); int i; }; - -struct test9_D : virtual test9_B1, virtual test9_B21, virtual test9_B31 { - virtual void funcD() { } -}; - -// CHECK-LPLL64:@_ZTV7test9_D = weak_odr constant [70 x i8*] [i8* inttoptr (i64 168 to i8*), i8* inttoptr (i64 152 to i8*), i8* inttoptr (i64 136 to i8*), i8* inttoptr (i64 120 to i8*), i8* inttoptr (i64 104 to i8*), i8* inttoptr (i64 88 to i8*), i8* inttoptr (i64 72 to i8*), i8* inttoptr (i64 56 to i8*), i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 8 to i8*), i8* null, i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_D*)* @_ZN7test9_D5funcDEv to i8*), i8* null, i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_B1*)* @_ZN8test9_B16funcB1Ev to i8*), i8* null, i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -24 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN8test9_B26funcB2Ev to i8*), i8* null, i8* inttoptr (i64 -40 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN8test9_B36funcB3Ev to i8*), i8* null, i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -56 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_B1*)* @_ZN9test9_B217funcB21Ev to i8*), i8* null, i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -72 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test9_B227funcB22Ev to i8*), i8* null, i8* inttoptr (i64 -88 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN9test9_B237funcB23Ev to i8*), i8* null, i8* inttoptr (i64 64 to i8*), i8* inttoptr (i64 48 to i8*), i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -104 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_B31*)* @_ZN9test9_B317funcB31Ev to i8*), i8* null, i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -120 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.test9_B1*)* @_ZN9test9_B327funcB32Ev to i8*), i8* null, i8* inttoptr (i64 -136 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN9test9_B337funcB33Ev to i8*), i8* null, i8* inttoptr (i64 -152 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test9_B2328funcB232Ev to i8*), i8* null, i8* inttoptr (i64 -168 to i8*), i8* bitcast (%2* @_ZTI7test9_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test9_B2318funcB231Ev to i8*)] ; <[70 x i8*]*> [#uses=12] - - -struct test10_O { int i; }; - -struct test10_B1 : virtual test10_O { - virtual void ftest10_B1() { } -}; - -struct test10_B2aa : virtual test10_O { - int i; -}; -struct test10_B2ab : virtual test10_O { - int i; -}; -struct test10_B2a : virtual test10_B2aa, virtual test10_B2ab,virtual test10_O { - virtual void ftest10_B2a() { } -}; -struct test10_B2b : virtual test10_O { - virtual void ftest10_B2b() { } -}; -struct test10_B2 : test10_B2a { - virtual void ftest10_B2() { } -}; -class test10_D : test10_B1, test10_B2 { - - void ftest10_B2aa() { } -}; - -// CHECK-LPLL64:@_ZTV8test10_D = weak_odr constant [19 x i8*] [i8* inttoptr (i64 40 to i8*), i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 16 to i8*), i8* null, i8* bitcast (%1* @_ZTI8test10_D to i8*), i8* bitcast (void (%struct.test10_B1*)* @_ZN9test10_B110ftest10_B1Ev to i8*), i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI8test10_D to i8*), i8* bitcast (void (%struct.test10_B2a*)* @_ZN10test10_B2a11ftest10_B2aEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN9test10_B210ftest10_B2Ev to i8*), i8* inttoptr (i64 -8 to i8*), i8* inttoptr (i64 -24 to i8*), i8* bitcast (%1* @_ZTI8test10_D to i8*), i8* inttoptr (i64 -24 to i8*), i8* inttoptr (i64 -40 to i8*), i8* bitcast (%1* @_ZTI8test10_D to i8*)] ; <[19 x i8*]*> [#uses=4] - - -struct test11_B { - virtual void B1() { } - virtual void D() { } - virtual void B2() { } -}; - -struct test11_D : test11_B { - virtual void D1() { } - virtual void D() { } - virtual void D2() { } -}; - -// CHECK-LPLL64:@_ZTV8test11_D = weak_odr constant [7 x i8*] [i8* null, i8* bitcast (%4* @_ZTI8test11_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test11_B2B1Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test11_D1DEv to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test11_B2B2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test11_D2D1Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test11_D2D2Ev to i8*)] - - -struct test13_B { - virtual void B1() { } - virtual void D() { } - virtual void Da(); - virtual void Db() { } - virtual void Dc() { } - virtual void B2() { } - int i; -}; - - -struct test13_NV1 { - virtual void fooNV1() { } - virtual void D() { } -}; - - -struct test13_B2 : /* test13_NV1, */ virtual test13_B { - virtual void B2a() { } - virtual void B2() { } - virtual void D() { } - virtual void Da(); - virtual void Dd() { } - virtual void B2b() { } - int i; -}; - - -struct test13_D : test13_NV1, virtual test13_B2 { - virtual void D1() { } - virtual void D() { } - virtual void Db() { } - virtual void Dd() { } - virtual void D2() { } - virtual void fooNV1() { } -}; - -// CHECK-LPLL64:@_ZTV8test13_D = weak_odr constant [39 x i8*] [i8* inttoptr (i64 24 to i8*), i8* inttoptr (i64 8 to i8*), i8* null, i8* bitcast (%1* @_ZTI8test13_D to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D6fooNV1Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D1DEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D2D1Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D2DbEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D2DdEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZN8test13_D2D2Ev to i8*), i8* null, i8* inttoptr (i64 -8 to i8*), i8* null, i8* inttoptr (i64 -8 to i8*), i8* null, i8* null, i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI8test13_D to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test13_B23B2aEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test13_B22B2Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZTv0_n48_N8test13_D1DEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test13_B22DaEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZTv0_n64_N8test13_D2DdEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZN9test13_B23B2bEv to i8*), i8* inttoptr (i64 -16 to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* inttoptr (i64 -16 to i8*), i8* inttoptr (i64 -24 to i8*), i8* null, i8* inttoptr (i64 -24 to i8*), i8* bitcast (%1* @_ZTI8test13_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN8test13_B2B1Ev to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZTv0_n32_N8test13_D1DEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZTv0_n40_N9test13_B22DaEv to i8*), i8* bitcast (void (%struct.test10_B2*)* @_ZTv0_n48_N8test13_D2DbEv to i8*), i8* bitcast (void (%struct.B*)* @_ZN8test13_B2DcEv to i8*), i8* bitcast (void (%struct.test13_B2*)* @_ZTv0_n64_N9test13_B22B2Ev to i8*)] - - -class test14 { -public: - virtual void initWithInt(int a); - static test14 *withInt(int a); -}; - -void test14::initWithInt(int a) { } - -test14 *test14::withInt(int a) { - test14 *me = new test14; - me->initWithInt(a); - return me; -} - - -struct test15_B { - virtual test15_B *foo1() { return 0; } - virtual test15_B *foo2() { return 0; } - virtual test15_B *foo3() { return 0; } - int i; -}; - -struct test15_NV1 { - virtual void fooNV1() { } - int i; -}; - -struct test15_B2 : test15_NV1, virtual test15_B { - virtual test15_B2 *foo1() { return 0; } - virtual test15_B2 *foo2() { return 0; } - int i; -}; - -struct test15_D : test15_NV1, virtual test15_B2 { - virtual test15_D *foo1() { return 0; } -}; - -// CHECK-LPLL64:@_ZTV8test15_D = weak_odr constant [23 x i8*] [i8* inttoptr (i64 32 to i8*), i8* inttoptr (i64 16 to i8*), i8* null, i8* bitcast (%1* @_ZTI8test15_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test15_NV16fooNV1Ev to i8*), i8* bitcast (%struct.test15_D* (%struct.test15_D*)* @_ZN8test15_D4foo1Ev to i8*), i8* null, i8* inttoptr (i64 -16 to i8*), i8* null, i8* inttoptr (i64 16 to i8*), i8* inttoptr (i64 -16 to i8*), i8* bitcast (%1* @_ZTI8test15_D to i8*), i8* bitcast (void (%struct.B*)* @_ZN10test15_NV16fooNV1Ev to i8*), i8* bitcast (%struct.test15_D* (%struct.test15_D*)* @_ZTcv0_n40_v0_n24_N8test15_D4foo1Ev to i8*), i8* bitcast (%struct.test15_B2* (%struct.test15_B2*)* @_ZN9test15_B24foo2Ev to i8*), i8* null, i8* inttoptr (i64 -16 to i8*), i8* inttoptr (i64 -32 to i8*), i8* inttoptr (i64 -32 to i8*), i8* bitcast (%1* @_ZTI8test15_D to i8*), i8* bitcast (%struct.test15_D* (%struct.test15_D*)* @_ZTcv0_n24_v0_n32_N8test15_D4foo1Ev to i8*), i8* bitcast (%struct.test15_B2* (%struct.test15_B2*)* @_ZTcv0_n32_v0_n24_N9test15_B24foo2Ev to i8*), i8* bitcast (%struct.B* (%struct.B*)* @_ZN8test15_B4foo3Ev to i8*)] - - -struct test16_NV1 { - virtual void fooNV1() { } -virtual void foo_NV1() { } - int i; -}; - -struct test16_NV2 { - virtual test16_NV2* foo1() { return 0; } -virtual void foo_NV2() { } -virtual void foo_NV2b() { } - int i; -}; - -struct test16_B : public test16_NV1, test16_NV2 { - virtual test16_B *foo1() { return 0; } - virtual test16_B *foo2() { return 0; } - virtual test16_B *foo3() { return 0; } -virtual void foo_B() { } - int i; -}; - -struct test16_B2 : test16_NV1, virtual test16_B { - virtual test16_B2 *foo1() { return 0; } - virtual test16_B2 *foo2() { return 0; } -virtual void foo_B2() { } - int i; -}; - -struct test16_D : test16_NV1, virtual test16_B2 { - virtual void bar() { } - virtual test16_D *foo1() { return 0; } -}; - -// FIXME: -// CHECK-LP64: __ZTV8test16_D: -// CHECK-LP64-NEXT: .quad 32 -// CHECK-LP64-NEXT: .quad 16 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad __ZTI8test16_D -// CHECK-LP64-NEXT: .quad __ZN10test16_NV16fooNV1Ev -// CHECK-LP64-NEXT: .quad __ZN10test16_NV17foo_NV1Ev -// CHECK-LP64-NEXT: .quad __ZN8test16_D3barEv -// CHECK-LP64-NEXT: .quad __ZN8test16_D4foo1Ev -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad -16 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad 16 -// CHECK-LP64-NEXT: .quad -16 -// CHECK-LP64-NEXT: .quad __ZTI8test16_D -// CHECK-LP64-NEXT: .quad __ZN10test16_NV16fooNV1Ev -// CHECK-LP64-NEXT: .quad __ZN10test16_NV17foo_NV1Ev -// CHECK-LP64-NEXT: .quad __ZTcv0_n48_v0_n24_N8test16_D4foo1Ev -// CHECK-LP64-NEXT: .quad __ZN9test16_B24foo2Ev -// CHECK-LP64-NEXT: .quad __ZN9test16_B26foo_B2Ev -// CHECK-LP64-NEXT: .quad 16 -// CHECK-LP64-NEXT: .quad 16 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad -16 -// CHECK-LP64-NEXT: .quad -32 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad -32 -// CHECK-LP64-NEXT: .quad __ZTI8test16_D -// CHECK-LP64-NEXT: .quad __ZN10test16_NV16fooNV1Ev -// CHECK-LP64-NEXT: .quad __ZN10test16_NV17foo_NV1Ev -// CHECK-LP64-NEXT: .quad __ZTcv0_n40_v0_n32_N8test16_D4foo1Ev -// CHECK-LP64-NEXT: .quad __ZTcv0_n48_v0_n24_N9test16_B24foo2Ev -// CHECK-LP64-NEXT: .quad __ZN8test16_B4foo3Ev -// CHECK-LP64-NEXT: .quad __ZN8test16_B5foo_BEv -// CHECK-LP64-NEXT: .quad -48 -// CHECK-LP64-NEXT: .quad __ZTI8test16_D -// CHECK-LP64-NEXT: .quad __ZTcvn16_n40_v16_n32_N8test16_D4foo1Ev -// CHECK-LP64-NEXT: .quad __ZN10test16_NV27foo_NV2Ev -// CHECK-LP64-NEXT: .quad __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() { } -}; - - -// CHECK-LPLL64:@_ZTV8test17_D = weak_odr constant [4 x i8*] [i8* null, i8* bitcast (%4* @_ZTI8test17_D to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test17_B23fooEv to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN8test17_D3barEv to i8*)] - -// CHECK-LPLL64:@_ZTV9test17_B2 = weak_odr constant [4 x i8*] [i8* null, i8* bitcast (%4* @_ZTI9test17_B2 to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test17_B23fooEv to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*)] - -// CHECK-LPLL64:@_ZTV9test17_B1 = weak_odr constant [4 x i8*] [i8* null, i8* bitcast (%0* @_ZTI9test17_B1 to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test17_B13barEv to i8*)] - - -struct test18_NV1 { - virtual void fooNV1() { } -virtual void foo_NV1() { } - int i; -}; - -struct test18_NV2 { - virtual test18_NV2& foo1() { return *this; } -virtual void foo_NV2() { } -virtual void foo_NV2b() { } - int i; -}; - -struct test18_B : public test18_NV1, test18_NV2 { - virtual test18_B& foo1() { return *this; } - virtual test18_B *foo2() { return 0; } - virtual test18_B *foo3() { return 0; } -virtual void foo_B() { } - int i; -}; - -struct test18_B2 : test18_NV1, virtual test18_B { - virtual test18_B2& foo1() { return *this; } - virtual test18_B2 *foo2() { return 0; } -virtual void foo_B2() { } - int i; -}; - -struct test18_D : test18_NV1, virtual test18_B2 { - virtual test18_D& foo1() { return *this; } -}; - - -struct test19_VB1 { }; -struct test19_B1 : public virtual test19_VB1 { - virtual void fB1() { } - virtual void foB1B2() { } - virtual void foB1B3() { } - virtual void foB1B4() { } -}; - -struct test19_VB2 { }; -struct test19_B2: public test19_B1, public virtual test19_VB2 { - virtual void foB1B2() { } - virtual void foB1B3() { } - virtual void foB1B4() { } - - virtual void fB2() { } - virtual void foB2B3() { } - virtual void foB2B4() { } -}; - -struct test19_VB3 { }; -struct test19_B3: virtual public test19_B2, public virtual test19_VB3 { - virtual void foB1B3() { } - virtual void foB1B4() { } - - virtual void foB2B3() { } - virtual void foB2B4() { } - - virtual void fB3() { } - virtual void foB3B4() { } -}; - -struct test19_VB4 { }; -struct test19_B4: public test19_B3, public virtual test19_VB4 { - virtual void foB1B4() { } - - virtual void foB2B4() { } - - virtual void foB3B4() { } - - virtual void fB4() { } -}; - -struct test19_D : virtual test19_B4 { -}; - - -// CHECK-LPLL64:@_ZTV8test19_D = weak_odr constant [28 x i8*] [i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI8test19_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test19_B13fB1Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B26foB1B2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B36foB1B3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B46foB1B4Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B23fB2Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B36foB2B3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B46foB2B4Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B33fB3Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B46foB3B4Ev to i8*), i8* bitcast (void (%class.test17_B2*)* @_ZN9test19_B43fB4Ev to i8*)] - -// FIXME: -// CHECK-LP64: __ZTT8test19_D: -// CHECK-LP64-NEXT: .quad __ZTV8test19_D+144 -// CHECK-LP64-NEXT: .quad __ZTV8test19_D+144 -// CHECK-LP64-NEXT .quad __ZTV8test19_D+144 -// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B4+136 -// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B3+104 -// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B3+104 -// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B4+136 -// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B2+88 -// CHECK-LP64-NEXT .quad __ZTC8test19_D0_9test19_B1+24 - -class test20_V { - virtual void foo1(); -}; -class test20_V1 { - virtual void foo2(); -}; -class test20_B : virtual test20_V { -} b; -class test20_B1 : virtual test20_V1 { -}; -class test20_D : public test20_B, public test20_B1 { -}; - -// CHECK-LPLL64:@_ZTV8test20_D = weak_odr constant [11 x i8*] [i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* null, i8* bitcast (%1* @_ZTI8test20_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test20_V4foo1Ev to i8*), i8* null, i8* null, i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI8test20_D to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test20_V14foo2Ev to i8*)] - -// CHECK-LPLL64:@_ZTC8test20_D0_8test20_B = internal constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI8test20_B to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test20_V4foo1Ev to i8*)] - -// CHECK-LPLL64:@_ZTC8test20_D8_9test20_B1 = internal constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI9test20_B1 to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test20_V14foo2Ev to i8*)] ; <[5 x i8*]*> [#uses=1] - -// FIXME: -// CHECK-LP64: __ZTT8test20_D: -// CHECK-LP64-NEXT: .quad __ZTV8test20_D+40 -// CHECK-LP64-NEXT: .quad __ZTC8test20_D0_8test20_B+32 -// CHECK-LP64-NEXT: .quad __ZTC8test20_D0_8test20_B+32 -// CHECK-LP64-NEXT: .quad __ZTC8test20_D8_9test20_B1+32 -// CHECK-LP64-NEXT: .quad __ZTC8test20_D8_9test20_B1+32 -// CHECK-LP64-NEXT .quad __ZTV8test20_D+40 -// CHECK-LP64-NEXT .quad __ZTV8test20_D+80 -// CHECK-LP64-NEXT .quad __ZTV8test20_D+80 - - -class test21_V { - virtual void foo() { } -}; -class test21_V1 { - virtual void foo() { } -}; -class test21_B : virtual test21_V { -}; -class test21_B1 : virtual test21_V1 { -}; -class test21_D : public test21_B, public test21_B1 { - void foo() { } -}; - -// CHECK-LPLL64:@_ZTV8test21_D = weak_odr constant [11 x i8*] [i8* inttoptr (i64 8 to i8*), i8* null, i8* null, i8* null, i8* bitcast (%1* @_ZTI8test21_D to i8*), i8* bitcast (void (%class.test20_D*)* @_ZN8test21_D3fooEv to i8*), i8* null, i8* inttoptr (i64 -8 to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%1* @_ZTI8test21_D to i8*), i8* bitcast (void (%class.test20_D*)* @_ZTv0_n24_N8test21_D3fooEv to i8*)] - -// CHECK-LPLL64:@_ZTC8test21_D0_8test21_B = internal constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI8test21_B to i8*), i8* bitcast (void (%class.test14*)* @_ZN8test21_V3fooEv to i8*)] - -// CHECK-LPLL64:@_ZTC8test21_D8_9test21_B1 = internal constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (%3* @_ZTI9test21_B1 to i8*), i8* bitcast (void (%class.test14*)* @_ZN9test21_V13fooEv to i8*)] ; <[5 x i8*]*> [#uses=1] - -// FIXME: -// CHECK-LP64: __ZTT8test21_D: -// CHECK-LP64-NEXT: .quad __ZTV8test21_D+40 -// CHECK-LP64-NEXT: .quad __ZTC8test21_D0_8test21_B+32 -// CHECK-LP64-NEXT: .quad __ZTC8test21_D0_8test21_B+32 -// CHECK-LP64-NEXT: .quad __ZTC8test21_D8_9test21_B1+32 -// CHECK-LP64-NEXT: .quad __ZTC8test21_D8_9test21_B1+32 -// CHECK-LP64-NEXT .quad __ZTV8test21_D+40 -// CHECK-LP64-NEXT .quad __ZTV8test21_D+80 -// CHECK-LP64-NEXT .quad __ZTV8test21_D+80 - - -struct test22_s1 { virtual void dtor() { } }; -struct test22_s2 { virtual void dtor() { } }; -struct test22_s3 : test22_s1, test22_s2 { virtual void dtor() { } }; -struct test22_D : test22_s3 { virtual void dtor() { } }; - -// CHECK-LPLL64:@_ZTV8test22_D = weak_odr constant [6 x i8*] [i8* null, i8* bitcast (%4* @_ZTI8test22_D to i8*), i8* bitcast (void (%class.test20_D*)* @_ZN8test22_D4dtorEv to i8*), i8* inttoptr (i64 -8 to i8*), i8* bitcast (%4* @_ZTI8test22_D to i8*), i8* bitcast (void (%class.test20_D*)* @_ZThn8_N8test22_D4dtorEv to i8*)] - - -class test23_s1 { - virtual void fun1(char *t) { } -}; -class test23_s2 { - virtual void fun2(char *t) { } -}; -class test23_s3 { - virtual void fun3(char *t) { } -}; -class test23_s4: virtual test23_s1, test23_s2, test23_s3 { - virtual void fun4(char *t) { } -}; -class test23_D: virtual test23_s4 { - virtual void fun5(char *t) { } -}; - - -// FIXME: -// CHECK-LP64: __ZTV8test23_D: -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad 8 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64-NEXT: .quad __ZTI8test23_D -// CHECK-LP64-NEXT: .quad __ZN9test23_s14fun1EPc -// CHECK-LP64-NEXT: .quad __ZN8test23_D4fun5EPc -// CHECK-LP64-NEXT .quad 8 -// CHECK-LP64: .quad 0 -// CHECK-LP64-NEXT: .quad 0 -// CHECK-LP64: .quad -8 -// CHECK-LP64-NEXT: .quad -8 -// CHECK-LP64-NEXT: .quad __ZTI8test23_D -// CHECK-LP64-NEXT: .quad __ZN9test23_s24fun2EPc -// CHECK-LP64-NEXT: .quad __ZN9test23_s44fun4EPc -// CHECK-LP64-NEXT: .quad -16 -// CHECK-LP64-NEXT: .quad __ZTI8test23_D -// CHECK-LP64-NEXT: .quad __ZN9test23_s34fun3EPc - - -test23_D d23; -test22_D d22; -test21_D d21; -test20_D d20; -test19_D d19; -test18_D d18; -test17_D d17; -test16_D d16; -test15_D d15; -test13_D d13; -test11_D d11; -test10_D d10; -test9_D d9; -test8_D d8; - -test5_D d5; -test4_D d4; -test3_D d3; - -test6_D d6; -test7_D d7; - - -int j; -void *vp; -void test2() { - F f; - static int sz = (char *)(&f.f) - (char *)(&f); - vp = &sz; - j = sz; - // FIXME: These should result in a frontend constant a la fold, no run time - // initializer - // CHECK-LPLL64: define void @_Z5test2v() - // CHECK-LPLL64: = getelementptr inbounds %class.F* %f, i32 0, i32 1 -} - -static_assert(sizeof(F) == sizeof(void*)*4, "invalid vbase size"); - - -void test12_foo() { - test12_pa->foo0(); - test12_pb->foo0(); - test12_pd->foo0(); - test12_pa->foo(); - test12_pb->foo(); - test12_pd->foo(); - test12_pa->test12_A::foo(); -} - - -// CHECK-LPLL64:define void @_Z10test12_foov() nounwind { -// CHECK-LPLL64: call void % -// CHECK-LPLL64: call void % -// CHECK-LPLL64: call void % -// CHECK-LPLL64: call void % -// CHECK-LPLL64: call void % -// CHECK-LPLL64: call void % -// CHECK-LPLL64: call void @_ZN8test12_A3fooEv(%class.test14* %{{.*}}) - diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp index 3a0dae41c3b06..f2f5179d4a19f 100644 --- a/test/CodeGenCXX/vtable-layout.cpp +++ b/test/CodeGenCXX/vtable-layout.cpp @@ -1303,3 +1303,337 @@ struct B : virtual A { V2 *B::f() { return 0; } } + +namespace Test30 { + +// Test that we don't assert when generating a vtable for F. +struct A { }; + +struct B : virtual A { + int i; +}; + +struct C { + virtual void f(); +}; + +struct D : virtual C, B { }; +struct E : virtual D { }; + +struct F : E { + virtual void f(); +}; +void F::f() { } + +} + +namespace Test31 { + +// Test that we don't add D::f twice to the primary vtable. +struct A { + int a; +}; + +struct B { + virtual void f(); +}; + +struct C : A, virtual B { + virtual void f(); +}; + +// CHECK: Vtable for 'Test31::D' (11 entries). +// CHECK-NEXT: 0 | vbase_offset (0) +// CHECK-NEXT: 1 | vbase_offset (8) +// CHECK-NEXT: 2 | vcall_offset (0) +// CHECK-NEXT: 3 | offset_to_top (0) +// CHECK-NEXT: 4 | Test31::D RTTI +// CHECK-NEXT: -- (Test31::B, 0) vtable address -- +// CHECK-NEXT: -- (Test31::D, 0) vtable address -- +// CHECK-NEXT: 5 | void Test31::D::f() +// CHECK-NEXT: 6 | vbase_offset (-8) +// CHECK-NEXT: 7 | vcall_offset (-8) +// CHECK-NEXT: 8 | offset_to_top (-8) +// CHECK-NEXT: 9 | Test31::D RTTI +// CHECK-NEXT: -- (Test31::C, 8) vtable address -- +// CHECK-NEXT: 10 | void Test31::D::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +struct D : virtual C { + virtual void f(); +}; +void D::f() { } + +} + +namespace Test32 { + +// Check that we correctly lay out the virtual bases of 'Test32::D'. + +struct A { + virtual void f(); +}; + +struct B : virtual A { }; +struct C : A, virtual B { }; +struct D : virtual B { }; + +// CHECK: Virtual base offset offsets for 'Test32::E' (3 entries). +// CHECK-NEXT: Test32::A | -32 +// CHECK-NEXT: Test32::B | -24 +// CHECK-NEXT: Test32::D | -40 +struct E : C, virtual D { + virtual void f(); +}; +void E::f() { } + +} + +namespace Test33 { + +// Test that we don't emit too many vcall offsets in 'Test32::F'. + +struct A { + virtual void a(); +}; + +struct B { + virtual void b(); +}; + +struct C : virtual A, virtual B { + virtual void c(); +}; + +struct D : virtual C { }; + +struct E : A, D { + virtual void e(); +}; + +// CHECK: Vtable for 'Test33::F' (30 entries). +// CHECK-NEXT: 0 | vbase_offset (24) +// CHECK-NEXT: 1 | vbase_offset (16) +// CHECK-NEXT: 2 | vbase_offset (16) +// CHECK-NEXT: 3 | vbase_offset (8) +// CHECK-NEXT: 4 | offset_to_top (0) +// CHECK-NEXT: 5 | Test33::F RTTI +// CHECK-NEXT: -- (Test33::A, 0) vtable address -- +// CHECK-NEXT: -- (Test33::F, 0) vtable address -- +// CHECK-NEXT: 6 | void Test33::A::a() +// CHECK-NEXT: 7 | void Test33::F::f() +// CHECK-NEXT: 8 | vcall_offset (0) +// CHECK-NEXT: 9 | vcall_offset (0) +// CHECK-NEXT: 10 | vbase_offset (16) +// CHECK-NEXT: 11 | vbase_offset (8) +// CHECK-NEXT: 12 | vbase_offset (8) +// CHECK-NEXT: 13 | offset_to_top (-8) +// CHECK-NEXT: 14 | Test33::F RTTI +// CHECK-NEXT: -- (Test33::A, 8) vtable address -- +// CHECK-NEXT: -- (Test33::E, 8) vtable address -- +// CHECK-NEXT: 15 | void Test33::A::a() +// CHECK-NEXT: 16 | void Test33::E::e() +// CHECK-NEXT: 17 | vbase_offset (0) +// CHECK-NEXT: 18 | vcall_offset (0) +// CHECK-NEXT: 19 | vbase_offset (8) +// CHECK-NEXT: 20 | vbase_offset (0) +// CHECK-NEXT: 21 | vcall_offset (0) +// CHECK-NEXT: 22 | offset_to_top (-16) +// CHECK-NEXT: 23 | Test33::F RTTI +// CHECK-NEXT: -- (Test33::A, 16) vtable address -- +// CHECK-NEXT: -- (Test33::C, 16) vtable address -- +// CHECK-NEXT: -- (Test33::D, 16) vtable address -- +// CHECK-NEXT: 24 | void Test33::A::a() +// CHECK-NEXT: 25 | void Test33::C::c() +// CHECK-NEXT: 26 | vcall_offset (0) +// CHECK-NEXT: 27 | offset_to_top (-24) +// CHECK-NEXT: 28 | Test33::F RTTI +// CHECK-NEXT: -- (Test33::B, 24) vtable address -- +// CHECK-NEXT: 29 | void Test33::B::b() +struct F : virtual E, A { + virtual void f(); +}; +void F::f() { } + +} + +namespace Test34 { + +// Test that we lay out the construction vtable for 'Test34::E' in 'Test34::F' correctly. + +struct A { + virtual void a(); +}; +struct B : virtual A { }; + +struct C : B, A { + virtual void c(); +}; + +struct D : A, C { }; + +struct E : virtual D { + virtual void e(); +}; + +// CHECK: Construction vtable for ('Test34::E', 0) in 'Test34::F' (22 entries). +// CHECK-NEXT: 0 | vbase_offset (0) +// CHECK-NEXT: 1 | vbase_offset (8) +// CHECK-NEXT: 2 | vcall_offset (0) +// CHECK-NEXT: 3 | offset_to_top (0) +// CHECK-NEXT: 4 | Test34::E RTTI +// CHECK-NEXT: -- (Test34::A, 0) vtable address -- +// CHECK-NEXT: -- (Test34::E, 0) vtable address -- +// CHECK-NEXT: 5 | void Test34::A::a() +// CHECK-NEXT: 6 | void Test34::E::e() +// CHECK-NEXT: 7 | vcall_offset (8) +// CHECK-NEXT: 8 | vcall_offset (0) +// CHECK-NEXT: 9 | vbase_offset (-8) +// CHECK-NEXT: 10 | offset_to_top (-8) +// CHECK-NEXT: 11 | Test34::E RTTI +// CHECK-NEXT: -- (Test34::A, 8) vtable address -- +// CHECK-NEXT: -- (Test34::D, 8) vtable address -- +// CHECK-NEXT: 12 | void Test34::A::a() +// CHECK-NEXT: 13 | vbase_offset (-16) +// CHECK-NEXT: 14 | vcall_offset (-16) +// CHECK-NEXT: 15 | offset_to_top (-16) +// CHECK-NEXT: 16 | Test34::E RTTI +// CHECK-NEXT: -- (Test34::B, 16) vtable address -- +// CHECK-NEXT: -- (Test34::C, 16) vtable address -- +// CHECK-NEXT: 17 | [unused] void Test34::A::a() +// CHECK-NEXT: 18 | void Test34::C::c() +// CHECK-NEXT: 19 | offset_to_top (-24) +// CHECK-NEXT: 20 | Test34::E RTTI +// CHECK-NEXT: -- (Test34::A, 24) vtable address -- +// CHECK-NEXT: 21 | void Test34::A::a() +struct F : E { + virtual void f(); +}; +void F::f() { } + +} + +namespace Test35 { + +// Test that we lay out the virtual bases of 'Test35::H' in the correct order. + +struct A { + virtual void a(); + + int i; +}; + +struct B : virtual A { + virtual void b(); +}; + +struct C { + virtual void c(); +}; + +struct D : C, virtual B { + virtual void d(); +}; + +struct E : D { + virtual void e(); + + bool b; +}; + +struct F : virtual D { }; +struct G : virtual E { }; + +// CHECK: Vtable for 'Test35::H' (32 entries). +// CHECK-NEXT: 0 | vbase_offset (32) +// CHECK-NEXT: 1 | vbase_offset (0) +// CHECK-NEXT: 2 | vcall_offset (0) +// CHECK-NEXT: 3 | vcall_offset (0) +// CHECK-NEXT: 4 | vbase_offset (16) +// CHECK-NEXT: 5 | vbase_offset (8) +// CHECK-NEXT: 6 | offset_to_top (0) +// CHECK-NEXT: 7 | Test35::H RTTI +// CHECK-NEXT: -- (Test35::C, 0) vtable address -- +// CHECK-NEXT: -- (Test35::D, 0) vtable address -- +// CHECK-NEXT: -- (Test35::F, 0) vtable address -- +// CHECK-NEXT: -- (Test35::H, 0) vtable address -- +// CHECK-NEXT: 8 | void Test35::C::c() +// CHECK-NEXT: 9 | void Test35::D::d() +// CHECK-NEXT: 10 | void Test35::H::h() +// CHECK-NEXT: 11 | vbase_offset (0) +// CHECK-NEXT: 12 | vbase_offset (24) +// CHECK-NEXT: 13 | vcall_offset (0) +// CHECK-NEXT: 14 | vbase_offset (8) +// CHECK-NEXT: 15 | offset_to_top (-8) +// CHECK-NEXT: 16 | Test35::H RTTI +// CHECK-NEXT: -- (Test35::B, 8) vtable address -- +// CHECK-NEXT: -- (Test35::G, 8) vtable address -- +// CHECK-NEXT: 17 | void Test35::B::b() +// CHECK-NEXT: 18 | vcall_offset (0) +// CHECK-NEXT: 19 | offset_to_top (-16) +// CHECK-NEXT: 20 | Test35::H RTTI +// CHECK-NEXT: -- (Test35::A, 16) vtable address -- +// CHECK-NEXT: 21 | void Test35::A::a() +// CHECK-NEXT: 22 | vcall_offset (0) +// CHECK-NEXT: 23 | vcall_offset (0) +// CHECK-NEXT: 24 | vcall_offset (0) +// CHECK-NEXT: 25 | vbase_offset (-16) +// CHECK-NEXT: 26 | vbase_offset (-24) +// CHECK-NEXT: 27 | offset_to_top (-32) +// CHECK-NEXT: 28 | Test35::H RTTI +// CHECK-NEXT: -- (Test35::C, 32) vtable address -- +// CHECK-NEXT: -- (Test35::D, 32) vtable address -- +// CHECK-NEXT: -- (Test35::E, 32) vtable address -- +// CHECK-NEXT: 29 | void Test35::C::c() +// CHECK-NEXT: 30 | void Test35::D::d() +// CHECK-NEXT: 31 | void Test35::E::e() + +// CHECK: Virtual base offset offsets for 'Test35::H' (4 entries). +// CHECK-NEXT: Test35::A | -32 +// CHECK-NEXT: Test35::B | -24 +// CHECK-NEXT: Test35::D | -56 +// CHECK-NEXT: Test35::E | -64 +struct H : F, G { + virtual void h(); +}; +void H::h() { } + +} + +namespace Test36 { + +// Test that we don't mark B::f as unused in the vtable for D. + +struct A { + virtual void f(); +}; + +struct B : virtual A { }; + +struct C : virtual A { + virtual void f(); +}; + +// CHECK: Vtable for 'Test36::D' (12 entries). +// CHECK-NEXT: 0 | vbase_offset (8) +// CHECK-NEXT: 1 | vbase_offset (8) +// CHECK-NEXT: 2 | vcall_offset (0) +// CHECK-NEXT: 3 | offset_to_top (0) +// CHECK-NEXT: 4 | Test36::D RTTI +// CHECK-NEXT: -- (Test36::C, 0) vtable address -- +// CHECK-NEXT: -- (Test36::D, 0) vtable address -- +// CHECK-NEXT: 5 | void Test36::C::f() +// CHECK-NEXT: 6 | void Test36::D::g() +// CHECK-NEXT: 7 | vbase_offset (0) +// CHECK-NEXT: 8 | vcall_offset (-8) +// CHECK-NEXT: 9 | offset_to_top (-8) +// CHECK-NEXT: 10 | Test36::D RTTI +// CHECK-NEXT: -- (Test36::A, 8) vtable address -- +// CHECK-NEXT: -- (Test36::B, 8) vtable address -- +// CHECK-NEXT: 11 | void Test36::C::f() +// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +struct D : virtual B, C { + virtual void g(); +}; +void D::g() { } + +} diff --git a/test/CodeGenCXX/x86_32-arguments.cpp b/test/CodeGenCXX/x86_32-arguments.cpp index d13c0e4888fd2..f8d655145b8f0 100644 --- a/test/CodeGenCXX/x86_32-arguments.cpp +++ b/test/CodeGenCXX/x86_32-arguments.cpp @@ -6,7 +6,7 @@ struct S { int s; }; -// CHECK: define void @_Z1fv(%struct.S* noalias sret % +// CHECK: define void @_Z1fv(%struct.S* sret % S f() { return S(); } // CHECK: define void @_Z1f1S(%struct.S*) void f(S) { } @@ -17,7 +17,7 @@ class C { double c; }; -// CHECK: define void @_Z1gv(%class.C* noalias sret % +// CHECK: define void @_Z1gv(%class.C* sret % C g() { return C(); } // CHECK: define void @_Z1f1C(%class.C*) |
