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 {
ftest1::A27     void f() { C::foo(); }
28   };
29 
30   template <class T> struct A<T*> {
ftest1::A31     void f() { C::foo(); }
32   };
33 
34   template <> struct A<char> {
ftest1::A35     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 {
ftest2::A49     void f() { C::foo(); }
50   };
51 
52   template <class T> struct A<T*> {
ftest2::A53     void f() { C::foo(); }
54   };
55 
56   template <> struct A<char> {
ftest2::A57     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 
foo()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 
test()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