1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
22700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename T>
32700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorvoid call_f0(T x) {
42700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  x.Base::f0();
52700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor}
62700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
72700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorstruct Base {
82700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  void f0();
92700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor};
102700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
112700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorstruct X0 : Base {
122700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  typedef Base CrazyBase;
132700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor};
142700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
152700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorvoid test_f0(X0 x0) {
162700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  call_f0(x0);
172700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor}
182700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
192700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename TheBase, typename T>
202700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorvoid call_f0_through_typedef(T x) {
212700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  typedef TheBase Base2;
222700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  x.Base2::f0();
232700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor}
242700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
252700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorvoid test_f0_through_typedef(X0 x0) {
262700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  call_f0_through_typedef<Base>(x0);
272700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor}
282700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
292700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename TheBase, typename T>
302700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorvoid call_f0_through_typedef2(T x) {
312700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  typedef TheBase CrazyBase; // expected-note{{current scope}}
32c68afe2cbe7f875a9243c411077602fb5f5dc74bDouglas Gregor  x.CrazyBase::f0(); // expected-error{{ambiguous}} \
33c68afe2cbe7f875a9243c411077602fb5f5dc74bDouglas Gregor                     // expected-error 2{{no member named}}
342700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor}
352700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
362700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorstruct OtherBase { };
372700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
382700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorstruct X1 : Base, OtherBase {
392700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  typedef OtherBase CrazyBase; // expected-note{{object type}}
402700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor};
412700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
422700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorvoid test_f0_through_typedef2(X0 x0, X1 x1) {
432700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  call_f0_through_typedef2<Base>(x0);
44c68afe2cbe7f875a9243c411077602fb5f5dc74bDouglas Gregor  call_f0_through_typedef2<OtherBase>(x1); // expected-note{{instantiation}}
45c68afe2cbe7f875a9243c411077602fb5f5dc74bDouglas Gregor  call_f0_through_typedef2<Base>(x1); // expected-note{{instantiation}}
462700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor}
472700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
482700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
4981499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregorstruct X2 {
5081499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregor  operator int() const;
5181499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregor};
5281499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregor
5381499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregortemplate<typename T, typename U>
5481499bbeb2bd157a77b60364676ac434aca7a4dfDouglas GregorT convert(const U& value) {
5581499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregor  return value.operator T(); // expected-error{{operator long}}
5681499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregor}
5781499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregor
5881499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregorvoid test_convert(X2 x2) {
5981499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregor  convert<int>(x2);
6081499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregor  convert<long>(x2); // expected-note{{instantiation}}
6181499bbeb2bd157a77b60364676ac434aca7a4dfDouglas Gregor}
62a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
63a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregortemplate<typename T>
64a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregorvoid destruct(T* ptr) {
65a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  ptr->~T();
66a2e7dd2f4a50d835351153aee568d35ccc986310Douglas Gregor  ptr->T::~T();
67a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor}
68a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
69a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregortemplate<typename T>
70a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregorvoid destruct_intptr(int *ip) {
71a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  ip->~T();
72a2e7dd2f4a50d835351153aee568d35ccc986310Douglas Gregor  ip->T::~T();
73a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor}
74a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor
75a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregorvoid test_destruct(X2 *x2p, int *ip) {
76a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  destruct(x2p);
77a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  destruct(ip);
78a71d819bb8f50c28938db0f2867d3fb6e2ce5910Douglas Gregor  destruct_intptr<int>(ip);
79a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor}
80a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor
81a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor// PR5220
82a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregorclass X3 {
83a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregorprotected:
84a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor  template <int> float* &f0();
85a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor  template <int> const float* &f0() const;
86a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor  void f1() {
87a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor    (void)static_cast<float*>(f0<0>());
88a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor  }
89a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor  void f1() const{
90a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor    (void)f0<0>();
91a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor  }
92a9e29aa4b1e5042a763240899d8b8cf1267c3ec5Douglas Gregor};
93b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor
94b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor// Fun with template instantiation and conversions
95b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregorstruct X4 {
96b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor  int& member();
97b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor  float& member() const;
98b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor};
99b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor
100b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregortemplate<typename T>
101b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregorstruct X5 {
102b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor  void f(T* ptr) { int& ir = ptr->member(); }
103b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor  void g(T* ptr) { float& fr = ptr->member(); }
104b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor};
105b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor
106b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregorvoid test_X5(X5<X4> x5, X5<const X4> x5c, X4 *xp, const X4 *cxp) {
107b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor  x5.f(xp);
108b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor  x5c.g(cxp);
109b1c2ea5dddc9188e2ea30de7f6546f640b85deadDouglas Gregor}
110410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall
111410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall// In theory we can do overload resolution at template-definition time on this.
112410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall// We should at least not assert.
113410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCallnamespace test4 {
114410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall  struct Base {
115410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall    template <class T> void foo() {}
116410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall  };
117410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall
118410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall  template <class T> struct Foo : Base {
119410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall    void test() {
120410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall      foo<int>();
121410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall    }
122410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall  };
123410a3f3c194a541acb5cdf3b98e96d6078685cf2John McCall}
124e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor
125e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregornamespace test5 {
126e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor  template<typename T>
127e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor  struct X {
128e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor    using T::value;
129e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor
130e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor    T &getValue() {
131e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor      return &value;
132e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor    }
133e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor  };
134e2248be8746e0ebb01e9a3b823bc0e129283bef4Douglas Gregor}
13501b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall
13601b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall// PR8739
13701b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCallnamespace test6 {
13801b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall  struct A {};
13901b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall  struct B {};
14001b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall  template <class T> class Base;
14101b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall  template <class T> class Derived : public Base<T> {
14201b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall    A *field;
14301b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall    void get(B **ptr) {
14401b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall      // It's okay if at some point we figure out how to diagnose this
14501b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall      // at instantiation time.
14601b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall      *ptr = field;
14701b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall    }
14801b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall  };
14901b2e4e3e2fbd60e62539f7e8e8b99575fa8a5b0John McCall}
150