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