xref: /llvm-project/clang/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp (revision c854c6655759fd0e5ee629c39362e9f7785565b2)
18fbe78f6SDaniel Dunbar // RUN: %clang_cc1 -fsyntax-only -verify %s
200bb0cbfSDouglas Gregor 
300bb0cbfSDouglas Gregor template<typename T>
400bb0cbfSDouglas Gregor struct X0 {
500bb0cbfSDouglas Gregor   void f();
600bb0cbfSDouglas Gregor 
700bb0cbfSDouglas Gregor   template<typename U>
800bb0cbfSDouglas Gregor   void g(U);
900bb0cbfSDouglas Gregor 
1000bb0cbfSDouglas Gregor   struct Nested {
1100bb0cbfSDouglas Gregor   };
1200bb0cbfSDouglas Gregor 
1300bb0cbfSDouglas Gregor   static T member;
1400bb0cbfSDouglas Gregor };
1500bb0cbfSDouglas Gregor 
use_X0_int(X0<int> x0i,int i)1600bb0cbfSDouglas Gregor int &use_X0_int(X0<int> x0i,  // expected-note{{implicit instantiation first required here}}
1700bb0cbfSDouglas Gregor                 int i) {
1800bb0cbfSDouglas Gregor   x0i.f(); // expected-note{{implicit instantiation first required here}}
1900bb0cbfSDouglas Gregor   x0i.g(i); // expected-note{{implicit instantiation first required here}}
2000bb0cbfSDouglas Gregor   X0<int>::Nested nested; // expected-note{{implicit instantiation first required here}}
2100bb0cbfSDouglas Gregor   return X0<int>::member; // expected-note{{implicit instantiation first required here}}
2200bb0cbfSDouglas Gregor }
2300bb0cbfSDouglas Gregor 
2400bb0cbfSDouglas Gregor template<>
f()2500bb0cbfSDouglas Gregor void X0<int>::f() { // expected-error{{after instantiation}}
2600bb0cbfSDouglas Gregor }
2700bb0cbfSDouglas Gregor 
2800bb0cbfSDouglas Gregor template<> template<>
g(int)2900bb0cbfSDouglas Gregor void X0<int>::g(int) { // expected-error{{after instantiation}}
3000bb0cbfSDouglas Gregor }
3100bb0cbfSDouglas Gregor 
3200bb0cbfSDouglas Gregor template<>
3300bb0cbfSDouglas Gregor struct X0<int>::Nested { }; // expected-error{{after instantiation}}
3400bb0cbfSDouglas Gregor 
3500bb0cbfSDouglas Gregor template<>
3600bb0cbfSDouglas Gregor int X0<int>::member = 17; // expected-error{{after instantiation}}
3700bb0cbfSDouglas Gregor 
3800bb0cbfSDouglas Gregor template<>
3900bb0cbfSDouglas Gregor struct X0<int> { }; // expected-error{{after instantiation}}
4000bb0cbfSDouglas Gregor 
4100bb0cbfSDouglas Gregor // Example from the standard
4200bb0cbfSDouglas Gregor template<class T> class Array { /* ... */ };
4300bb0cbfSDouglas Gregor 
sort(Array<T> & v)4400bb0cbfSDouglas Gregor template<class T> void sort(Array<T>& v) { /* ... */ }
4500bb0cbfSDouglas Gregor 
4600bb0cbfSDouglas Gregor struct String {};
4700bb0cbfSDouglas Gregor 
f(Array<String> & v)4800bb0cbfSDouglas Gregor void f(Array<String>& v) {
4900bb0cbfSDouglas Gregor 
5000bb0cbfSDouglas Gregor   sort(v); // expected-note{{required}}
5100bb0cbfSDouglas Gregor            // use primary template
5200bb0cbfSDouglas Gregor            // sort(Array<T>&), T is String
5300bb0cbfSDouglas Gregor }
5400bb0cbfSDouglas Gregor 
5500bb0cbfSDouglas Gregor template<> void sort<String>(Array<String>& v); // // expected-error{{after instantiation}}
5600bb0cbfSDouglas Gregor template<> void sort<>(Array<char*>& v);	// OK: sort<char*> not yet used
57*c854c665SDouglas Gregor 
58*c854c665SDouglas Gregor namespace PR6160 {
59*c854c665SDouglas Gregor   template<typename T> void f(T);
60*c854c665SDouglas Gregor   template<> void f(int);
61*c854c665SDouglas Gregor   extern template void f(int);
f(int)62*c854c665SDouglas Gregor   template<> void f(int) { }
63*c854c665SDouglas Gregor }
64