1 | // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s |
2 | template<typename T> |
3 | class X0 { |
4 | friend T; |
5 | }; |
6 | |
7 | class Y1 { }; |
8 | enum E1 { }; |
9 | X0<Y1> x0a; |
10 | X0<Y1 *> x0b; |
11 | X0<int> x0c; |
12 | X0<E1> x0d; |
13 | |
14 | template<typename T> |
15 | class X1 { |
16 | friend typename T::type; // expected-error{{no type named 'type' in 'Y1'}} |
17 | }; |
18 | |
19 | struct Y2 { |
20 | struct type { }; |
21 | }; |
22 | |
23 | struct Y3 { |
24 | typedef int type; |
25 | }; |
26 | |
27 | X1<Y2> x1a; |
28 | X1<Y3> x1b; |
29 | X1<Y1> x1c; // expected-note{{in instantiation of template class 'X1<Y1>' requested here}} |
30 | |
31 | template<typename T> class B; |
32 | |
33 | template<typename T> |
34 | class A { |
35 | T x; |
36 | public: |
37 | class foo {}; |
38 | static int y; |
39 | template <typename S> friend class B<S>::ty; // expected-warning {{dependent nested name specifier 'B<S>::' for friend class declaration is not supported}} |
40 | }; |
41 | |
42 | template<typename T> class B { typedef int ty; }; |
43 | |
44 | template<> class B<int> { |
45 | class ty { |
46 | static int f(A<int> &a) { return a.y; } // ok, befriended |
47 | }; |
48 | }; |
49 | int f(A<char> &a) { return a.y; } // FIXME: should be an error |
50 | |
51 | struct { |
52 | // Ill-formed |
53 | int friend; // expected-error {{'friend' must appear first in a non-function declaration}} |
54 | unsigned friend int; // expected-error {{'friend' must appear first in a non-function declaration}} |
55 | const volatile friend int; // expected-error {{'friend' must appear first in a non-function declaration}} \ |
56 | // expected-error {{'const' is invalid in friend declarations}} \ |
57 | // expected-error {{'volatile' is invalid in friend declarations}} |
58 | int |
59 | friend; // expected-error {{'friend' must appear first in a non-function declaration}} |
60 | friend const int; // expected-error {{'const' is invalid in friend declarations}} |
61 | friend volatile int; // expected-error {{'volatile' is invalid in friend declarations}} |
62 | template <typename T> friend const class X; // expected-error {{'const' is invalid in friend declarations}} |
63 | // C++ doesn't have restrict and _Atomic, but they're both the same sort |
64 | // of qualifier. |
65 | typedef int *PtrToInt; |
66 | friend __restrict PtrToInt; // expected-error {{'restrict' is invalid in friend declarations}} \ |
67 | // expected-error {{restrict requires a pointer or reference}} |
68 | friend _Atomic int; // expected-error {{'_Atomic' is invalid in friend declarations}} |
69 | |
70 | // OK |
71 | int friend foo(void); |
72 | const int friend foo2(void); |
73 | friend int; |
74 | friend |
75 | |
76 | float; |
77 | template<typename T> friend class A<T>::foo; // expected-warning {{not supported}} |
78 | } a; |
79 | |
80 | void testA() { (void)sizeof(A<int>); } |
81 | |