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