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}}
fA5   virtual void f() { }
6 };
7 
8 template<typename T> struct B {
fB9   virtual void f() { }
10 };
11 
12 namespace {
13   struct C {
f__anoncea9a5010111::C14     virtual void f() { }
15   };
16 }
17 
f()18 void f() {
19   struct A {
20     virtual void f() { }
21   };
22 
23   A *a;
24   a->f();
25 }
26 
27 // Use the vtables
uses(A & a,B<int> & b,C & c)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:
Parent()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:
getFoo() const50   void * getFoo() const { return 0; }
51 };
52 
~Parent()53 Parent::~Parent() {}
54 
uses(Parent & p,Derived & d,VeryDerived & vd)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}}
fTemplVirt72   virtual void f() {}
73 };
74 
uses(TemplVirt<float> & f,TemplVirt<bool> & b,TemplVirt<long> & l)75 void uses(TemplVirt<float>& f, TemplVirt<bool>& b, TemplVirt<long>& l) {
76   f.f();
77   b.f();
78   l.f();
79 }
80