1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li
3*67e74705SXin Li struct X {
4*67e74705SXin Li template<typename T> T& f0(T);
5*67e74705SXin Li
g0X6*67e74705SXin Li void g0(int i, double d) {
7*67e74705SXin Li int &ir = f0(i);
8*67e74705SXin Li double &dr = f0(d);
9*67e74705SXin Li }
10*67e74705SXin Li
11*67e74705SXin Li template<typename T> T& f1(T);
12*67e74705SXin Li template<typename T, typename U> U& f1(T, U);
13*67e74705SXin Li
g1X14*67e74705SXin Li void g1(int i, double d) {
15*67e74705SXin Li int &ir1 = f1(i);
16*67e74705SXin Li int &ir2 = f1(d, i);
17*67e74705SXin Li int &ir3 = f1(i, i);
18*67e74705SXin Li }
19*67e74705SXin Li };
20*67e74705SXin Li
test_X_f0(X x,int i,float f)21*67e74705SXin Li void test_X_f0(X x, int i, float f) {
22*67e74705SXin Li int &ir = x.f0(i);
23*67e74705SXin Li float &fr = x.f0(f);
24*67e74705SXin Li }
25*67e74705SXin Li
test_X_f1(X x,int i,float f)26*67e74705SXin Li void test_X_f1(X x, int i, float f) {
27*67e74705SXin Li int &ir1 = x.f1(i);
28*67e74705SXin Li int &ir2 = x.f1(f, i);
29*67e74705SXin Li int &ir3 = x.f1(i, i);
30*67e74705SXin Li }
31*67e74705SXin Li
test_X_f0_address()32*67e74705SXin Li void test_X_f0_address() {
33*67e74705SXin Li int& (X::*pm1)(int) = &X::f0;
34*67e74705SXin Li float& (X::*pm2)(float) = &X::f0;
35*67e74705SXin Li }
36*67e74705SXin Li
test_X_f1_address()37*67e74705SXin Li void test_X_f1_address() {
38*67e74705SXin Li int& (X::*pm1)(int) = &X::f1;
39*67e74705SXin Li float& (X::*pm2)(float) = &X::f1;
40*67e74705SXin Li int& (X::*pm3)(float, int) = &X::f1;
41*67e74705SXin Li }
42*67e74705SXin Li
test_X_f0_explicit(X x,int i,long l)43*67e74705SXin Li void test_X_f0_explicit(X x, int i, long l) {
44*67e74705SXin Li int &ir1 = x.f0<int>(i);
45*67e74705SXin Li int &ir2 = x.f0<>(i);
46*67e74705SXin Li long &il1 = x.f0<long>(i);
47*67e74705SXin Li }
48*67e74705SXin Li
49*67e74705SXin Li // PR4608
a(x z)50*67e74705SXin Li class A { template <class x> x a(x z) { return z+y; } int y; };
51*67e74705SXin Li
52*67e74705SXin Li // PR5419
53*67e74705SXin Li struct Functor {
54*67e74705SXin Li template <typename T>
operator ()Functor55*67e74705SXin Li bool operator()(const T& v) const {
56*67e74705SXin Li return true;
57*67e74705SXin Li }
58*67e74705SXin Li };
59*67e74705SXin Li
test_Functor(Functor f)60*67e74705SXin Li void test_Functor(Functor f) {
61*67e74705SXin Li f(1);
62*67e74705SXin Li }
63*67e74705SXin Li
64*67e74705SXin Li // Instantiation on ->
65*67e74705SXin Li template<typename T>
66*67e74705SXin Li struct X1 {
67*67e74705SXin Li template<typename U> U& get();
68*67e74705SXin Li };
69*67e74705SXin Li
70*67e74705SXin Li template<typename T> struct X2; // expected-note{{here}}
71*67e74705SXin Li
test_incomplete_access(X1<int> * x1,X2<int> * x2)72*67e74705SXin Li void test_incomplete_access(X1<int> *x1, X2<int> *x2) {
73*67e74705SXin Li float &fr = x1->get<float>();
74*67e74705SXin Li (void)x2->get<float>(); // expected-error{{implicit instantiation of undefined template}}
75*67e74705SXin Li }
76*67e74705SXin Li
77*67e74705SXin Li // Instantiation of template template parameters in a member function
78*67e74705SXin Li // template.
79*67e74705SXin Li namespace TTP {
80*67e74705SXin Li template<int Dim> struct X {
81*67e74705SXin Li template<template<class> class M, class T> void f(const M<T>&);
82*67e74705SXin Li };
83*67e74705SXin Li
84*67e74705SXin Li template<typename T> struct Y { };
85*67e74705SXin Li
test_f(X<3> x,Y<int> y)86*67e74705SXin Li void test_f(X<3> x, Y<int> y) { x.f(y); }
87*67e74705SXin Li }
88*67e74705SXin Li
89*67e74705SXin Li namespace PR7387 {
90*67e74705SXin Li template <typename T> struct X {};
91*67e74705SXin Li
92*67e74705SXin Li template <typename T1> struct S {
93*67e74705SXin Li template <template <typename> class TC> void foo(const TC<T1>& arg);
94*67e74705SXin Li };
95*67e74705SXin Li
96*67e74705SXin Li template <typename T1> template <template <typename> class TC>
foo(const TC<T1> & arg)97*67e74705SXin Li void S<T1>::foo(const TC<T1>& arg) {}
98*67e74705SXin Li
test(const X<int> & x)99*67e74705SXin Li void test(const X<int>& x) {
100*67e74705SXin Li S<int> s;
101*67e74705SXin Li s.foo(x);
102*67e74705SXin Li }
103*67e74705SXin Li }
104