p1.cpp revision e131c574c7baa28eb0759181478d710a2aa60cb6
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}
119
120namespace Dependent {
121  template<typename T, typename Traits> class X;
122  template<typename T, typename Traits>
123  X<T, Traits> operator+(const X<T, Traits>&, const T*);
124
125  template<typename T, typename Traits> class X {
126    typedef typename Traits::value_type value_type;
127    friend X operator+<>(const X&, const value_type*);
128  };
129}
130