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__anon4bd77e580111::C14     virtual void f() { }
15   };
16 }
17 
f()18 void f() {
19   struct A {
20     virtual void f() { }
21   };
22 
23   A a;
24 }
25 
26 // Use the vtables
uses_abc()27 void uses_abc() {
28   A a;
29   B<int> b;
30   C c;
31 }
32 
33 // <rdar://problem/9979458>
34 class Parent {
35 public:
Parent()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:
getFoo() const49   void * getFoo() const { return 0; }
50 };
51 
~Parent()52 Parent::~Parent() {}
53 
uses_derived()54 void uses_derived() {
55   Derived d;
56   VeryDerived vd;
57 }
58 
59 template<typename T> struct TemplVirt {
60   virtual void f();
61 };
62 
63 template class TemplVirt<float>; // expected-warning{{explicit template instantiation 'TemplVirt<float>' will emit a vtable in every translation unit}}
64 
65 template<> struct TemplVirt<bool> {
66   virtual void f();
67 };
68 
69 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}}
fTemplVirt70   virtual void f() {}
71 };
72 
uses_templ()73 void uses_templ() {
74   TemplVirt<float> f;
75   TemplVirt<bool> b;
76   TemplVirt<long> l;
77 }
78