p9-cxx0x.cpp revision 1f2e1a96bec2ba6418ae7f2d2b525a3575203b6a
1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3// C++98 [class.friend]p7:
4// C++11 [class.friend]p9:
5//   A name nominated by a friend declaration shall be accessible in
6//   the scope of the class containing the friend declaration.
7
8// PR12328
9// Simple, non-templated case.
10namespace test0 {
11  class X {
12    void f(); // expected-note {{implicitly declared private here}}
13  };
14
15  class Y {
16    friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test0::X'}}
17  };
18}
19
20// Templated but non-dependent.
21namespace test1 {
22  class X {
23    void f(); // expected-note {{implicitly declared private here}}
24  };
25
26  template <class T> class Y {
27    friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test1::X'}}
28  };
29}
30
31// Dependent but instantiated at the right type.
32namespace test2 {
33  template <class T> class Y;
34
35  class X {
36    void f();
37    friend class Y<int>;
38  };
39
40  template <class T> class Y {
41    friend void X::f();
42  };
43
44  template class Y<int>;
45}
46
47// Dependent and instantiated at the wrong type.
48namespace test3 {
49  template <class T> class Y;
50
51  class X {
52    void f(); // expected-note {{implicitly declared private here}}
53    friend class Y<int>;
54  };
55
56  template <class T> class Y {
57    friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test3::X'}}
58  };
59
60  template class Y<float>; // expected-note {{in instantiation}}
61}
62
63// Dependent because dependently-scoped.
64namespace test4 {
65  template <class T> class X {
66    void f();
67  };
68
69  template <class T> class Y {
70    friend void X<T>::f();
71  };
72}
73
74// Dependently-scoped, no friends.
75namespace test5 {
76  template <class T> class X {
77    void f(); // expected-note {{implicitly declared private here}}
78  };
79
80  template <class T> class Y {
81    friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test5::X<int>'}}
82  };
83
84  template class Y<int>; // expected-note {{in instantiation}}
85}
86
87// Dependently-scoped, wrong friend.
88namespace test6 {
89  template <class T> class Y;
90
91  template <class T> class X {
92    void f(); // expected-note {{implicitly declared private here}}
93    friend class Y<float>;
94  };
95
96  template <class T> class Y {
97    friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test6::X<int>'}}
98  };
99
100  template class Y<int>; // expected-note {{in instantiation}}
101}
102
103// Dependently-scoped, right friend.
104namespace test7 {
105  template <class T> class Y;
106
107  template <class T> class X {
108    void f();
109    friend class Y<int>;
110  };
111
112  template <class T> class Y {
113    friend void X<T>::f();
114  };
115
116  template class Y<int>;
117}
118