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