| Richard Smith | 9ca5c42 | 2011-10-13 22:29:44 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s | 
| Douglas Gregor | 3b4abb6 | 2010-04-07 17:57:12 +0000 | [diff] [blame] | 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}} | 
| Richard Smith | a31a89a | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 30 |  | 
| Nick Lewycky | 36722d2 | 2013-02-06 05:59:33 +0000 | [diff] [blame] | 31 | template<typename T> class B; | 
|  | 32 |  | 
| Richard Smith | a31a89a | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 33 | template<typename T> | 
|  | 34 | class A { | 
|  | 35 | T x; | 
|  | 36 | public: | 
|  | 37 | class foo {}; | 
|  | 38 | static int y; | 
| Richard Smith | cd556eb | 2013-11-08 18:59:56 +0000 | [diff] [blame] | 39 | template <typename S> friend class B<S>::ty; // expected-warning {{dependent nested name specifier 'B<S>::' for friend class declaration is not supported}} | 
| Richard Smith | a31a89a | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 40 | }; | 
|  | 41 |  | 
| Richard Smith | cd556eb | 2013-11-08 18:59:56 +0000 | [diff] [blame] | 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 | 
| Nick Lewycky | 36722d2 | 2013-02-06 05:59:33 +0000 | [diff] [blame] | 50 |  | 
| Richard Smith | a31a89a | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 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 | int | 
|  | 57 | friend; // expected-error {{'friend' must appear first in a non-function declaration}} | 
|  | 58 |  | 
|  | 59 | // OK | 
|  | 60 | int friend foo(void); | 
|  | 61 | friend int; | 
|  | 62 | friend const volatile int; | 
|  | 63 | friend | 
|  | 64 |  | 
|  | 65 | float; | 
| Richard Smith | cd556eb | 2013-11-08 18:59:56 +0000 | [diff] [blame] | 66 | template<typename T> friend class A<T>::foo; // expected-warning {{not supported}} | 
| Richard Smith | a31a89a | 2012-09-20 01:31:00 +0000 | [diff] [blame] | 67 | } a; | 
| Nick Lewycky | 36722d2 | 2013-02-06 05:59:33 +0000 | [diff] [blame] | 68 |  | 
|  | 69 | void testA() { (void)sizeof(A<int>); } |