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