1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2
3 template<typename T>
4 struct X0 {
5 void f();
6
7 template<typename U>
8 void g(U);
9
10 struct Nested {
11 };
12
13 static T member;
14 };
15
use_X0_int(X0<int> x0i,int i)16 int &use_X0_int(X0<int> x0i, // expected-note{{implicit instantiation first required here}}
17 int i) {
18 x0i.f(); // expected-note{{implicit instantiation first required here}}
19 x0i.g(i); // expected-note{{implicit instantiation first required here}}
20 X0<int>::Nested nested; // expected-note{{implicit instantiation first required here}}
21 return X0<int>::member; // expected-note{{implicit instantiation first required here}}
22 }
23
24 template<>
f()25 void X0<int>::f() { // expected-error{{after instantiation}}
26 }
27
28 template<> template<>
g(int)29 void X0<int>::g(int) { // expected-error{{after instantiation}}
30 }
31
32 template<>
33 struct X0<int>::Nested { }; // expected-error{{after instantiation}}
34
35 template<>
36 int X0<int>::member = 17; // expected-error{{after instantiation}}
37
38 template<>
39 struct X0<int> { }; // expected-error{{after instantiation}}
40
41 // Example from the standard
42 template<class T> class Array { /* ... */ };
43
sort(Array<T> & v)44 template<class T> void sort(Array<T>& v) { /* ... */ }
45
46 struct String {};
47
f(Array<String> & v)48 void f(Array<String>& v) {
49
50 sort(v); // expected-note{{required}}
51 // use primary template
52 // sort(Array<T>&), T is String
53 }
54
55 template<> void sort<String>(Array<String>& v); // // expected-error{{after instantiation}}
56 template<> void sort<>(Array<char*>& v); // OK: sort<char*> not yet used
57
58 namespace PR6160 {
59 template<typename T> void f(T);
60 template<> void f(int);
61 extern template void f(int);
f(int)62 template<> void f(int) { }
63 }
64