]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CXX/temp/temp.decls/temp.friend/p1.cpp
Update clang to r100181.
[FreeBSD/FreeBSD.git] / test / CXX / temp / temp.decls / temp.friend / p1.cpp
1 // RUN: %clang_cc1 -faccess-control -verify -emit-llvm-only %s
2
3 namespace test0 {
4 template <typename T> struct Num {
5   T value_;
6
7 public:
8   Num(T value) : value_(value) {}
9   T get() const { return value_; }
10
11   template <typename U> struct Rep {
12     U count_;
13     Rep(U count) : count_(count) {}
14
15     friend Num operator*(const Num &a, const Rep &n) {
16       Num x = 0;
17       for (U count = n.count_; count; --count)
18         x += a;
19       return x;
20     } 
21   };
22
23   friend Num operator+(const Num &a, const Num &b) {
24     return a.value_ + b.value_;
25   }
26
27   Num& operator+=(const Num& b) {
28     value_ += b.value_;
29     return *this;
30   }
31
32   class Representation {};
33   friend class Representation;
34 };
35
36 class A {
37   template <typename T> friend bool iszero(const A &a) throw();
38 };
39
40 template <class T> class B_iterator;
41 template <class T> class B {
42   friend class B_iterator<T>;
43 };
44
45 int calc1() {
46   Num<int> left = -1;
47   Num<int> right = 1;
48   Num<int> result = left + right;
49   return result.get();
50 }
51
52 int calc2() {
53   Num<int> x = 3;
54   Num<int>::Rep<char> n = (char) 10;
55   Num<int> result = x * n;
56   return result.get();
57 }
58 }
59
60 // Reduced from GNU <locale>
61 namespace test1 {
62   class A {
63     bool b; // expected-note {{declared private here}}
64     template <typename T> friend bool has(const A&);
65   };
66   template <typename T> bool has(const A &x) {
67     return x.b;
68   }
69   template <typename T> bool hasnot(const A &x) {
70     return x.b; // expected-error {{'b' is a private member of 'test1::A'}}
71   }
72 }
73
74 namespace test2 {
75   class A {
76     bool b; // expected-note {{declared private here}}
77     template <typename T> friend class HasChecker;
78   };
79   template <typename T> class HasChecker {
80     bool check(A *a) {
81       return a->b;
82     }
83   };
84   template <typename T> class HasNotChecker {
85     bool check(A *a) {
86       return a->b; // expected-error {{'b' is a private member of 'test2::A'}}
87     }
88   };
89 }
90
91 namespace test3 {
92   class Bool;
93   template <class T> class User;
94   template <class T> T transform(class Bool, T);
95
96   class Bool {
97     friend class User<bool>;
98     friend bool transform<>(Bool, bool);
99
100     bool value; // expected-note 2 {{declared private here}}
101   };
102
103   template <class T> class User {
104     static T compute(Bool b) {
105       return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}}
106     }
107   };
108
109   template <class T> T transform(Bool b, T value) {
110     if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}}
111       return value;
112     return value + 1;
113   }
114
115   template bool transform(Bool, bool);
116   template int transform(Bool, int); // expected-note {{requested here}}
117
118   template class User<bool>;
119   template class User<int>; // expected-note {{requested here}}
120 }
121
122 namespace test4 {
123   template <class T> class A {
124     template <class T0> friend class B;
125     bool foo(const A<T> *) const;
126   };
127
128   template <class T> class B {
129     bool bar(const A<T> *a, const A<T> *b) {
130       return a->foo(b);
131     }
132   };
133
134   template class B<int>;
135 }
136
137 namespace test5 {
138   template <class T, class U=int> class A {};
139   template <class T> class B {
140     template <class X, class Y> friend class A;
141   };
142   template class B<int>;
143   template class A<int>;
144 }
145
146 namespace Dependent {
147   template<typename T, typename Traits> class X;
148   template<typename T, typename Traits> 
149   X<T, Traits> operator+(const X<T, Traits>&, const T*);
150
151   template<typename T, typename Traits> class X {
152     typedef typename Traits::value_type value_type;
153     friend X operator+<>(const X&, const value_type*);
154   };
155 }
156
157 namespace test7 {
158   template <class T> class A { // expected-note {{previous definition is here}}
159     friend class B;
160     int x; // expected-note {{declared private here}}
161   };
162
163   class B {
164     int foo(A<int> &a) {
165       return a.x;
166     }
167   };
168
169   class C {
170     int foo(A<int> &a) {
171       return a.x; // expected-error {{'x' is a private member of 'test7::A<int>'}}
172     }
173   };
174
175   // This shouldn't crash.
176   template <class T> class D {
177     friend class A; // expected-error {{redefinition of 'A' as different kind of symbol}}
178   };
179   template class D<int>;
180 }
181
182 namespace test8 {
183   template <class N> class A {
184     static int x;
185     template <class T> friend void foo();
186   };
187   template class A<int>;
188
189   template <class T> void foo() {
190     A<int>::x = 0;
191   }
192   template void foo<int>();
193 }
194
195 namespace test9 {
196   template <class T> class A {
197     class B; class C;
198
199     int foo(B *b) {
200       return b->x;
201     }
202
203     int foo(C *c) {
204       return c->x; // expected-error {{'x' is a private member}}
205     }
206
207     class B {
208       int x;
209       friend int A::foo(B*);
210     };
211
212     class C {
213       int x; // expected-note {{declared private here}}
214     };
215   };
216
217   template class A<int>; // expected-note {{in instantiation}}
218 }