Home | History | Annotate | Download | only in temp.friend
      1 // RUN: %clang_cc1 -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 {{declared 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 {{elaborated type refers to a template}}
    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 }
    219 
    220 namespace test10 {
    221   template <class T> class A;
    222   template <class T> A<T> bar(const T*, const A<T>&);
    223   template <class T> class A {
    224   private:
    225     void foo(); // expected-note {{declared private here}}
    226     friend A bar<>(const T*, const A<T>&);
    227   };
    228 
    229   template <class T> A<T> bar(const T *l, const A<T> &r) {
    230     A<T> l1;
    231     l1.foo();
    232 
    233     A<char> l2;
    234     l2.foo(); // expected-error {{'foo' is a private member of 'test10::A<char>'}}
    235 
    236     return l1;
    237   }
    238 
    239   template A<int> bar<int>(const int *, const A<int> &); // expected-note {{in instantiation}}
    240 }
    241 
    242 // PR6752: this shouldn't crash.
    243 namespace test11 {
    244   struct Foo {
    245     template<class A>
    246     struct IteratorImpl {
    247       template<class T> friend class IteratorImpl;
    248     };
    249   };
    250 
    251   template struct Foo::IteratorImpl<int>;
    252   template struct Foo::IteratorImpl<long>;
    253 }
    254 
    255 // PR6827
    256 namespace test12 {
    257   template <typename T> class Foo;
    258   template <typename T> Foo<T> foo(T* t){ return Foo<T>(t, true); }
    259 
    260   template <typename T> class Foo {
    261   public:
    262     Foo(T*);
    263     friend Foo<T> foo<T>(T*);
    264   private:
    265     Foo(T*, bool); // expected-note {{declared private here}}
    266   };
    267 
    268   // Should work.
    269   int globalInt;
    270   Foo<int> f = foo(&globalInt);
    271 
    272   // Shouldn't work.
    273   long globalLong;
    274   template <> Foo<long> foo(long *t) {
    275     Foo<int> s(&globalInt, false); // expected-error {{calling a private constructor}}
    276     return Foo<long>(t, true);
    277   }
    278 }
    279 
    280 // PR6514
    281 namespace test13 {
    282   template <int N, template <int> class Temp>
    283   class Role : public Temp<N> {
    284     friend class Temp<N>;
    285     int x;
    286   };
    287 
    288   template <int N> class Foo {
    289     void foo(Role<N, test13::Foo> &role) {
    290       (void) role.x;
    291     }
    292   };
    293 
    294   template class Foo<0>;
    295 }
    296 
    297 namespace test14 {
    298   template <class T> class B;
    299   template <class T> class A {
    300     friend void B<T>::foo();
    301     static void foo(); // expected-note {{declared private here}}
    302   };
    303 
    304   template <class T> class B {
    305     void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test14::A<long>'}}
    306   };
    307 
    308   template class B<int>; // expected-note {{in instantiation}}
    309 }
    310 
    311 namespace test15 {
    312   template <class T> class B;
    313   template <class T> class A {
    314     friend void B<T>::foo();
    315 
    316     // This shouldn't be misrecognized as a templated-scoped reference.
    317     template <class U> friend void B<T>::bar(U);
    318 
    319     static void foo(); // expected-note {{declared private here}}
    320   };
    321 
    322   template <class T> class B {
    323     void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test15::A<long>'}}
    324   };
    325 
    326   template <> class B<float> {
    327     void foo() { return A<float>::foo(); }
    328     template <class U> void bar(U u) {
    329       (void) A<float>::foo();
    330     }
    331   };
    332 
    333   template class B<int>; // expected-note {{in instantiation}}
    334 }
    335