1// RUN: %clang_cc1 %s -verify -fexceptions
2class A {
3  void f() __attribute__((deprecated)); // expected-note 2 {{'f' has been explicitly marked deprecated here}}
4  void g(A* a);
5  void h(A* a) __attribute__((deprecated));
6
7  int b __attribute__((deprecated)); // expected-note 2 {{'b' has been explicitly marked deprecated here}}
8};
9
10void A::g(A* a)
11{
12  f(); // expected-warning{{'f' is deprecated}}
13  a->f(); // expected-warning{{'f' is deprecated}}
14
15  (void)b; // expected-warning{{'b' is deprecated}}
16  (void)a->b; // expected-warning{{'b' is deprecated}}
17}
18
19void A::h(A* a)
20{
21  f();
22  a->f();
23
24  (void)b;
25  (void)a->b;
26}
27
28struct B {
29  virtual void f() __attribute__((deprecated)); // expected-note 4 {{'f' has been explicitly marked deprecated here}}
30  void g();
31};
32
33void B::g() {
34  f();
35  B::f(); // expected-warning{{'f' is deprecated}}
36}
37
38struct C : B {
39  virtual void f();
40  void g();
41};
42
43void C::g() {
44  f();
45  C::f();
46  B::f(); // expected-warning{{'f' is deprecated}}
47}
48
49void f(B* b, C *c) {
50  b->f();
51  b->B::f(); // expected-warning{{'f' is deprecated}}
52
53  c->f();
54  c->C::f();
55  c->B::f(); // expected-warning{{'f' is deprecated}}
56}
57
58struct D {
59  virtual void f() __attribute__((deprecated));
60};
61
62void D::f() { }
63
64void f(D* d) {
65  d->f();
66}
67
68
69// Overloaded namespace members.
70namespace test1 {
71  void foo(int) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
72  void test1() { foo(10); } // expected-warning {{deprecated}}
73  void foo(short) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
74  void test2(short s) { foo(s); } // expected-warning {{deprecated}}
75  void foo(long);
76  void test3(long l) { foo(l); }
77  struct A {
78    friend void foo(A*) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
79  };
80  void test4(A *a) { foo(a); } // expected-warning {{deprecated}}
81
82  namespace ns {
83    struct Foo {};
84    void foo(const Foo &f) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
85  }
86  void test5() {
87    foo(ns::Foo()); // expected-warning {{deprecated}}
88  }
89}
90
91// Overloaded class members.
92namespace test2 {
93  struct A {
94    void foo(int) __attribute__((deprecated)); // expected-note 2 {{'foo' has been explicitly marked deprecated here}}
95    void foo(long);
96    static void bar(int) __attribute__((deprecated)); // expected-note 3 {{'bar' has been explicitly marked deprecated here}}
97    static void bar(long);
98
99    void test2(int i, long l);
100  };
101  void test1(int i, long l) {
102    A a;
103    a.foo(i); // expected-warning {{deprecated}}
104    a.foo(l);
105    a.bar(i); // expected-warning {{deprecated}}
106    a.bar(l);
107    A::bar(i); // expected-warning {{deprecated}}
108    A::bar(l);
109  }
110
111  void A::test2(int i, long l) {
112    foo(i); // expected-warning {{deprecated}}
113    foo(l);
114    bar(i); // expected-warning {{deprecated}}
115    bar(l);
116  }
117}
118
119// Overloaded operators.
120namespace test3 {
121  struct A {
122    void operator*(const A &);
123    void operator*(int) __attribute__((deprecated)); // expected-note {{'operator*' has been explicitly marked deprecated here}}
124    void operator-(const A &) const;
125  };
126  void operator+(const A &, const A &);
127  void operator+(const A &, int) __attribute__((deprecated)); // expected-note {{'operator+' has been explicitly marked deprecated here}}
128  void operator-(const A &, int) __attribute__((deprecated)); // expected-note {{'operator-' has been explicitly marked deprecated here}}
129
130  void test() {
131    A a, b;
132    a + b;
133    a + 1; // expected-warning {{deprecated}}
134    a - b;
135    a - 1; // expected-warning {{deprecated}}
136    a * b;
137    a * 1; // expected-warning {{deprecated}}
138  }
139}
140
141// Overloaded operator call.
142namespace test4 {
143  struct A {
144    typedef void (*intfn)(int);
145    typedef void (*unintfn)(unsigned);
146    operator intfn() __attribute__((deprecated)); // expected-note {{'operator void (*)(int)' has been explicitly marked deprecated here}}
147    operator unintfn();
148    void operator ()(A &) __attribute__((deprecated)); // expected-note {{'operator()' has been explicitly marked deprecated here}}
149    void operator ()(const A &);
150  };
151
152  void test() {
153    A a;
154    a(1); // expected-warning {{deprecated}}
155    a(1U);
156
157    A &b = a;
158    const A &c = a;
159    a(b); // expected-warning {{deprecated}}
160    a(c);
161  }
162}
163
164namespace test5 {
165  struct A {
166    operator int() __attribute__((deprecated)); // expected-note 3 {{'operator int' has been explicitly marked deprecated here}}
167    operator long();
168  };
169  void test1(A a) {
170    int i = a; // expected-warning {{deprecated}}
171    long l = a;
172  }
173
174  void foo(int);
175  void foo(void*);
176  void bar(long);
177  void bar(void*);
178  void test2(A a) {
179    foo(a); // expected-warning {{deprecated}}
180    bar(a);
181  }
182
183  struct B {
184    int myInt;
185    long myLong;
186
187    B(A &a) :
188      myInt(a), // expected-warning {{deprecated}}
189      myLong(a)
190    {}
191  };
192}
193
194// rdar://problem/8518751
195namespace test6 {
196  enum __attribute__((deprecated)) A { // expected-note {{'A' has been explicitly marked deprecated here}}
197    a0 // expected-note {{'a0' has been explicitly marked deprecated here}}
198  };
199  void testA() {
200    A x; // expected-warning {{'A' is deprecated}}
201    x = a0; // expected-warning {{'a0' is deprecated}}
202  }
203
204  enum B {
205    b0 __attribute__((deprecated)), // expected-note {{'b0' has been explicitly marked deprecated here}}
206    b1
207  };
208  void testB() {
209    B x;
210    x = b0; // expected-warning {{'b0' is deprecated}}
211    x = b1;
212  }
213
214  template <class T> struct C {
215    enum __attribute__((deprecated)) Enum { // expected-note {{'Enum' has been explicitly marked deprecated here}}
216      c0 // expected-note {{'c0' has been explicitly marked deprecated here}}
217    };
218  };
219  void testC() {
220    C<int>::Enum x; // expected-warning {{'Enum' is deprecated}}
221    x = C<int>::c0; // expected-warning {{'c0' is deprecated}}
222  }
223
224  template <class T> struct D {
225    enum Enum {
226      d0,
227      d1 __attribute__((deprecated)), // expected-note {{'d1' has been explicitly marked deprecated here}}
228    };
229  };
230  void testD() {
231    D<int>::Enum x;
232    x = D<int>::d0;
233    x = D<int>::d1; // expected-warning {{'d1' is deprecated}}
234  }
235}
236
237namespace test7 {
238  struct X {
239    void* operator new(typeof(sizeof(void*))) __attribute__((deprecated));  // expected-note{{'operator new' has been explicitly marked deprecated here}}
240    void operator delete(void *) __attribute__((deprecated));  // expected-note{{'operator delete' has been explicitly marked deprecated here}}
241  };
242
243  void test() {
244    X *x = new X;  // expected-warning{{'operator new' is deprecated}} expected-warning{{'operator delete' is deprecated}}
245  }
246}
247
248// rdar://problem/15044218
249typedef struct TDS {
250} TDS __attribute__((deprecated)); // expected-note {{'TDS' has been explicitly marked deprecated here}}
251TDS tds; // expected-warning {{'TDS' is deprecated}}
252struct TDS tds2; // no warning, attribute only applies to the typedef.
253