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