Home | History | Annotate | Download | only in temp.friend
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 namespace test0 {
      4   template <class T> class A {
      5     class Member {};
      6   };
      7 
      8   class B {
      9     template <class T> friend class A<T>::Member; // expected-warning {{not supported}}
     10     int n;
     11   };
     12 
     13   A<int> a;
     14   B b;
     15 }
     16 
     17 // rdar://problem/8204127
     18 namespace test1 {
     19   template <class T> struct A;
     20 
     21   class C {
     22     static void foo();
     23     template <class T> friend void A<T>::f(); // expected-warning {{not supported}}
     24   };
     25 
     26   template <class T> struct A {
     27     void f() { C::foo(); }
     28   };
     29 
     30   template <class T> struct A<T*> {
     31     void f() { C::foo(); }
     32   };
     33 
     34   template <> struct A<char> {
     35     void f() { C::foo(); }
     36   };
     37 }
     38 
     39 // FIXME: these should fail!
     40 namespace test2 {
     41   template <class T> struct A;
     42 
     43   class C {
     44     static void foo();
     45     template <class T> friend void A<T>::g(); // expected-warning {{not supported}}
     46   };
     47 
     48   template <class T> struct A {
     49     void f() { C::foo(); }
     50   };
     51 
     52   template <class T> struct A<T*> {
     53     void f() { C::foo(); }
     54   };
     55 
     56   template <> struct A<char> {
     57     void f() { C::foo(); }
     58   };
     59 }
     60 
     61 // Tests 3, 4 and 5 were all noted in <rdar://problem/8540527>.
     62 namespace test3 {
     63   template <class T> struct A {
     64     struct Inner {
     65       static int foo();
     66     };
     67   };
     68 
     69   template <class U> class C {
     70     int i;
     71     template <class T> friend struct A<T>::Inner; // expected-warning {{not supported}}
     72   };
     73 
     74   template <class T> int A<T>::Inner::foo() {
     75     C<int> c;
     76     c.i = 0;
     77     return 0;
     78   }
     79 
     80   int test = A<int>::Inner::foo();
     81 }
     82 
     83 namespace test4 {
     84   template <class T> struct X {
     85     template <class U> void operator+=(U);
     86 
     87     template <class V>
     88     template <class U>
     89     friend void X<V>::operator+=(U); // expected-warning {{not supported}}
     90   };
     91 
     92   void test() {
     93     X<int>() += 1.0;
     94   }
     95 }
     96 
     97 namespace test5 {
     98   template<template <class> class T> struct A {
     99     template<template <class> class U> friend void A<U>::foo(); // expected-warning {{not supported}}
    100   };
    101 
    102   template <class> struct B {};
    103   template class A<B>;
    104 }
    105