Daniel Dunbar | a572887 | 2009-12-15 20:14:24 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
Douglas Gregor | d85bea2 | 2009-09-26 06:47:28 +0000 | [diff] [blame] | 2 | |
| 3 | // PR5057 |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 4 | namespace test0 { |
| 5 | namespace std { |
| 6 | class X { |
| 7 | public: |
| 8 | template<typename T> friend struct Y; |
| 9 | }; |
| 10 | } |
| 11 | |
| 12 | namespace std { |
| 13 | template<typename T> struct Y {}; |
| 14 | } |
Douglas Gregor | d85bea2 | 2009-09-26 06:47:28 +0000 | [diff] [blame] | 15 | } |
| 16 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 17 | namespace test1 { |
Douglas Gregor | 182ddf0 | 2009-09-28 00:08:27 +0000 | [diff] [blame] | 18 | template<typename T> void f1(T) { } // expected-note{{here}} |
| 19 | |
| 20 | class X { |
| 21 | template<typename T> friend void f0(T); |
| 22 | template<typename T> friend void f1(T); |
| 23 | }; |
| 24 | |
| 25 | template<typename T> void f0(T) { } |
| 26 | template<typename T> void f1(T) { } // expected-error{{redefinition}} |
| 27 | } |
Douglas Gregor | d7e5bdb | 2009-10-09 21:11:42 +0000 | [diff] [blame] | 28 | |
| 29 | // PR4768 |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 30 | namespace test2 { |
| 31 | template<typename T> struct X0 { |
| 32 | template<typename U> friend struct X0; |
| 33 | }; |
| 34 | |
| 35 | template<typename T> struct X0<T*> { |
| 36 | template<typename U> friend struct X0; |
| 37 | }; |
Douglas Gregor | d7e5bdb | 2009-10-09 21:11:42 +0000 | [diff] [blame] | 38 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 39 | template<> struct X0<int> { |
| 40 | template<typename U> friend struct X0; |
| 41 | }; |
Douglas Gregor | d7e5bdb | 2009-10-09 21:11:42 +0000 | [diff] [blame] | 42 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 43 | template<typename T> struct X1 { |
| 44 | template<typename U> friend void f2(U); |
| 45 | template<typename U> friend void f3(U); |
| 46 | }; |
Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 47 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 48 | template<typename U> void f2(U); |
Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 49 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 50 | X1<int> x1i; |
| 51 | X0<int*> x0ip; |
Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 52 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 53 | template<> void f2(int); |
Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 54 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 55 | // FIXME: Should this declaration of f3 be required for the specialization of |
| 56 | // f3<int> (further below) to work? GCC and EDG don't require it, we do... |
| 57 | template<typename U> void f3(U); |
Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 58 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 59 | template<> void f3(int); |
| 60 | } |
Douglas Gregor | e8c01bd | 2009-10-30 21:07:27 +0000 | [diff] [blame] | 61 | |
| 62 | // PR5332 |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 63 | namespace test3 { |
| 64 | template <typename T> class Foo { |
| 65 | template <typename U> |
| 66 | friend class Foo; |
| 67 | }; |
Douglas Gregor | e8c01bd | 2009-10-30 21:07:27 +0000 | [diff] [blame] | 68 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 69 | Foo<int> foo; |
Douglas Gregor | 259571e | 2009-10-30 22:42:42 +0000 | [diff] [blame] | 70 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 71 | template<typename T, T Value> struct X2a; |
Douglas Gregor | 259571e | 2009-10-30 22:42:42 +0000 | [diff] [blame] | 72 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 73 | template<typename T, int Size> struct X2b; |
Douglas Gregor | 259571e | 2009-10-30 22:42:42 +0000 | [diff] [blame] | 74 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 75 | template<typename T> |
| 76 | class X3 { |
| 77 | template<typename U, U Value> friend struct X2a; |
| 78 | template<typename U, T Value> friend struct X2b; |
| 79 | }; |
Douglas Gregor | 259571e | 2009-10-30 22:42:42 +0000 | [diff] [blame] | 80 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 81 | X3<int> x3i; // okay |
Douglas Gregor | 259571e | 2009-10-30 22:42:42 +0000 | [diff] [blame] | 82 | |
John McCall | 4b6e90a | 2009-12-11 20:51:23 +0000 | [diff] [blame] | 83 | X3<long> x3l; // FIXME: should cause an instantiation-time failure |
| 84 | } |
John McCall | e976ffe | 2009-12-14 23:19:40 +0000 | [diff] [blame] | 85 | |
| 86 | // PR5716 |
| 87 | namespace test4 { |
| 88 | template<typename> struct A { |
| 89 | template<typename T> friend void f(const A<T>&); |
| 90 | }; |
| 91 | |
| 92 | template<typename T> void f(const A<T>&) { |
| 93 | int a[sizeof(T) ? -1 : -1]; // expected-error {{array size is negative}} |
| 94 | } |
| 95 | |
| 96 | void f() { |
| 97 | f(A<int>()); // expected-note {{in instantiation of function template specialization}} |
| 98 | } |
| 99 | } |
John McCall | 65c4946 | 2009-12-18 11:25:59 +0000 | [diff] [blame^] | 100 | |
| 101 | namespace test5 { |
| 102 | class outer { |
| 103 | class foo; |
| 104 | template <typename T> friend struct cache; |
| 105 | }; |
| 106 | class outer::foo { |
| 107 | template <typename T> friend struct cache; |
| 108 | }; |
| 109 | } |