1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 %s -fsyntax-only -verify -triple %itanium_abi_triple -Wweak-vtables -Wweak-template-vtables
2*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 %s -fsyntax-only -triple %ms_abi_triple -Werror -Wno-weak-vtables -Wno-weak-template-vtables
3f4a2713aSLionel Sambuc
4f4a2713aSLionel Sambuc struct A { // expected-warning {{'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
fA5f4a2713aSLionel Sambuc virtual void f() { }
6f4a2713aSLionel Sambuc };
7f4a2713aSLionel Sambuc
8f4a2713aSLionel Sambuc template<typename T> struct B {
fB9f4a2713aSLionel Sambuc virtual void f() { }
10f4a2713aSLionel Sambuc };
11f4a2713aSLionel Sambuc
12f4a2713aSLionel Sambuc namespace {
13f4a2713aSLionel Sambuc struct C {
f__anon5f5cdb890111::C14f4a2713aSLionel Sambuc virtual void f() { }
15f4a2713aSLionel Sambuc };
16f4a2713aSLionel Sambuc }
17f4a2713aSLionel Sambuc
f()18f4a2713aSLionel Sambuc void f() {
19f4a2713aSLionel Sambuc struct A {
20f4a2713aSLionel Sambuc virtual void f() { }
21f4a2713aSLionel Sambuc };
22f4a2713aSLionel Sambuc
23f4a2713aSLionel Sambuc A *a;
24f4a2713aSLionel Sambuc a->f();
25f4a2713aSLionel Sambuc }
26f4a2713aSLionel Sambuc
27f4a2713aSLionel Sambuc // Use the vtables
uses(A & a,B<int> & b,C & c)28f4a2713aSLionel Sambuc void uses(A &a, B<int> &b, C &c) {
29f4a2713aSLionel Sambuc a.f();
30f4a2713aSLionel Sambuc b.f();
31f4a2713aSLionel Sambuc c.f();
32f4a2713aSLionel Sambuc }
33f4a2713aSLionel Sambuc
34f4a2713aSLionel Sambuc // <rdar://problem/9979458>
35f4a2713aSLionel Sambuc class Parent {
36f4a2713aSLionel Sambuc public:
Parent()37f4a2713aSLionel Sambuc Parent() {}
38f4a2713aSLionel Sambuc virtual ~Parent();
39f4a2713aSLionel Sambuc virtual void * getFoo() const = 0;
40f4a2713aSLionel Sambuc };
41f4a2713aSLionel Sambuc
42f4a2713aSLionel Sambuc class Derived : public Parent {
43f4a2713aSLionel Sambuc public:
44f4a2713aSLionel Sambuc Derived();
45f4a2713aSLionel Sambuc void * getFoo() const;
46f4a2713aSLionel Sambuc };
47f4a2713aSLionel Sambuc
48f4a2713aSLionel Sambuc class VeryDerived : public Derived { // expected-warning{{'VeryDerived' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
49f4a2713aSLionel Sambuc public:
getFoo() const50f4a2713aSLionel Sambuc void * getFoo() const { return 0; }
51f4a2713aSLionel Sambuc };
52f4a2713aSLionel Sambuc
~Parent()53f4a2713aSLionel Sambuc Parent::~Parent() {}
54f4a2713aSLionel Sambuc
uses(Parent & p,Derived & d,VeryDerived & vd)55f4a2713aSLionel Sambuc void uses(Parent &p, Derived &d, VeryDerived &vd) {
56f4a2713aSLionel Sambuc p.getFoo();
57f4a2713aSLionel Sambuc d.getFoo();
58f4a2713aSLionel Sambuc vd.getFoo();
59f4a2713aSLionel Sambuc }
60f4a2713aSLionel Sambuc
61f4a2713aSLionel Sambuc template<typename T> struct TemplVirt {
62f4a2713aSLionel Sambuc virtual void f();
63f4a2713aSLionel Sambuc };
64f4a2713aSLionel Sambuc
65f4a2713aSLionel Sambuc template class TemplVirt<float>; // expected-warning{{explicit template instantiation 'TemplVirt<float>' will emit a vtable in every translation unit}}
66f4a2713aSLionel Sambuc
67f4a2713aSLionel Sambuc template<> struct TemplVirt<bool> {
68f4a2713aSLionel Sambuc virtual void f();
69f4a2713aSLionel Sambuc };
70f4a2713aSLionel Sambuc
71f4a2713aSLionel Sambuc template<> struct TemplVirt<long> { // expected-warning{{'TemplVirt<long>' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
fTemplVirt72f4a2713aSLionel Sambuc virtual void f() {}
73f4a2713aSLionel Sambuc };
74f4a2713aSLionel Sambuc
uses(TemplVirt<float> & f,TemplVirt<bool> & b,TemplVirt<long> & l)75f4a2713aSLionel Sambuc void uses(TemplVirt<float>& f, TemplVirt<bool>& b, TemplVirt<long>& l) {
76f4a2713aSLionel Sambuc f.f();
77f4a2713aSLionel Sambuc b.f();
78f4a2713aSLionel Sambuc l.f();
79f4a2713aSLionel Sambuc }
80