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