Home | History | Annotate | Download | only in temp.expl.spec
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 // This test creates cases where implicit instantiations of various entities
      4 // would cause a diagnostic, but provides expliict specializations for those
      5 // entities that avoid the diagnostic. The intent is to verify that
      6 // implicit instantiations do not occur (because the explicit specialization
      7 // is used instead).
      8 struct NonDefaultConstructible {
      9   NonDefaultConstructible(int);
     10 };
     11 
     12 
     13 // C++ [temp.expl.spec]p1:
     14 //   An explicit specialization of any of the following:
     15 
     16 //     -- function template
     17 template<typename T> void f0(T) {
     18   T t;
     19 }
     20 
     21 template<> void f0(NonDefaultConstructible) { }
     22 
     23 void test_f0(NonDefaultConstructible NDC) {
     24   f0(NDC);
     25 }
     26 
     27 //     -- class template
     28 template<typename T>
     29 struct X0 {
     30   static T member;
     31 
     32   void f1(T t) {
     33     t = 17;
     34   }
     35 
     36   struct Inner : public T { };
     37 
     38   template<typename U>
     39   struct InnerTemplate : public T { };
     40 
     41   template<typename U>
     42   void ft1(T t, U u);
     43 };
     44 
     45 template<typename T>
     46 template<typename U>
     47 void X0<T>::ft1(T t, U u) {
     48   t = u;
     49 }
     50 
     51 template<typename T> T X0<T>::member;
     52 
     53 template<> struct X0<void> { };
     54 X0<void> test_X0;
     55 
     56 
     57 //     -- member function of a class template
     58 template<> void X0<void*>::f1(void *) { }
     59 
     60 void test_spec(X0<void*> xvp, void *vp) {
     61   xvp.f1(vp);
     62 }
     63 
     64 //     -- static data member of a class template
     65 template<>
     66 NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
     67 
     68 NonDefaultConstructible &get_static_member() {
     69   return X0<NonDefaultConstructible>::member;
     70 }
     71 
     72 //    -- member class of a class template
     73 template<>
     74 struct X0<void*>::Inner { };
     75 
     76 X0<void*>::Inner inner0;
     77 
     78 //    -- member class template of a class template
     79 template<>
     80 template<>
     81 struct X0<void*>::InnerTemplate<int> { };
     82 
     83 X0<void*>::InnerTemplate<int> inner_template0;
     84 
     85 //    -- member function template of a class template
     86 template<>
     87 template<>
     88 void X0<void*>::ft1(void*, const void*) { }
     89 
     90 void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
     91   xvp.ft1(vp, cvp);
     92 }
     93 
     94 // example from the standard:
     95 template<class T> class stream;
     96 template<> class stream<char> { /* ... */ };
     97 template<class T> class Array { /* ... */ };
     98 template<class T> void sort(Array<T>& v) { /* ... */ }
     99 template<> void sort<char*>(Array<char*>&) ;
    100