1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3template<typename T>
4struct 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
16int &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
24template<>
25void X0<int>::f() { // expected-error{{after instantiation}}
26}
27
28template<> template<>
29void X0<int>::g(int) { // expected-error{{after instantiation}}
30}
31
32template<>
33struct X0<int>::Nested { }; // expected-error{{after instantiation}}
34
35template<>
36int X0<int>::member = 17; // expected-error{{after instantiation}}
37
38template<>
39struct X0<int> { }; // expected-error{{after instantiation}}
40
41// Example from the standard
42template<class T> class Array { /* ... */ };
43
44template<class T> void sort(Array<T>& v) { /* ... */ }
45
46struct String {};
47
48void f(Array<String>& v) {
49
50  sort(v); // expected-note{{required}}
51           // use primary template
52           // sort(Array<T>&), T is String
53}
54
55template<> void sort<String>(Array<String>& v); // // expected-error{{after instantiation}}
56template<> void sort<>(Array<char*>& v);	// OK: sort<char*> not yet used
57
58namespace PR6160 {
59  template<typename T> void f(T);
60  template<> void f(int);
61  extern template void f(int);
62  template<> void f(int) { }
63}
64