1// RUN: %clang_cc1 -fsyntax-only -verify %s
2template<typename T>
3class X {
4public:
5  void f(T x); // expected-error{{argument may not have 'void' type}}
6  void g(T*);
7
8  static int h(T, T); // expected-error {{argument may not have 'void' type}}
9};
10
11int identity(int x) { return x; }
12
13void test(X<int> *xi, int *ip, X<int(int)> *xf) {
14  xi->f(17);
15  xi->g(ip);
16  xf->f(&identity);
17  xf->g(identity);
18  X<int>::h(17, 25);
19  X<int(int)>::h(identity, &identity);
20}
21
22void test_bad() {
23  X<void> xv; // expected-note{{in instantiation of template class 'X<void>' requested here}}
24}
25
26template<typename T, typename U>
27class Overloading {
28public:
29  int& f(T, T); // expected-note{{previous declaration is here}}
30  float& f(T, U); // expected-error{{functions that differ only in their return type cannot be overloaded}}
31};
32
33void test_ovl(Overloading<int, long> *oil, int i, long l) {
34  int &ir = oil->f(i, i);
35  float &fr = oil->f(i, l);
36}
37
38void test_ovl_bad() {
39  Overloading<float, float> off; // expected-note{{in instantiation of template class 'Overloading<float, float>' requested here}}
40}
41
42template<typename T>
43class HasDestructor {
44public:
45  virtual ~HasDestructor() = 0;
46};
47
48int i = sizeof(HasDestructor<int>); // FIXME: forces instantiation, but
49                // the code below should probably instantiate by itself.
50int abstract_destructor[__is_abstract(HasDestructor<int>)? 1 : -1];
51
52
53template<typename T>
54class Constructors {
55public:
56  Constructors(const T&);
57  Constructors(const Constructors &other);
58};
59
60void test_constructors() {
61  Constructors<int> ci1(17);
62  Constructors<int> ci2 = ci1;
63}
64
65
66template<typename T>
67struct ConvertsTo {
68  operator T();
69};
70
71void test_converts_to(ConvertsTo<int> ci, ConvertsTo<int *> cip) {
72  int i = ci;
73  int *ip = cip;
74}
75
76// PR4660
77template<class T> struct A0 { operator T*(); };
78template<class T> struct A1;
79
80int *a(A0<int> &x0, A1<int> &x1) {
81  int *y0 = x0;
82  int *y1 = x1; // expected-error{{no viable conversion}}
83}
84
85struct X0Base {
86  int &f();
87  int& g(int);
88  static double &g(double);
89};
90
91template<typename T>
92struct X0 : X0Base {
93};
94
95template<typename U>
96struct X1 : X0<U> {
97  int &f2() {
98    return X0Base::f();
99  }
100};
101
102void test_X1(X1<int> x1i) {
103  int &ir = x1i.f2();
104}
105
106template<typename U>
107struct X2 : X0Base, U {
108  int &f2() { return X0Base::f(); }
109};
110
111template<typename T>
112struct X3 {
113  void test(T x) {
114    double& d1 = X0Base::g(x);
115  }
116};
117
118
119template struct X3<double>;
120
121// Don't try to instantiate this, it's invalid.
122namespace test1 {
123  template <class T> class A {};
124  template <class T> class B {
125    void foo(A<test1::Undeclared> &a) // expected-error {{no member named 'Undeclared' in namespace 'test1'}}
126    {}
127  };
128  template class B<int>;
129}
130
131namespace PR6947 {
132  template< class T >
133  struct X {
134    int f0( )
135    {
136      typedef void ( X::*impl_fun_ptr )( );
137      impl_fun_ptr pImpl = &X::template
138        f0_impl1<int>;
139    }
140  private:
141    int f1() {
142    }
143    template< class Processor>
144    void f0_impl1( )
145    {
146    }
147  };
148
149  char g0() {
150    X<int> pc;
151    pc.f0();
152  }
153
154}
155
156namespace PR7022 {
157  template <typename >
158  struct X1
159  {
160    typedef int state_t( );
161    state_t g ;
162  };
163
164  template <  typename U = X1<int> > struct X2
165  {
166    X2( U = U())
167    {
168    }
169  };
170
171  void m(void)
172  {
173    typedef X2<> X2_type;
174    X2_type c;
175  }
176
177}
178