xref: /llvm-project/clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp (revision c6e68daac0fa6e77a89f3ca72f266a528503dd1c)
18fbe78f6SDaniel Dunbar // RUN: %clang_cc1 -fsyntax-only -verify %s
2*c6e68daaSAndy Gibbs // expected-no-diagnostics
327c26e9aSDouglas Gregor 
427c26e9aSDouglas Gregor // This test creates cases where implicit instantiations of various entities
527c26e9aSDouglas Gregor // would cause a diagnostic, but provides expliict specializations for those
627c26e9aSDouglas Gregor // entities that avoid the diagnostic. The intent is to verify that
754888651SDouglas Gregor // implicit instantiations do not occur (because the explicit specialization
854888651SDouglas Gregor // is used instead).
927c26e9aSDouglas Gregor struct NonDefaultConstructible {
1027c26e9aSDouglas Gregor   NonDefaultConstructible(int);
1127c26e9aSDouglas Gregor };
1227c26e9aSDouglas Gregor 
1327c26e9aSDouglas Gregor 
1427c26e9aSDouglas Gregor // C++ [temp.expl.spec]p1:
1527c26e9aSDouglas Gregor //   An explicit specialization of any of the following:
1627c26e9aSDouglas Gregor 
1727c26e9aSDouglas Gregor //     -- function template
f0(T)1827c26e9aSDouglas Gregor template<typename T> void f0(T) {
1927c26e9aSDouglas Gregor   T t;
2027c26e9aSDouglas Gregor }
2127c26e9aSDouglas Gregor 
f0(NonDefaultConstructible)2227c26e9aSDouglas Gregor template<> void f0(NonDefaultConstructible) { }
2327c26e9aSDouglas Gregor 
test_f0(NonDefaultConstructible NDC)2427c26e9aSDouglas Gregor void test_f0(NonDefaultConstructible NDC) {
2527c26e9aSDouglas Gregor   f0(NDC);
2627c26e9aSDouglas Gregor }
2727c26e9aSDouglas Gregor 
2827c26e9aSDouglas Gregor //     -- class template
2927c26e9aSDouglas Gregor template<typename T>
3027c26e9aSDouglas Gregor struct X0 {
3127c26e9aSDouglas Gregor   static T member;
3227c26e9aSDouglas Gregor 
f1X03327c26e9aSDouglas Gregor   void f1(T t) {
3427c26e9aSDouglas Gregor     t = 17;
3527c26e9aSDouglas Gregor   }
3627c26e9aSDouglas Gregor 
3727c26e9aSDouglas Gregor   struct Inner : public T { };
3827c26e9aSDouglas Gregor 
3927c26e9aSDouglas Gregor   template<typename U>
4027c26e9aSDouglas Gregor   struct InnerTemplate : public T { };
4127c26e9aSDouglas Gregor 
4227c26e9aSDouglas Gregor   template<typename U>
4327c26e9aSDouglas Gregor   void ft1(T t, U u);
4427c26e9aSDouglas Gregor };
4527c26e9aSDouglas Gregor 
4627c26e9aSDouglas Gregor template<typename T>
4727c26e9aSDouglas Gregor template<typename U>
ft1(T t,U u)4827c26e9aSDouglas Gregor void X0<T>::ft1(T t, U u) {
4927c26e9aSDouglas Gregor   t = u;
5027c26e9aSDouglas Gregor }
5127c26e9aSDouglas Gregor 
5227c26e9aSDouglas Gregor template<typename T> T X0<T>::member;
5327c26e9aSDouglas Gregor 
5427c26e9aSDouglas Gregor template<> struct X0<void> { };
5527c26e9aSDouglas Gregor X0<void> test_X0;
5627c26e9aSDouglas Gregor 
5727c26e9aSDouglas Gregor 
5827c26e9aSDouglas Gregor //     -- member function of a class template
f1(void *)5927c26e9aSDouglas Gregor template<> void X0<void*>::f1(void *) { }
6027c26e9aSDouglas Gregor 
test_spec(X0<void * > xvp,void * vp)6127c26e9aSDouglas Gregor void test_spec(X0<void*> xvp, void *vp) {
6227c26e9aSDouglas Gregor   xvp.f1(vp);
6327c26e9aSDouglas Gregor }
6427c26e9aSDouglas Gregor 
6527c26e9aSDouglas Gregor //     -- static data member of a class template
6627c26e9aSDouglas Gregor template<>
6727c26e9aSDouglas Gregor NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
6827c26e9aSDouglas Gregor 
get_static_member()6927c26e9aSDouglas Gregor NonDefaultConstructible &get_static_member() {
7027c26e9aSDouglas Gregor   return X0<NonDefaultConstructible>::member;
7127c26e9aSDouglas Gregor }
7227c26e9aSDouglas Gregor 
7327c26e9aSDouglas Gregor //    -- member class of a class template
7427c26e9aSDouglas Gregor template<>
7527c26e9aSDouglas Gregor struct X0<void*>::Inner { };
7627c26e9aSDouglas Gregor 
7727c26e9aSDouglas Gregor X0<void*>::Inner inner0;
7827c26e9aSDouglas Gregor 
7927c26e9aSDouglas Gregor //    -- member class template of a class template
8027c26e9aSDouglas Gregor template<>
8127c26e9aSDouglas Gregor template<>
8227c26e9aSDouglas Gregor struct X0<void*>::InnerTemplate<int> { };
8327c26e9aSDouglas Gregor 
8427c26e9aSDouglas Gregor X0<void*>::InnerTemplate<int> inner_template0;
8527c26e9aSDouglas Gregor 
8627c26e9aSDouglas Gregor //    -- member function template of a class template
8727c26e9aSDouglas Gregor template<>
8827c26e9aSDouglas Gregor template<>
ft1(void *,const void *)8927c26e9aSDouglas Gregor void X0<void*>::ft1(void*, const void*) { }
9027c26e9aSDouglas Gregor 
test_func_template(X0<void * > xvp,void * vp,const void * cvp)9127c26e9aSDouglas Gregor void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
9227c26e9aSDouglas Gregor   xvp.ft1(vp, cvp);
9327c26e9aSDouglas Gregor }
9427c26e9aSDouglas Gregor 
9527c26e9aSDouglas Gregor // example from the standard:
9627c26e9aSDouglas Gregor template<class T> class stream;
9727c26e9aSDouglas Gregor template<> class stream<char> { /* ... */ };
9827c26e9aSDouglas Gregor template<class T> class Array { /* ... */ };
sort(Array<T> & v)9927c26e9aSDouglas Gregor template<class T> void sort(Array<T>& v) { /* ... */ }
10027c26e9aSDouglas Gregor template<> void sort<char*>(Array<char*>&) ;
101