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