17002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall// RUN: %clang_cc1 -verify -emit-llvm-only %s
29c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall
39c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCallnamespace test0 {
402cace78cf48cc26686bd5b07c78606abca13bcdJohn McCalltemplate <typename T> struct Num {
5fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall  T value_;
6fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall
7fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCallpublic:
8fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall  Num(T value) : value_(value) {}
9fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall  T get() const { return value_; }
1002cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall
1102cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall  template <typename U> struct Rep {
1202cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall    U count_;
1302cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall    Rep(U count) : count_(count) {}
1402cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall
1502cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall    friend Num operator*(const Num &a, const Rep &n) {
1602cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall      Num x = 0;
1702cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall      for (U count = n.count_; count; --count)
1802cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall        x += a;
1902cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall      return x;
2002cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall    }
2102cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall  };
2202cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall
23fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall  friend Num operator+(const Num &a, const Num &b) {
24fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall    return a.value_ + b.value_;
25fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall  }
2602cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall
2702cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall  Num& operator+=(const Num& b) {
2802cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall    value_ += b.value_;
2902cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall    return *this;
3002cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall  }
3182b9fb8e7a05066e690670d2eb386a624b04f684John McCall
3282b9fb8e7a05066e690670d2eb386a624b04f684John McCall  class Representation {};
3382b9fb8e7a05066e690670d2eb386a624b04f684John McCall  friend class Representation;
34fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall};
35fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall
361a26c27eba32f8766c0eeec73fe43634cd814825John McCallclass A {
371a26c27eba32f8766c0eeec73fe43634cd814825John McCall  template <typename T> friend bool iszero(const A &a) throw();
381a26c27eba32f8766c0eeec73fe43634cd814825John McCall};
391a26c27eba32f8766c0eeec73fe43634cd814825John McCall
406b2becfc434b0bdced8560802c4d0e03148c61b8John McCalltemplate <class T> class B_iterator;
416b2becfc434b0bdced8560802c4d0e03148c61b8John McCalltemplate <class T> class B {
426b2becfc434b0bdced8560802c4d0e03148c61b8John McCall  friend class B_iterator<T>;
436b2becfc434b0bdced8560802c4d0e03148c61b8John McCall};
446b2becfc434b0bdced8560802c4d0e03148c61b8John McCall
4502cace78cf48cc26686bd5b07c78606abca13bcdJohn McCallint calc1() {
46fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall  Num<int> left = -1;
47fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall  Num<int> right = 1;
48fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall  Num<int> result = left + right;
49fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall  return result.get();
50fd810b1386ed29b250e7d522ea826a65c815e49dJohn McCall}
5102cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall
5202cace78cf48cc26686bd5b07c78606abca13bcdJohn McCallint calc2() {
5302cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall  Num<int> x = 3;
542a29c4b6ef710de49b1fd72902d6930033edae24John McCall  Num<int>::Rep<char> n = (char) 10;
5502cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall  Num<int> result = x * n;
5602cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall  return result.get();
5702cace78cf48cc26686bd5b07c78606abca13bcdJohn McCall}
589c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall}
59a742db0032d8f458fe229600d2082981a1fb1481John McCall
60a742db0032d8f458fe229600d2082981a1fb1481John McCall// Reduced from GNU <locale>
61a742db0032d8f458fe229600d2082981a1fb1481John McCallnamespace test1 {
62a742db0032d8f458fe229600d2082981a1fb1481John McCall  class A {
63a742db0032d8f458fe229600d2082981a1fb1481John McCall    bool b; // expected-note {{declared private here}}
64a742db0032d8f458fe229600d2082981a1fb1481John McCall    template <typename T> friend bool has(const A&);
65a742db0032d8f458fe229600d2082981a1fb1481John McCall  };
66a742db0032d8f458fe229600d2082981a1fb1481John McCall  template <typename T> bool has(const A &x) {
67a742db0032d8f458fe229600d2082981a1fb1481John McCall    return x.b;
68a742db0032d8f458fe229600d2082981a1fb1481John McCall  }
69a742db0032d8f458fe229600d2082981a1fb1481John McCall  template <typename T> bool hasnot(const A &x) {
70a742db0032d8f458fe229600d2082981a1fb1481John McCall    return x.b; // expected-error {{'b' is a private member of 'test1::A'}}
71a742db0032d8f458fe229600d2082981a1fb1481John McCall  }
72a742db0032d8f458fe229600d2082981a1fb1481John McCall}
73a742db0032d8f458fe229600d2082981a1fb1481John McCall
74a742db0032d8f458fe229600d2082981a1fb1481John McCallnamespace test2 {
75a742db0032d8f458fe229600d2082981a1fb1481John McCall  class A {
76a742db0032d8f458fe229600d2082981a1fb1481John McCall    bool b; // expected-note {{declared private here}}
77a742db0032d8f458fe229600d2082981a1fb1481John McCall    template <typename T> friend class HasChecker;
78a742db0032d8f458fe229600d2082981a1fb1481John McCall  };
79a742db0032d8f458fe229600d2082981a1fb1481John McCall  template <typename T> class HasChecker {
80a742db0032d8f458fe229600d2082981a1fb1481John McCall    bool check(A *a) {
81a742db0032d8f458fe229600d2082981a1fb1481John McCall      return a->b;
82a742db0032d8f458fe229600d2082981a1fb1481John McCall    }
83a742db0032d8f458fe229600d2082981a1fb1481John McCall  };
84a742db0032d8f458fe229600d2082981a1fb1481John McCall  template <typename T> class HasNotChecker {
85a742db0032d8f458fe229600d2082981a1fb1481John McCall    bool check(A *a) {
86a742db0032d8f458fe229600d2082981a1fb1481John McCall      return a->b; // expected-error {{'b' is a private member of 'test2::A'}}
87a742db0032d8f458fe229600d2082981a1fb1481John McCall    }
88a742db0032d8f458fe229600d2082981a1fb1481John McCall  };
89a742db0032d8f458fe229600d2082981a1fb1481John McCall}
900c01d18094100db92d38daa923c95661512db203John McCall
910c01d18094100db92d38daa923c95661512db203John McCallnamespace test3 {
920c01d18094100db92d38daa923c95661512db203John McCall  class Bool;
930c01d18094100db92d38daa923c95661512db203John McCall  template <class T> class User;
940c01d18094100db92d38daa923c95661512db203John McCall  template <class T> T transform(class Bool, T);
950c01d18094100db92d38daa923c95661512db203John McCall
960c01d18094100db92d38daa923c95661512db203John McCall  class Bool {
970c01d18094100db92d38daa923c95661512db203John McCall    friend class User<bool>;
980c01d18094100db92d38daa923c95661512db203John McCall    friend bool transform<>(Bool, bool);
990c01d18094100db92d38daa923c95661512db203John McCall
1007ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall    bool value; // expected-note 2 {{declared private here}}
1010c01d18094100db92d38daa923c95661512db203John McCall  };
1020c01d18094100db92d38daa923c95661512db203John McCall
1030c01d18094100db92d38daa923c95661512db203John McCall  template <class T> class User {
1040c01d18094100db92d38daa923c95661512db203John McCall    static T compute(Bool b) {
1050c01d18094100db92d38daa923c95661512db203John McCall      return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}}
1060c01d18094100db92d38daa923c95661512db203John McCall    }
1070c01d18094100db92d38daa923c95661512db203John McCall  };
1080c01d18094100db92d38daa923c95661512db203John McCall
1090c01d18094100db92d38daa923c95661512db203John McCall  template <class T> T transform(Bool b, T value) {
1107ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall    if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}}
1110c01d18094100db92d38daa923c95661512db203John McCall      return value;
1120c01d18094100db92d38daa923c95661512db203John McCall    return value + 1;
1130c01d18094100db92d38daa923c95661512db203John McCall  }
1140c01d18094100db92d38daa923c95661512db203John McCall
1150c01d18094100db92d38daa923c95661512db203John McCall  template bool transform(Bool, bool);
1167ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9John McCall  template int transform(Bool, int); // expected-note {{requested here}}
1170c01d18094100db92d38daa923c95661512db203John McCall
1180c01d18094100db92d38daa923c95661512db203John McCall  template class User<bool>;
1190c01d18094100db92d38daa923c95661512db203John McCall  template class User<int>; // expected-note {{requested here}}
12093ba8579c341d5329175f1413cdc3b35a36592d2John McCall}
12193ba8579c341d5329175f1413cdc3b35a36592d2John McCall
12293ba8579c341d5329175f1413cdc3b35a36592d2John McCallnamespace test4 {
12393ba8579c341d5329175f1413cdc3b35a36592d2John McCall  template <class T> class A {
12493ba8579c341d5329175f1413cdc3b35a36592d2John McCall    template <class T0> friend class B;
12593ba8579c341d5329175f1413cdc3b35a36592d2John McCall    bool foo(const A<T> *) const;
12693ba8579c341d5329175f1413cdc3b35a36592d2John McCall  };
1270c01d18094100db92d38daa923c95661512db203John McCall
12893ba8579c341d5329175f1413cdc3b35a36592d2John McCall  template <class T> class B {
12993ba8579c341d5329175f1413cdc3b35a36592d2John McCall    bool bar(const A<T> *a, const A<T> *b) {
13093ba8579c341d5329175f1413cdc3b35a36592d2John McCall      return a->foo(b);
13193ba8579c341d5329175f1413cdc3b35a36592d2John McCall    }
13293ba8579c341d5329175f1413cdc3b35a36592d2John McCall  };
13393ba8579c341d5329175f1413cdc3b35a36592d2John McCall
13493ba8579c341d5329175f1413cdc3b35a36592d2John McCall  template class B<int>;
13593ba8579c341d5329175f1413cdc3b35a36592d2John McCall}
13693ba8579c341d5329175f1413cdc3b35a36592d2John McCall
13793ba8579c341d5329175f1413cdc3b35a36592d2John McCallnamespace test5 {
13893ba8579c341d5329175f1413cdc3b35a36592d2John McCall  template <class T, class U=int> class A {};
13993ba8579c341d5329175f1413cdc3b35a36592d2John McCall  template <class T> class B {
14093ba8579c341d5329175f1413cdc3b35a36592d2John McCall    template <class X, class Y> friend class A;
14193ba8579c341d5329175f1413cdc3b35a36592d2John McCall  };
14293ba8579c341d5329175f1413cdc3b35a36592d2John McCall  template class B<int>;
14393ba8579c341d5329175f1413cdc3b35a36592d2John McCall  template class A<int>;
1440c01d18094100db92d38daa923c95661512db203John McCall}
145036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor
146036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregornamespace Dependent {
147036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor  template<typename T, typename Traits> class X;
148036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor  template<typename T, typename Traits>
149036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor  X<T, Traits> operator+(const X<T, Traits>&, const T*);
150036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor
151036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor  template<typename T, typename Traits> class X {
152036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor    typedef typename Traits::value_type value_type;
153036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor    friend X operator+<>(const X&, const value_type*);
154036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor  };
155036ada215d2c53e6a286b42d7cbd2386b0007516Douglas Gregor}
1569c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall
1579c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCallnamespace test7 {
1580d6b1640eb4d1a4a0203235cfdfcdaf3335af36dJohn McCall  template <class T> class A { // expected-note {{declared here}}
1599c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall    friend class B;
1609c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall    int x; // expected-note {{declared private here}}
1619c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall  };
1629c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall
1639c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall  class B {
1649c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall    int foo(A<int> &a) {
1659c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall      return a.x;
1669c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall    }
1679c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall  };
1689c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall
1699c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall  class C {
1709c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall    int foo(A<int> &a) {
1719c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall      return a.x; // expected-error {{'x' is a private member of 'test7::A<int>'}}
1729c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall    }
1739c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall  };
1749c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall
1759c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall  // This shouldn't crash.
1769c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall  template <class T> class D {
1770d6b1640eb4d1a4a0203235cfdfcdaf3335af36dJohn McCall    friend class A; // expected-error {{elaborated type refers to a template}}
1789c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall  };
1799c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall  template class D<int>;
1809c86b513cb42ea6d9e3f98cb2b7eda39a2eb526bJohn McCall}
181d325daa506338ab86f9dd468b48fd010673f49a6John McCall
182d325daa506338ab86f9dd468b48fd010673f49a6John McCallnamespace test8 {
183d325daa506338ab86f9dd468b48fd010673f49a6John McCall  template <class N> class A {
184d325daa506338ab86f9dd468b48fd010673f49a6John McCall    static int x;
185d325daa506338ab86f9dd468b48fd010673f49a6John McCall    template <class T> friend void foo();
186d325daa506338ab86f9dd468b48fd010673f49a6John McCall  };
187d325daa506338ab86f9dd468b48fd010673f49a6John McCall  template class A<int>;
188d325daa506338ab86f9dd468b48fd010673f49a6John McCall
189d325daa506338ab86f9dd468b48fd010673f49a6John McCall  template <class T> void foo() {
190d325daa506338ab86f9dd468b48fd010673f49a6John McCall    A<int>::x = 0;
191d325daa506338ab86f9dd468b48fd010673f49a6John McCall  }
192d325daa506338ab86f9dd468b48fd010673f49a6John McCall  template void foo<int>();
193d325daa506338ab86f9dd468b48fd010673f49a6John McCall}
194b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall
195b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCallnamespace test9 {
196b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall  template <class T> class A {
197b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall    class B; class C;
198b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall
199b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall    int foo(B *b) {
200b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall      return b->x;
201b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall    }
202b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall
203b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall    int foo(C *c) {
204b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall      return c->x; // expected-error {{'x' is a private member}}
205b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall    }
206b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall
207b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall    class B {
208b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall      int x;
209b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall      friend int A::foo(B*);
210b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall    };
211b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall
212b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall    class C {
213b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall      int x; // expected-note {{declared private here}}
214b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall    };
215b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall  };
216b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall
217b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall  template class A<int>; // expected-note {{in instantiation}}
218b0cb022daec8671406ab25f4b5d5a6d48d823bc4John McCall}
219af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
220af2094e7cecadf36667deb61a83587ffdd979bd3John McCallnamespace test10 {
221af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  template <class T> class A;
222af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  template <class T> A<T> bar(const T*, const A<T>&);
223af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  template <class T> class A {
224af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  private:
225af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    void foo(); // expected-note {{declared private here}}
226af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    friend A bar<>(const T*, const A<T>&);
227af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  };
228af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
229af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  template <class T> A<T> bar(const T *l, const A<T> &r) {
230af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    A<T> l1;
231af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    l1.foo();
232af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
233af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    A<char> l2;
234af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    l2.foo(); // expected-error {{'foo' is a private member of 'test10::A<char>'}}
235af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
236af2094e7cecadf36667deb61a83587ffdd979bd3John McCall    return l1;
237af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  }
238af2094e7cecadf36667deb61a83587ffdd979bd3John McCall
239af2094e7cecadf36667deb61a83587ffdd979bd3John McCall  template A<int> bar<int>(const int *, const A<int> &); // expected-note {{in instantiation}}
240af2094e7cecadf36667deb61a83587ffdd979bd3John McCall}
241ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall
242ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall// PR6752: this shouldn't crash.
243ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCallnamespace test11 {
244ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall  struct Foo {
245ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall    template<class A>
246ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall    struct IteratorImpl {
247ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall      template<class T> friend class IteratorImpl;
248ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall    };
249ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall  };
250ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall
251ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall  template struct Foo::IteratorImpl<int>;
252ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall  template struct Foo::IteratorImpl<long>;
253ea7390c7b384ce607bfc8fc13c01f37cfc3776f0John McCall}
25421c0160959961b3a6ab3308608ee3fde182ecb49John McCall
25521c0160959961b3a6ab3308608ee3fde182ecb49John McCall// PR6827
25621c0160959961b3a6ab3308608ee3fde182ecb49John McCallnamespace test12 {
25721c0160959961b3a6ab3308608ee3fde182ecb49John McCall  template <typename T> class Foo;
25821c0160959961b3a6ab3308608ee3fde182ecb49John McCall  template <typename T> Foo<T> foo(T* t){ return Foo<T>(t, true); }
25921c0160959961b3a6ab3308608ee3fde182ecb49John McCall
26021c0160959961b3a6ab3308608ee3fde182ecb49John McCall  template <typename T> class Foo {
26121c0160959961b3a6ab3308608ee3fde182ecb49John McCall  public:
26221c0160959961b3a6ab3308608ee3fde182ecb49John McCall    Foo(T*);
26321c0160959961b3a6ab3308608ee3fde182ecb49John McCall    friend Foo<T> foo<T>(T*);
26421c0160959961b3a6ab3308608ee3fde182ecb49John McCall  private:
26521c0160959961b3a6ab3308608ee3fde182ecb49John McCall    Foo(T*, bool); // expected-note {{declared private here}}
26621c0160959961b3a6ab3308608ee3fde182ecb49John McCall  };
26721c0160959961b3a6ab3308608ee3fde182ecb49John McCall
26821c0160959961b3a6ab3308608ee3fde182ecb49John McCall  // Should work.
26921c0160959961b3a6ab3308608ee3fde182ecb49John McCall  int globalInt;
27021c0160959961b3a6ab3308608ee3fde182ecb49John McCall  Foo<int> f = foo(&globalInt);
27121c0160959961b3a6ab3308608ee3fde182ecb49John McCall
27221c0160959961b3a6ab3308608ee3fde182ecb49John McCall  // Shouldn't work.
27321c0160959961b3a6ab3308608ee3fde182ecb49John McCall  long globalLong;
27421c0160959961b3a6ab3308608ee3fde182ecb49John McCall  template <> Foo<long> foo(long *t) {
27521c0160959961b3a6ab3308608ee3fde182ecb49John McCall    Foo<int> s(&globalInt, false); // expected-error {{calling a private constructor}}
27621c0160959961b3a6ab3308608ee3fde182ecb49John McCall    return Foo<long>(t, true);
27721c0160959961b3a6ab3308608ee3fde182ecb49John McCall  }
27821c0160959961b3a6ab3308608ee3fde182ecb49John McCall}
27974256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
28074256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall// PR6514
28174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCallnamespace test13 {
28274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall  template <int N, template <int> class Temp>
28374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall  class Role : public Temp<N> {
28474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    friend class Temp<N>;
28574256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    int x;
28674256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall  };
28774256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
28874256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall  template <int N> class Foo {
28974256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    void foo(Role<N, test13::Foo> &role) {
29074256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall      (void) role.x;
29174256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall    }
29274256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall  };
29374256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall
29474256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall  template class Foo<0>;
29574256f5ea6950c9fd34595aa124eb4740372f15cJohn McCall}
296c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall
297c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCallnamespace test14 {
298c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall  template <class T> class B;
299c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall  template <class T> class A {
300c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall    friend void B<T>::foo();
301c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall    static void foo(); // expected-note {{declared private here}}
302c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall  };
303c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall
304c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall  template <class T> class B {
3051f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  public:
306c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall    void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test14::A<long>'}}
307c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall  };
308c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall
309c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall  template class B<int>; // expected-note {{in instantiation}}
310c54d688c604d28dcb9ab8f92047837c10c8f9c61John McCall}
3114e2cbb28baa0342b51336e55c519cd06308c4df2John McCall
3124e2cbb28baa0342b51336e55c519cd06308c4df2John McCallnamespace test15 {
3134e2cbb28baa0342b51336e55c519cd06308c4df2John McCall  template <class T> class B;
3144e2cbb28baa0342b51336e55c519cd06308c4df2John McCall  template <class T> class A {
3154e2cbb28baa0342b51336e55c519cd06308c4df2John McCall    friend void B<T>::foo();
3164e2cbb28baa0342b51336e55c519cd06308c4df2John McCall
3174e2cbb28baa0342b51336e55c519cd06308c4df2John McCall    // This shouldn't be misrecognized as a templated-scoped reference.
3184e2cbb28baa0342b51336e55c519cd06308c4df2John McCall    template <class U> friend void B<T>::bar(U);
3194e2cbb28baa0342b51336e55c519cd06308c4df2John McCall
3204e2cbb28baa0342b51336e55c519cd06308c4df2John McCall    static void foo(); // expected-note {{declared private here}}
3214e2cbb28baa0342b51336e55c519cd06308c4df2John McCall  };
3224e2cbb28baa0342b51336e55c519cd06308c4df2John McCall
3234e2cbb28baa0342b51336e55c519cd06308c4df2John McCall  template <class T> class B {
3241f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  public:
3254e2cbb28baa0342b51336e55c519cd06308c4df2John McCall    void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test15::A<long>'}}
3264e2cbb28baa0342b51336e55c519cd06308c4df2John McCall  };
3274e2cbb28baa0342b51336e55c519cd06308c4df2John McCall
3284e2cbb28baa0342b51336e55c519cd06308c4df2John McCall  template <> class B<float> {
3291f2e1a96bec2ba6418ae7f2d2b525a3575203b6aJohn McCall  public:
3304e2cbb28baa0342b51336e55c519cd06308c4df2John McCall    void foo() { return A<float>::foo(); }
3314e2cbb28baa0342b51336e55c519cd06308c4df2John McCall    template <class U> void bar(U u) {
3324e2cbb28baa0342b51336e55c519cd06308c4df2John McCall      (void) A<float>::foo();
3334e2cbb28baa0342b51336e55c519cd06308c4df2John McCall    }
3344e2cbb28baa0342b51336e55c519cd06308c4df2John McCall  };
3354e2cbb28baa0342b51336e55c519cd06308c4df2John McCall
3364e2cbb28baa0342b51336e55c519cd06308c4df2John McCall  template class B<int>; // expected-note {{in instantiation}}
3374e2cbb28baa0342b51336e55c519cd06308c4df2John McCall}
33833ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor
33933ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregornamespace PR10913 {
34033ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  template<class T> class X;
34133ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor
34233ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  template<class T> void f(X<T> *x) {
34333ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor    x->member = 0;
34433ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  }
34533ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor
34633ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  template<class U, class T> void f2(X<T> *x) {
34733ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor    x->member = 0; // expected-error{{'member' is a protected member of 'PR10913::X<int>'}}
34833ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  }
34933ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor
35033ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  template<class T> class X {
35133ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor    friend void f<T>(X<T> *x);
35233ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor    friend void f2<T>(X<int> *x);
35333ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor
35433ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  protected:
35533ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor    int member; // expected-note{{declared protected here}}
35633ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  };
35733ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor
35833ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  template void f(X<int> *);
35933ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  template void f2<int>(X<int> *);
36033ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor  template void f2<float>(X<int> *); // expected-note{{in instantiation of function template specialization 'PR10913::f2<float, int>' requested here}}
36133ab0da4b50c0868f0dbbbbb8d018b44acd2bd4dDouglas Gregor}
362