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