Clang Project

clang_source_code/test/SemaTemplate/explicit-instantiation.cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions -fcxx-exceptions %s
2// RUN: %clang_cc1 -fsyntax-only -verify -fexceptions -fcxx-exceptions -std=c++11 %s
3
4template void *; // expected-error{{expected unqualified-id}}
5
6template typedef void f0; // expected-error{{explicit instantiation of typedef}}
7
8int v0; // expected-note{{refers here}}
9template int v0; // expected-error{{does not refer}}
10
11template<typename T>
12struct X0 {
13  static T value;
14  
15  T f0(T x) {
16    return x + 1;  // expected-error{{invalid operands}}
17  }
18  T *f0(T *, T *) { return T(); } // expected-warning 0-1 {{expression which evaluates to zero treated as a null pointer constant of type 'int *'}} expected-error 0-1 {{cannot initialize return object of type 'int *' with an rvalue of type 'int'}}
19
20  template <typename U> T f0(T, U) { return T(); } // expected-note-re {{candidate template ignored: could not match 'int (int, U){{( __attribute__\(\(thiscall\)\))?}}' against 'int (int){{( __attribute__\(\(thiscall\)\))?}} const'}} \
21                                                   // expected-note {{candidate template ignored: could not match 'int' against 'int *'}}
22};
23
24template<typename T>
25T X0<T>::value; // expected-error{{no matching constructor}}
26
27template int X0<int>::value;
28
29struct NotDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor)}} expected-note 0-1 {{candidate constructor (the implicit move constructor)}}
30  NotDefaultConstructible(int); // expected-note{{candidate constructor}}
31};
32
33template NotDefaultConstructible X0<NotDefaultConstructible>::value; // expected-note{{instantiation}}
34
35template int X0<int>::f0(int);
36template int* X0<int>::f0(int*, int*); // expected-note{{in instantiation of member function 'X0<int>::f0' requested here}}
37template int X0<int>::f0(int, float);
38
39template int X0<int>::f0(int) const; // expected-error{{does not refer}}
40template int* X0<int>::f0(int*, float*); // expected-error{{does not refer}}
41
42struct X1 { };
43typedef int X1::*MemPtr;
44
45template MemPtr X0<MemPtr>::f0(MemPtr); // expected-note{{requested here}}
46
47struct X2 {
48  int f0(int); // expected-note{{refers here}}
49  
50  template<typename T> T f1(T) { return T(); }
51  template<typename T> T* f1(T*) { return 0; }
52
53  template<typename T, typename U> void f2(T, U*) { } // expected-note{{candidate}}
54  template<typename T, typename U> void f2(T*, U) { } // expected-note{{candidate}}
55};
56
57template int X2::f0(int); // expected-error{{not an instantiation}}
58
59template int *X2::f1(int *); // okay
60
61template void X2::f2(int *, int *); // expected-error{{ambiguous}}
62
63template <typename T>
64void print_type() {} // expected-note {{candidate template ignored: could not match 'void ()' against 'void (float *)'}}
65
66template void print_type<int>();
67template void print_type<float>();
68
69template <typename T>
70void print_type(T *) {} // expected-note {{candidate template ignored: could not match 'void (int *)' against 'void (float *)'}}
71
72template void print_type(int*);
73template void print_type<int>(float*); // expected-error{{does not refer}}
74
75void print_type(double*);
76template void print_type<double>(double*);
77
78// PR5069
79template<int I> void foo0 (int (&)[I + 1]) { }
80template void foo0<2> (int (&)[3]);
81
82namespace explicit_instantiation_after_implicit_instantiation {
83  template <int I> struct X0 { static int x; };
84  template <int I> int X0<I>::x;
85  void test1() { (void)&X0<1>::x; }
86  template struct X0<1>;
87}
88
89template<typename> struct X3 { };
90inline template struct X3<int>; // expected-warning{{ignoring 'inline' keyword on explicit template instantiation}}
91static template struct X3<float>; // expected-warning{{ignoring 'static' keyword on explicit template instantiation}}
92
93namespace PR7622 {
94  template<typename,typename=int>
95  struct basic_streambuf;
96
97  template<typename,typename>
98  struct basic_streambuf{friend bob<>()}; // expected-error{{no template named 'bob'}} \
99                                          // expected-error{{expected member name or ';' after declaration specifiers}}
100  template struct basic_streambuf<int>;
101}
102
103// Test that we do not crash.
104class TC1 {
105  class TC2 {
106    template
107    void foo() { } // expected-error{{expected '<' after 'template'}}
108   };
109};
110
111namespace PR8020 {
112  template <typename T> struct X { X() {} };
113  template<> struct X<int> { X(); };
114  template X<int>::X() {}  // expected-error{{function cannot be defined in an explicit instantiation}}
115}
116
117namespace PR10086 {
118  template void foobar(int i) {}  // expected-error{{function cannot be defined in an explicit instantiation}}
119  int func() {
120    foobar(5);
121  }
122}
123
124namespace undefined_static_data_member {
125  template<typename T> struct A {
126    static int a; // expected-note {{here}}
127    template<typename U> static int b; // expected-note {{here}} expected-warning 0+ {{extension}}
128  };
129  struct B {
130    template<typename U> static int c; // expected-note {{here}} expected-warning 0+ {{extension}}
131  };
132
133  template int A<int>::a; // expected-error {{explicit instantiation of undefined static data member 'a' of class template 'undefined_static_data_member::A<int>'}}
134  template int A<int>::b<int>; // expected-error {{explicit instantiation of undefined variable template 'undefined_static_data_member::A<int>::b<int>'}}
135  template int B::c<int>; // expected-error {{explicit instantiation of undefined variable template 'undefined_static_data_member::B::c<int>'}}
136
137
138  template<typename T> struct C {
139    static int a;
140    template<typename U> static int b; // expected-warning 0+ {{extension}}
141  };
142  struct D {
143    template<typename U> static int c; // expected-warning 0+ {{extension}}
144  };
145  template<typename T> int C<T>::a;
146  template<typename T> template<typename U> int C<T>::b; // expected-warning 0+ {{extension}}
147  template<typename U> int D::c; // expected-warning 0+ {{extension}}
148
149  template int C<int>::a;
150  template int C<int>::b<int>;
151  template int D::c<int>;
152}
153
154// expected-note@+1 3-4 {{explicit instantiation refers here}}
155template <class T> void Foo(T i) throw(T) { throw i; }
156// expected-error@+1 {{exception specification in explicit instantiation does not match instantiated one}}
157template void Foo(int a) throw(char);
158// expected-error@+1 {{exception specification in explicit instantiation does not match instantiated one}}
159template void Foo(double a) throw();
160// expected-error@+1 1 {{exception specification in explicit instantiation does not match instantiated one}}
161template void Foo(long a) throw(long, char);
162template void Foo(float a);
163#if __cplusplus >= 201103L
164// expected-error@+1 0-1 {{exception specification in explicit instantiation does not match instantiated one}}
165template void Foo(double a) noexcept;
166#endif
167
168#if __cplusplus >= 201103L
169namespace PR21942 {
170template <int>
171struct A {
172  virtual void foo() final;
173};
174
175template <>
176void A<0>::foo() {} // expected-note{{overridden virtual function is here}}
177
178struct B : A<0> {
179  virtual void foo() override; // expected-error{{declaration of 'foo' overrides a 'final' function}}
180};
181}
182#endif
183