13573b2c84372d9484296fa658f5276f6c09acb92Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
2398a801c9b914b01c4f6222c8338448314dd6f4fDouglas Gregor
3398a801c9b914b01c4f6222c8338448314dd6f4fDouglas Gregorstruct X {
44fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  template<typename T> T& f0(T);
54fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor
64fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  void g0(int i, double d) {
74fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor    int &ir = f0(i);
84fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor    double &dr = f0(d);
94fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  }
104fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor
114fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  template<typename T> T& f1(T);
124fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  template<typename T, typename U> U& f1(T, U);
134fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor
144fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  void g1(int i, double d) {
154fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor    int &ir1 = f1(i);
164fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor    int &ir2 = f1(d, i);
174fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor    int &ir3 = f1(i, i);
184fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  }
19398a801c9b914b01c4f6222c8338448314dd6f4fDouglas Gregor};
204fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor
214fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregorvoid test_X_f0(X x, int i, float f) {
224fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  int &ir = x.f0(i);
234fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  float &fr = x.f0(f);
244fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor}
254fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor
264fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregorvoid test_X_f1(X x, int i, float f) {
274fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  int &ir1 = x.f1(i);
284fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  int &ir2 = x.f1(f, i);
294fdcdda2862ac8c818184ca593ef43ff11469eacDouglas Gregor  int &ir3 = x.f1(i, i);
30050cabf8b5ba0448c07fca099f3bcfceb1ad77a1Douglas Gregor}
311cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregor
321cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregorvoid test_X_f0_address() {
331cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregor  int& (X::*pm1)(int) = &X::f0;
341cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregor  float& (X::*pm2)(float) = &X::f0;
351cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregor}
361cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregor
371cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregorvoid test_X_f1_address() {
381cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregor  int& (X::*pm1)(int) = &X::f1;
391cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregor  float& (X::*pm2)(float) = &X::f1;
401cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregor  int& (X::*pm3)(float, int) = &X::f1;
411cfe1fadbc3d34e86ed81d415efcb6fb7fe28abcDouglas Gregor}
426ee3505754a995ce47e91de424cab07631a64248Douglas Gregor
43cfa0a63ebe696ba691ffad4963c6945d3d13fa84Douglas Gregorvoid test_X_f0_explicit(X x, int i, long l) {
44cfa0a63ebe696ba691ffad4963c6945d3d13fa84Douglas Gregor  int &ir1 = x.f0<int>(i);
45cfa0a63ebe696ba691ffad4963c6945d3d13fa84Douglas Gregor  int &ir2 = x.f0<>(i);
46d33e328e84080d75879182f882b578ffa7db52abDouglas Gregor  long &il1 = x.f0<long>(i);
47cfa0a63ebe696ba691ffad4963c6945d3d13fa84Douglas Gregor}
48cfa0a63ebe696ba691ffad4963c6945d3d13fa84Douglas Gregor
496ee3505754a995ce47e91de424cab07631a64248Douglas Gregor// PR4608
506ee3505754a995ce47e91de424cab07631a64248Douglas Gregorclass A { template <class x> x a(x z) { return z+y; } int y; };
51681d31d4185cfa8a5378440dee12fc1535e3de99Douglas Gregor
52d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregor// PR5419
53d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregorstruct Functor {
54d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregor  template <typename T>
55d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregor  bool operator()(const T& v) const {
56d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregor    return true;
57d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregor  }
58d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregor};
59d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregor
60d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregorvoid test_Functor(Functor f) {
61d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregor  f(1);
62d301812deb28eae0e81a36cd35ea2823e87a79afDouglas Gregor}
63c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregor
64c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregor// Instantiation on ->
65c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregortemplate<typename T>
66c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregorstruct X1 {
67c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregor  template<typename U> U& get();
68c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregor};
69c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregor
70c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregortemplate<typename T> struct X2; // expected-note{{here}}
71c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregor
72c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregorvoid test_incomplete_access(X1<int> *x1, X2<int> *x2) {
73c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregor  float &fr = x1->get<float>();
74c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregor  (void)x2->get<float>(); // expected-error{{implicit instantiation of undefined template}}
75c7fe2da068df4621ab3fd372b2bcb8fd8def8947Douglas Gregor}
7673ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor
7773ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor// Instantiation of template template parameters in a member function
7873ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor// template.
7973ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregornamespace TTP {
8073ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor  template<int Dim> struct X {
8173ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor    template<template<class> class M, class T> void f(const M<T>&);
8273ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor  };
8373ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor
8473ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor  template<typename T> struct Y { };
8573ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor
8673ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor  void test_f(X<3> x, Y<int> y) { x.f(y); }
8773ad818becb8f8473cfc562ad556e9802cd786beDouglas Gregor}
889951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor
899951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregornamespace PR7387 {
909951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor  template <typename T> struct X {};
919951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor
929951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor  template <typename T1> struct S {
939951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor    template <template <typename> class TC> void foo(const TC<T1>& arg);
949951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor  };
959951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor
969951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor  template <typename T1> template <template <typename> class TC>
979951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor  void S<T1>::foo(const TC<T1>& arg) {}
989951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor
999951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor  void test(const X<int>& x) {
1009951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor    S<int> s;
1019951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor    s.foo(x);
1029951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor  }
1039951415a2b9daf6bfc6711c5f267289764e5a5f9Douglas Gregor}
104