Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 // PR5057
      3 namespace test0 {
      4   namespace std {
      5     class X {
      6     public:
      7       template<typename T> friend struct Y;
      8     };
      9   }
     10 
     11   namespace std {
     12     template<typename T> struct Y {};
     13   }
     14 }
     15 
     16 namespace test1 {
     17   template<typename T> void f1(T) { } // expected-note{{here}}
     18 
     19   class X {
     20     template<typename T> friend void f0(T);
     21     template<typename T> friend void f1(T);
     22   };
     23 
     24   template<typename T> void f0(T) { }
     25   template<typename T> void f1(T) { } // expected-error{{redefinition}}
     26 }
     27 
     28 // PR4768
     29 namespace test2 {
     30   template<typename T> struct X0 {
     31     template<typename U> friend struct X0;
     32   };
     33 
     34   template<typename T> struct X0<T*> {
     35     template<typename U> friend struct X0;
     36   };
     37 
     38   template<> struct X0<int> {
     39     template<typename U> friend struct X0;
     40   };
     41 
     42   template<typename T> struct X1 {
     43     template<typename U> friend void f2(U);
     44     template<typename U> friend void f3(U);
     45   };
     46 
     47   template<typename U> void f2(U);
     48 
     49   X1<int> x1i;
     50   X0<int*> x0ip;
     51 
     52   template<> void f2(int);
     53 
     54   // FIXME: Should this declaration of f3 be required for the specialization of
     55   // f3<int> (further below) to work? GCC and EDG don't require it, we do...
     56   template<typename U> void f3(U);
     57 
     58   template<> void f3(int);
     59 }
     60 
     61 // PR5332
     62 namespace test3 {
     63   template <typename T> class Foo {
     64     template <typename U>
     65     friend class Foo;
     66   };
     67 
     68   Foo<int> foo;
     69 
     70   template<typename T, T Value> struct X2a;
     71 
     72   template<typename T, int Size> struct X2b;
     73 
     74   template<typename T>
     75   class X3 {
     76     template<typename U, U Value> friend struct X2a;
     77 
     78     // FIXME: the redeclaration note ends up here because redeclaration
     79     // lookup ends up finding the friend target from X3<int>.
     80     template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \
     81       // expected-note {{previous non-type template parameter with type 'int' is here}}
     82   };
     83 
     84   X3<int> x3i; // okay
     85 
     86   X3<long> x3l; // expected-note {{in instantiation}}
     87 }
     88 
     89 // PR5716
     90 namespace test4 {
     91   template<typename> struct A {
     92     template<typename T> friend void f(const A<T>&);
     93   };
     94 
     95   template<typename T> void f(const A<T>&) {
     96     int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}}
     97   }
     98 
     99   void f() {
    100     f(A<int>()); // expected-note {{in instantiation of function template specialization}}
    101   }
    102 }
    103 
    104 namespace test5 {
    105   class outer {
    106     class foo;
    107     template <typename T> friend struct cache;
    108   };
    109   class outer::foo {
    110     template <typename T> friend struct cache;
    111   };
    112 }
    113 
    114 // PR6022
    115 namespace PR6022 {
    116   template <class T1, class T2 , class T3  > class A;
    117 
    118   namespace inner {
    119     template<class T1, class T2, class T3, class T>
    120     A<T1, T2, T3>& f0(A<T1, T2, T3>&, T);
    121   }
    122 
    123   template<class T1, class T2, class T3>
    124   class A {
    125     template<class U1, class U2, class U3, class T>
    126     friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T);
    127   };
    128 }
    129 
    130 namespace FriendTemplateDefinition {
    131   template<unsigned > struct int_c { };
    132 
    133   template<typename T>
    134   struct X {
    135     template<unsigned N>
    136     friend void f(X, int_c<N>) {
    137       int value = N;
    138     };
    139   };
    140 
    141   void test_X(X<int> x, int_c<5> i5) {
    142     f(x, i5);
    143   }
    144 }
    145 
    146 namespace PR7013a {
    147   template<class > struct X0
    148   {
    149     typedef int type;
    150   };
    151   template<typename > struct X1
    152   {
    153   };
    154   template<typename , typename T> struct X2
    155   {
    156     typename T::type e;
    157   };
    158   namespace N
    159   {
    160     template <typename = int, typename = X1<int> > struct X3
    161     {
    162       template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
    163     };
    164     template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
    165     {
    166       X2<int, Tr> s;
    167     }
    168   }
    169   int n()
    170   {
    171     X2<int, X0<int> > ngs;
    172     N::X3<> b;
    173     op(ngs, b);
    174     return 0;
    175   }
    176 }
    177 
    178 namespace PR7013b {
    179   template<class > struct X0
    180   {
    181     typedef int type;
    182   };
    183   template<typename > struct X1
    184   {
    185   };
    186   template<typename , typename T> struct X2
    187   {
    188     typename T::type e;
    189   };
    190   namespace N
    191   {
    192     template <typename = X1<int> > struct X3
    193     {
    194       template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
    195     };
    196     template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
    197     {
    198       X2<int, Tr> s;
    199     }
    200   }
    201   int n()
    202   {
    203     X2<int, X0<int> > ngs;
    204     N::X3<> b;
    205     op(ngs, b);
    206     return 0;
    207   }
    208 
    209 }
    210 
    211 namespace PR8649 {
    212   template<typename T, typename U, unsigned N>
    213   struct X {
    214     template<unsigned M> friend class X<T, U, M>; // expected-error{{partial specialization cannot be declared as a friend}}
    215   };
    216 
    217   X<int, float, 7> x;
    218 }
    219 
    220 // Don't crash, and error on invalid friend type template.
    221 namespace friend_type_template_no_tag {
    222   template <typename T> struct S {
    223     template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}}
    224   };
    225   template struct S<int>;
    226 }
    227 
    228 namespace PR10660 {
    229   struct A {
    230     template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
    231   };
    232 }
    233 
    234 namespace rdar11147355 {
    235   template <class T>
    236   struct A {
    237     template <class U> class B;
    238     template <class S> template <class U> friend class A<S>::B; // expected-warning {{dependent nested name specifier 'A<S>::' for friend template declaration is not supported; ignoring this friend declaration}}
    239   private:
    240     int n; // expected-note {{here}}
    241   };
    242 
    243   template <class S> template <class U> class A<S>::B {
    244   public:
    245     // FIXME: This should be permitted.
    246     int f(A<S*> a) { return a.n; } // expected-error {{private}}
    247   };
    248 
    249   A<double>::B<double>  ab;
    250   A<double*> a;
    251   int k = ab.f(a); // expected-note {{instantiation of}}
    252 }
    253 
    254 namespace RedeclUnrelated {
    255   struct S {
    256     int packaged_task;
    257     template<typename> class future {
    258       template<typename> friend class packaged_task;
    259     };
    260     future<void> share;
    261   };
    262 }
    263 
    264 namespace PR12557 {
    265   template <typename>
    266   struct Foo;
    267 
    268   template <typename Foo_>
    269   struct Bar {
    270     typedef Foo_  Foo; // expected-note {{previous}}
    271 
    272     template <typename> friend struct Foo; // expected-error {{redefinition of 'Foo' as different kind of symbol}}
    273   };
    274 
    275   Bar<int> b;
    276 }
    277 
    278 namespace PR12585 {
    279   struct A { };
    280   template<typename> struct B {
    281     template<typename> friend class A::does_not_exist; // \
    282      // expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}}
    283   };
    284 
    285   struct C {
    286     template<typename> struct D;
    287   };
    288   template<typename> class E {
    289     int n;
    290     template<typename> friend struct C::D;
    291   };
    292   template<typename T> struct C::D {
    293     int f() {
    294       return E<int>().n;
    295     }
    296   };
    297   int n = C::D<void*>().f();
    298 
    299   struct F {
    300     template<int> struct G;
    301   };
    302   template<typename T> struct H {
    303     // FIXME: As with cases above, the note here is on an unhelpful declaration,
    304     // and should point to the declaration of G within F.
    305     template<T> friend struct F::G; // \
    306       // expected-error {{different type 'char' in template redeclaration}} \
    307       // expected-note {{previous}}
    308   };
    309   H<int> h1; // ok
    310   H<char> h2; // expected-note {{instantiation}}
    311 }
    312 
    313 // Ensure that we can still instantiate a friend function template
    314 // after the friend declaration is instantiated during the delayed
    315 // parsing of a member function, but before the friend function has
    316 // been parsed.
    317 namespace rdar12350696 {
    318   template <class T> struct A {
    319     void foo() {
    320       A<int> a;
    321     }
    322     template <class U> friend void foo(const A<U> & a) {
    323       int array[sizeof(T) == sizeof(U) ? -1 : 1]; // expected-error {{negative size}}
    324     }
    325   };
    326 
    327   void test() {
    328     A<int> b;
    329     foo(b); // expected-note {{in instantiation}}
    330   }
    331 }
    332