blob: 135e0342596c4cb0b99685def121dcdaf75b8970 (
about) (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
// RUN: %clang_cc1 %s -fsyntax-only -verify -Wweak-vtables -Wweak-template-vtables
struct A { // expected-warning {{'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
virtual void f() { }
};
template<typename T> struct B {
virtual void f() { }
};
namespace {
struct C {
virtual void f() { }
};
}
void f() {
struct A {
virtual void f() { }
};
A *a;
a->f();
}
// Use the vtables
void uses(A &a, B<int> &b, C &c) {
a.f();
b.f();
c.f();
}
// <rdar://problem/9979458>
class Parent {
public:
Parent() {}
virtual ~Parent();
virtual void * getFoo() const = 0;
};
class Derived : public Parent {
public:
Derived();
void * getFoo() const;
};
class VeryDerived : public Derived { // expected-warning{{'VeryDerived' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
public:
void * getFoo() const { return 0; }
};
Parent::~Parent() {}
void uses(Parent &p, Derived &d, VeryDerived &vd) {
p.getFoo();
d.getFoo();
vd.getFoo();
}
template<typename T> struct TemplVirt {
virtual void f();
};
template class TemplVirt<float>; // expected-warning{{explicit template instantiation 'TemplVirt<float>' will emit a vtable in every translation unit}}
template<> struct TemplVirt<bool> {
virtual void f();
};
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}}
virtual void f() {}
};
void uses(TemplVirt<float>& f, TemplVirt<bool>& b, TemplVirt<long>& l) {
f.f();
b.f();
l.f();
}
|