p1.cpp revision 93ba8579c341d5329175f1413cdc3b35a36592d2
1// RUN: %clang_cc1 -faccess-control -verify -emit-llvm-only %s 2template <typename T> struct Num { 3 T value_; 4 5public: 6 Num(T value) : value_(value) {} 7 T get() const { return value_; } 8 9 template <typename U> struct Rep { 10 U count_; 11 Rep(U count) : count_(count) {} 12 13 friend Num operator*(const Num &a, const Rep &n) { 14 Num x = 0; 15 for (U count = n.count_; count; --count) 16 x += a; 17 return x; 18 } 19 }; 20 21 friend Num operator+(const Num &a, const Num &b) { 22 return a.value_ + b.value_; 23 } 24 25 Num& operator+=(const Num& b) { 26 value_ += b.value_; 27 return *this; 28 } 29 30 class Representation {}; 31 friend class Representation; 32}; 33 34class A { 35 template <typename T> friend bool iszero(const A &a) throw(); 36}; 37 38template <class T> class B_iterator; 39template <class T> class B { 40 friend class B_iterator<T>; 41}; 42 43int calc1() { 44 Num<int> left = -1; 45 Num<int> right = 1; 46 Num<int> result = left + right; 47 return result.get(); 48} 49 50int calc2() { 51 Num<int> x = 3; 52 Num<int>::Rep<char> n = (char) 10; 53 Num<int> result = x * n; 54 return result.get(); 55} 56 57// Reduced from GNU <locale> 58namespace test1 { 59 class A { 60 bool b; // expected-note {{declared private here}} 61 template <typename T> friend bool has(const A&); 62 }; 63 template <typename T> bool has(const A &x) { 64 return x.b; 65 } 66 template <typename T> bool hasnot(const A &x) { 67 return x.b; // expected-error {{'b' is a private member of 'test1::A'}} 68 } 69} 70 71namespace test2 { 72 class A { 73 bool b; // expected-note {{declared private here}} 74 template <typename T> friend class HasChecker; 75 }; 76 template <typename T> class HasChecker { 77 bool check(A *a) { 78 return a->b; 79 } 80 }; 81 template <typename T> class HasNotChecker { 82 bool check(A *a) { 83 return a->b; // expected-error {{'b' is a private member of 'test2::A'}} 84 } 85 }; 86} 87 88namespace test3 { 89 class Bool; 90 template <class T> class User; 91 template <class T> T transform(class Bool, T); 92 93 class Bool { 94 friend class User<bool>; 95 friend bool transform<>(Bool, bool); 96 97 bool value; // expected-note 2 {{declared private here}} 98 }; 99 100 template <class T> class User { 101 static T compute(Bool b) { 102 return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}} 103 } 104 }; 105 106 template <class T> T transform(Bool b, T value) { 107 if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}} 108 return value; 109 return value + 1; 110 } 111 112 template bool transform(Bool, bool); 113 template int transform(Bool, int); // expected-note {{requested here}} 114 115 template class User<bool>; 116 template class User<int>; // expected-note {{requested here}} 117} 118 119namespace test4 { 120 template <class T> class A { 121 template <class T0> friend class B; 122 bool foo(const A<T> *) const; 123 }; 124 125 template <class T> class B { 126 bool bar(const A<T> *a, const A<T> *b) { 127 return a->foo(b); 128 } 129 }; 130 131 template class B<int>; 132} 133 134namespace test5 { 135 template <class T, class U=int> class A {}; 136 template <class T> class B { 137 template <class X, class Y> friend class A; 138 }; 139 template class B<int>; 140 template class A<int>; 141} 142 143namespace Dependent { 144 template<typename T, typename Traits> class X; 145 template<typename T, typename Traits> 146 X<T, Traits> operator+(const X<T, Traits>&, const T*); 147 148 template<typename T, typename Traits> class X { 149 typedef typename Traits::value_type value_type; 150 friend X operator+<>(const X&, const value_type*); 151 }; 152} 153