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}} 4 virtual void f() { } 5 }; 6 7 template<typename T> struct B { 8 virtual void f() { } 9 }; 10 11 namespace { 12 struct C { 13 virtual void f() { } 14 }; 15 } 16 17 void f() { 18 struct A { 19 virtual void f() { } 20 }; 21 22 A *a; 23 a->f(); 24 } 25 26 // Use the vtables 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: 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: 49 void * getFoo() const { return 0; } 50 }; 51 52 Parent::~Parent() {} 53 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}} 71 virtual void f() {} 72 }; 73 74 void uses(TemplVirt<float>& f, TemplVirt<bool>& b, TemplVirt<long>& l) { 75 f.f(); 76 b.f(); 77 l.f(); 78 } 79