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__anon5f5cdb890111::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