1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
23b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregortemplate<typename U, typename T>
33b6afbb99a1c44b4076f8e15fb7311405941b306Douglas GregorU f0(T t) {
43b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor  return t.template get<U>();
53b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor}
63b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor
73b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregortemplate<typename U, typename T>
83b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregorint &f1(T t) {
93b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor  // FIXME: When we pretty-print this, we lose the "template" keyword.
103b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor  return t.U::template get<int&>();
113b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor}
123b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor
133b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregorstruct X {
143b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor  template<typename T> T get();
153b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor};
163b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor
173b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregorvoid test_f0(X x) {
183b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor  int i = f0<int>(x);
193b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor  int &ir = f0<int&>(x);
203b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor}
213b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor
223b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregorstruct XDerived : public X {
233b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor};
243b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor
253b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregorvoid test_f1(XDerived xd) {
266cd219879ffce00920189ec1dcea927a42602961Douglas Gregor  int &ir = f1<X>(xd);
273b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor}
283b6afbb99a1c44b4076f8e15fb7311405941b306Douglas Gregor
29dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor// PR5213
30dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregortemplate <class T>
31dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregorstruct A {};
32dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor
33dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregortemplate<class T>
34dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregorclass B
35dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor{
36dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor  A<T> a_;
37dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor
38dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregorpublic:
39dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor  void destroy();
40dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor};
41dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor
42dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregortemplate<class T>
43dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregorvoid
44dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas GregorB<T>::destroy()
45dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor{
46dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor  a_.~A<T>();
47dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor}
48dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor
49dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregorvoid do_destroy_B(B<int> b) {
50dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor  b.destroy();
51dd62b15665a4144c45c1f7c53665414ad5f7f4f2Douglas Gregor}
523eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor
533eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregorstruct X1 {
543eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  int* f1(int);
553eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  template<typename T> float* f1(T);
563eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor
573eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  static int* f2(int);
583eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  template<typename T> static float* f2(T);
593eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor};
603eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor
613eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregorvoid test_X1(X1 x1) {
623eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float *fp1 = x1.f1<>(17);
63be0ee875d8a91c031a085cbbd73ad9e8dc1aa8ffDavid Blaikie  float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion from 'double' to 'int' changes value from 3.14 to 3}}
643eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  int *ip1 = x1.f1(17);
653eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float *ip2 = x1.f1(3.14);
663eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor
673eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float* (X1::*mf1)(int) = &X1::f1;
683eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float* (X1::*mf2)(int) = &X1::f1<>;
693eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float* (X1::*mf3)(float) = &X1::f1<float>;
703eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor
713eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float* (*fp3)(int) = &X1::f2;
723eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float* (*fp4)(int) = &X1::f2<>;
733eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float* (*fp5)(float) = &X1::f2<float>;
743eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float* (*fp6)(int) = X1::f2;
753eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float* (*fp7)(int) = X1::f2<>;
763eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor  float* (*fp8)(float) = X1::f2<float>;
773eefb1c4bd2c562e43f25e0dba657bb32361dd14Douglas Gregor}
78550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor
79550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregortemplate<int A> struct X2 {
80550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor  int m;
81550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor};
82550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor
83550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregortemplate<typename T>
84550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregorstruct X3 : T { };
85550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor
86550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregortemplate<typename T>
87550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregorstruct X4 {
88550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor  template<typename U>
89550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor  void f(X2<sizeof(X3<U>().U::m)>);
90550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor};
91550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor
92550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregorvoid f(X4<X3<int> > x4i) {
93550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor  X2<sizeof(int)> x2;
94550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor  x4i.f<X2<sizeof(int)> >(x2);
95550d9b28fd586db541eb6dd36f3c10d114e483d8Douglas Gregor}
9643d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregor
9743d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregortemplate<typename T>
9843d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregorstruct X5 {
9943d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregor  template<typename U>
10043d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregor  void f();
10143d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregor
10243d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregor  void g() {
10343d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregor    this->f<T*>();
10443d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregor  }
10543d8863df9d02f81acdf5f73fbc288f285bf442eDouglas Gregor};
1061cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor
1071cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregornamespace PR6021 {
1081cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor  template< class T1, class T2 >
1091cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor  class Outer
1101cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor  {
1111cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor  public: // Range operations
1121cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor    template< class X > X tmpl( const X* = 0 ) const;
1131cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor
1141cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor    struct Inner
1151cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor    {
1161cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor      const Outer& o;
1171cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor
1181cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor      template< class X >
1191cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor      operator X() const
1201cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor      {
1211cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor        return o.tmpl<X>();
1221cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor      }
1231cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor    };
1241cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor  };
1251cfb7da1f34723021f362cb09636965e5ade0c6dDouglas Gregor}
126f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor
127f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregornamespace rdar8198511 {
128f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor  template<int, typename U>
129f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor  struct Base {
130f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor    void f();
131f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor  };
132f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor
133f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor  template<typename T>
134f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor  struct X0 : Base<1, T> { };
135f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor
136f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor  template<typename T>
137f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor  struct X1 {
138f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor    X0<int> x0;
139f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor
140f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor    void f() {
141f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor      this->x0.Base<1, int>::f();
142f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor    }
143f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor  };
144f9f97a0ea15456dca52ba7962e5d8017f996cd4aDouglas Gregor}
145