summaryrefslogtreecommitdiff
path: root/test/SemaTemplate/instantiate-method.cpp
blob: 58cb8979555894a995d7bf42709ea99abdab6ba4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// RUN: %clang_cc1 -fsyntax-only -verify %s
template<typename T>
class X {
public:
  void f(T x); // expected-error{{argument may not have 'void' type}}
  void g(T*);

  static int h(T, T); // expected-error {{argument may not have 'void' type}}
};

int identity(int x) { return x; }

void test(X<int> *xi, int *ip, X<int(int)> *xf) {
  xi->f(17);
  xi->g(ip);
  xf->f(&identity);
  xf->g(identity);
  X<int>::h(17, 25);
  X<int(int)>::h(identity, &identity);
}

void test_bad() {
  X<void> xv; // expected-note{{in instantiation of template class 'X<void>' requested here}}
}

template<typename T, typename U>
class Overloading {
public:
  int& f(T, T); // expected-note{{previous declaration is here}}
  float& f(T, U); // expected-error{{functions that differ only in their return type cannot be overloaded}}
};

void test_ovl(Overloading<int, long> *oil, int i, long l) {
  int &ir = oil->f(i, i);
  float &fr = oil->f(i, l);
}

void test_ovl_bad() {
  Overloading<float, float> off; // expected-note{{in instantiation of template class 'Overloading<float, float>' requested here}}
}

template<typename T>
class HasDestructor {
public:
  virtual ~HasDestructor() = 0;
};

int i = sizeof(HasDestructor<int>); // FIXME: forces instantiation, but 
                // the code below should probably instantiate by itself.
int abstract_destructor[__is_abstract(HasDestructor<int>)? 1 : -1];


template<typename T>
class Constructors {
public:
  Constructors(const T&);
  Constructors(const Constructors &other);
};

void test_constructors() {
  Constructors<int> ci1(17);
  Constructors<int> ci2 = ci1;
}


template<typename T>
struct ConvertsTo {
  operator T();
};

void test_converts_to(ConvertsTo<int> ci, ConvertsTo<int *> cip) {
  int i = ci;
  int *ip = cip;
}

// PR4660
template<class T> struct A0 { operator T*(); };
template<class T> struct A1;

int *a(A0<int> &x0, A1<int> &x1) {
  int *y0 = x0;
  int *y1 = x1; // expected-error{{no viable conversion}}
}

struct X0Base {
  int &f();
  int& g(int);
  static double &g(double);
};

template<typename T>
struct X0 : X0Base {
};

template<typename U>
struct X1 : X0<U> {
  int &f2() { 
    return X0Base::f();
  }
};

void test_X1(X1<int> x1i) {
  int &ir = x1i.f2();
}

template<typename U>
struct X2 : X0Base, U {
  int &f2() { return X0Base::f(); }
};

template<typename T>
struct X3 {
  void test(T x) {
    double& d1 = X0Base::g(x);
  }
};


template struct X3<double>;

// Don't try to instantiate this, it's invalid.
namespace test1 {
  template <class T> class A {};
  template <class T> class B {
    void foo(A<test1::Undeclared> &a) // expected-error {{no member named 'Undeclared' in namespace 'test1'}}
    {}
  };
  template class B<int>;
}

namespace PR6947 {
  template< class T > 
  struct X {
    int f0( )      
    {
      typedef void ( X::*impl_fun_ptr )( );
      impl_fun_ptr pImpl = &X::template
        f0_impl1<int>;
    }
  private:                  
    int f1() {
    }
    template< class Processor>                  
    void f0_impl1( )                 
    {
    }
  };

  char g0() {
    X<int> pc;
    pc.f0();
  }

}

namespace PR7022 {
  template <typename > 
  struct X1
  {
    typedef int state_t( );
    state_t g ;
  };

  template <  typename U = X1<int> > struct X2
  {
    X2( U = U())
    {
    }
  };

  void m(void)
  {
    typedef X2<> X2_type;
    X2_type c;
  }
}

namespace SameSignatureAfterInstantiation {
  template<typename T> struct S {
    void f(T *); // expected-note {{previous}}
    void f(const T*); // expected-error-re {{multiple overloads of 'f' instantiate to the same signature 'void (const int *){{( __attribute__\(\(thiscall\)\))?}}'}}
  };
  S<const int> s; // expected-note {{instantiation}}
}