blob: b9054410a90d1e996372e7a37eb9c8ae7c6bfdba [file] [log] [blame]
Anders Carlsson824d7ea2010-02-11 08:02:13 +00001// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
2namespace Test1 {
3
4// CHECK: Vtable for 'Test1::A' (3 entries).
5// CHECK-NEXT: 0 | offset_to_top (0)
6// CHECK-NEXT: 1 | Test1::A RTTI
Anders Carlsson822307b2010-02-11 17:18:51 +00007// CHECK-NEXT: -- (Test1::A, 0) vtable address --
Anders Carlsson848fa642010-02-11 18:20:28 +00008// CHECK-NEXT: 2 | void Test1::A::f()
Anders Carlsson824d7ea2010-02-11 08:02:13 +00009struct A {
10 virtual void f();
11};
Anders Carlsson824d7ea2010-02-11 08:02:13 +000012void A::f() { }
Anders Carlsson57071e22010-02-12 05:25:12 +000013
Anders Carlsson824d7ea2010-02-11 08:02:13 +000014}
15
Anders Carlsson848fa642010-02-11 18:20:28 +000016namespace Test2 {
17
18// This is a smoke test of the vtable dumper.
Anders Carlssonbac72712010-02-11 18:21:49 +000019// CHECK: Vtable for 'Test2::A' (9 entries).
Anders Carlsson848fa642010-02-11 18:20:28 +000020// CHECK-NEXT: 0 | offset_to_top (0)
21// CHECK-NEXT: 1 | Test2::A RTTI
22// CHECK-NEXT: -- (Test2::A, 0) vtable address --
23// CHECK-NEXT: 2 | void Test2::A::f()
24// CHECK-NEXT: 3 | void Test2::A::f() const
25// CHECK-NEXT: 4 | Test2::A *Test2::A::g(int)
26// CHECK-NEXT: 5 | Test2::A::~A() [complete]
27// CHECK-NEXT: 6 | Test2::A::~A() [deleting]
28// CHECK-NEXT: 7 | void Test2::A::h()
Anders Carlssonbac72712010-02-11 18:21:49 +000029// CHECK-NEXT: 8 | Test2::A &Test2::A::operator=(Test2::A const &)
Anders Carlsson848fa642010-02-11 18:20:28 +000030struct A {
31 virtual void f();
32 virtual void f() const;
33
34 virtual A* g(int a);
35 virtual ~A();
36 virtual void h();
Anders Carlssonbac72712010-02-11 18:21:49 +000037 virtual A& operator=(const A&);
Anders Carlsson848fa642010-02-11 18:20:28 +000038};
Anders Carlsson848fa642010-02-11 18:20:28 +000039void A::f() { }
40
Anders Carlsson98241422010-02-12 02:38:13 +000041// Another simple vtable dumper test.
Anders Carlsson57071e22010-02-12 05:25:12 +000042
Anders Carlsson98241422010-02-12 02:38:13 +000043// CHECK: Vtable for 'Test2::B' (6 entries).
44// CHECK-NEXT: 0 | offset_to_top (0)
45// CHECK-NEXT: 1 | Test2::B RTTI
46// CHECK-NEXT: -- (Test2::B, 0) vtable address --
47// CHECK-NEXT: 2 | void Test2::B::f()
48// CHECK-NEXT: 3 | void Test2::B::g() [pure]
49// CHECK-NEXT: 4 | Test2::B::~B() [complete] [pure]
50// CHECK-NEXT: 5 | Test2::B::~B() [deleting] [pure]
Anders Carlsson98241422010-02-12 02:38:13 +000051struct B {
52 virtual void f();
53 virtual void g() = 0;
54 virtual ~B() = 0;
55};
Anders Carlsson98241422010-02-12 02:38:13 +000056void B::f() { }
57
Anders Carlsson848fa642010-02-11 18:20:28 +000058}
Anders Carlsson57071e22010-02-12 05:25:12 +000059
60namespace Test3 {
61
62// If a function in a derived class overrides a function in a primary base,
63// then the function should not have an entry in the derived class (unless the return
64// value requires adjusting).
65
66// CHECK: Vtable for 'Test3::A' (3 entries).
67// CHECK-NEXT: 0 | offset_to_top (0)
68// CHECK-NEXT: 1 | Test3::A RTTI
69// CHECK-NEXT: -- (Test3::A, 0) vtable address --
70// CHECK-NEXT: 2 | void Test3::A::f()
71struct A {
72 virtual void f();
73};
74void A::f() { }
75
76// CHECK: Vtable for 'Test3::B' (4 entries).
77// CHECK-NEXT: 0 | offset_to_top (0)
78// CHECK-NEXT: 1 | Test3::B RTTI
Anders Carlsson28cbc8b2010-02-12 07:43:48 +000079// CHECK-NEXT: -- (Test3::A, 0) vtable address --
Anders Carlsson57071e22010-02-12 05:25:12 +000080// CHECK-NEXT: -- (Test3::B, 0) vtable address --
81// CHECK-NEXT: 2 | void Test3::A::f()
82// CHECK-NEXT: 3 | void Test3::B::g()
83struct B : A {
84 virtual void f();
85 virtual void g();
86};
87void B::f() { }
88
89// CHECK: Vtable for 'Test3::C' (5 entries).
90// CHECK-NEXT: 0 | offset_to_top (0)
91// CHECK-NEXT: 1 | Test3::C RTTI
Anders Carlsson28cbc8b2010-02-12 07:43:48 +000092// CHECK-NEXT: -- (Test3::A, 0) vtable address --
Anders Carlsson57071e22010-02-12 05:25:12 +000093// CHECK-NEXT: -- (Test3::C, 0) vtable address --
94// CHECK-NEXT: 2 | void Test3::A::f()
95// CHECK-NEXT: 3 | void Test3::C::g()
96// CHECK-NEXT: 4 | void Test3::C::h()
97struct C : A {
98 virtual void g();
99 virtual void h();
100};
101void C::g() { }
102
103// CHECK: Vtable for 'Test3::D' (5 entries).
104// CHECK-NEXT: 0 | offset_to_top (0)
105// CHECK-NEXT: 1 | Test3::D RTTI
Anders Carlsson28cbc8b2010-02-12 07:43:48 +0000106// CHECK-NEXT: -- (Test3::A, 0) vtable address --
107// CHECK-NEXT: -- (Test3::B, 0) vtable address --
Anders Carlsson57071e22010-02-12 05:25:12 +0000108// CHECK-NEXT: -- (Test3::D, 0) vtable address --
109// CHECK-NEXT: 2 | void Test3::A::f()
110// CHECK-NEXT: 3 | void Test3::B::g()
111// CHECK-NEXT: 4 | void Test3::D::h()
112struct D : B {
113 virtual void f();
114 virtual void g();
115 virtual void h();
116};
117
118void D::f() { }
119}
John McCall96058952010-02-12 06:15:07 +0000120
121// For now, just verify this doesn't crash.
122namespace test0 {
123 struct Obj {};
124
125 struct Base { virtual const Obj *foo() = 0; };
126 struct Derived : Base { virtual Obj *foo() { return new Obj(); } };
127
128 void test(Derived *D) { D->foo(); }
129}