Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++11-extensions -Wno-c++1y-extensions -DPRECXX11
      2 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s
      3 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s
      4 
      5 class A {
      6   template<typename T> const T wrong;           // expected-error {{member 'wrong' declared as a template}}
      7   template<typename T> const T wrong_init = 5;      // expected-error {{member 'wrong_init' declared as a template}}
      8   template<typename T, typename T0> static const T right = T(100);
      9   template<typename T> static const T right<T,int> = 5;
     10   template<typename T> const int right<int,T>;  // expected-error {{member 'right' declared as a template}}
     11   template<typename T> const float right<float,T> = 5;  // expected-error {{member 'right' declared as a template}}
     12   template<> static const int right<int,int> = 7;       // expected-error {{explicit specialization of 'right' in class scope}}
     13   template<> static const float right<float,int>;       // expected-error {{explicit specialization of 'right' in class scope}}
     14   template static const int right<int,int>;     // expected-error {{template specialization requires 'template<>'}} \
     15                                                 // expected-error {{explicit specialization of 'right' in class scope}}
     16 };
     17 
     18 namespace out_of_line {
     19   class B0 {
     20     template<typename T, typename T0> static const T right = T(100);
     21     template<typename T> static const T right<T,int> = T(5);
     22   };
     23   template<> const int B0::right<int,int> = 7;
     24   template const int B0::right<int,int>;
     25   template<> const int B0::right<int,float>;
     26   template const int B0::right<int,float>;
     27 
     28   class B1 {
     29     template<typename T, typename T0> static const T right;
     30     template<typename T> static const T right<T,int>;
     31   };
     32   template<typename T, typename T0> const T B1::right = T(100);
     33   template<typename T> const T B1::right<T,int> = T(5);
     34 
     35   class B2 {
     36     template<typename T, typename T0> static const T right = T(100);  // expected-note {{previous definition is here}}
     37     template<typename T> static const T right<T,int> = T(5);          // expected-note {{previous definition is here}}
     38   };
     39   template<typename T, typename T0> const T B2::right = T(100);   // expected-error {{redefinition of 'right'}}
     40   template<typename T> const T B2::right<T,int> = T(5);           // expected-error {{redefinition of 'right'}}
     41 
     42   class B3 {
     43     template<typename T, typename T0> static const T right = T(100);
     44     template<typename T> static const T right<T,int> = T(5);
     45   };
     46   template<typename T, typename T0> const T B3::right;  // expected-error {{forward declaration of variable template cannot have a nested name specifier}}
     47   template<typename T> const T B3::right<T,int>;        // expected-error {{forward declaration of variable template partial specialization cannot have a nested name specifier}}
     48 
     49   class B4 {
     50     template<typename T, typename T0> static const T right;
     51     template<typename T> static const T right<T,int>;
     52     template<typename T, typename T0> static const T right_def = T(100);
     53     template<typename T> static const T right_def<T,int>;   // expected-note {{explicit instantiation refers here}}
     54   };
     55   template<typename T, typename T0> const T B4::right;  // expected-error {{forward declaration of variable template cannot have a nested name specifier}}
     56   template<typename T> const T B4::right<T,int>;        // expected-error {{forward declaration of variable template partial specialization cannot have a nested name specifier}} \
     57                                                         // expected-note {{explicit instantiation refers here}}
     58   template const int B4::right<int,int>;  // expected-error {{explicit instantiation of undefined static data member template 'right' of class}}
     59   template const int B4::right_def<int,int>;  // expected-error {{explicit instantiation of undefined static data member template 'right_def' of class}}
     60 }
     61 
     62 namespace non_const_init {
     63   class A {
     64     template<typename T> static T wrong_inst = T(10); // expected-error {{non-const static data member must be initialized out of line}}
     65     template<typename T> static T wrong_inst_fixed;
     66   };
     67   template int A::wrong_inst<int>;  // expected-note {{in instantiation of static data member 'non_const_init::A::wrong_inst<int>' requested here}}
     68   template<typename T> T A::wrong_inst_fixed = T(10);
     69   template int A::wrong_inst_fixed<int>;
     70 
     71   class B {
     72     template<typename T> static T wrong_inst;
     73     template<typename T> static T wrong_inst<T*> = T(100);  // expected-error {{non-const static data member must be initialized out of line}}
     74 
     75     template<typename T> static T wrong_inst_fixed;
     76     template<typename T> static T wrong_inst_fixed<T*>;
     77   };
     78   template int B::wrong_inst<int*>;  // expected-note {{in instantiation of static data member 'non_const_init::B::wrong_inst<int *>' requested here}}
     79   template<typename T> T B::wrong_inst_fixed = T(100);
     80   template int B::wrong_inst_fixed<int>;
     81 
     82   class C {
     83     template<typename T> static const T right_inst = T(10);
     84     template<typename T> static const T right_inst<T*> = T(100);
     85   };
     86   template const int C::right_inst<int>;
     87   template const int C::right_inst<int*>;
     88 
     89   namespace pointers {
     90 
     91     struct C0 {
     92       template<typename U> static U Data;
     93       template<typename U> static const U Data<U*> = U();   // Okay
     94     };
     95     template const int C0::Data<int*>;
     96 
     97     struct C1a {
     98       template<typename U> static U Data;
     99       template<typename U> static U* Data<U>;   // Okay, with out-of-line definition
    100     };
    101     template<typename T> T* C1a::Data<T> = new T();
    102     template int* C1a::Data<int>;
    103 
    104     struct C1b {
    105       template<typename U> static U Data;
    106       template<typename U> static const U* Data<U>;   // Okay, with out-of-line definition
    107     };
    108     template<typename T> const T* C1b::Data<T> = (T*)(0);
    109     template const int* C1b::Data<int>;
    110 
    111     struct C2a {
    112       template<typename U> static U Data;
    113       template<typename U> static U* Data<U> = new U();   // expected-error {{non-const static data member must be initialized out of line}}
    114     };
    115     template int* C2a::Data<int>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2a::Data<int>' requested here}}
    116 
    117     struct C2b {  // FIXME: ?!? Should this be an error? pointer-types are automatically non-const?
    118       template<typename U> static U Data;
    119       template<typename U> static const U* Data<U> = (U*)(0); // expected-error {{non-const static data member must be initialized out of line}}
    120     };
    121     template const int* C2b::Data<int>; // expected-note {{in instantiation of static data member 'non_const_init::pointers::C2b::Data<int>' requested here}}
    122   }
    123 }
    124 
    125 struct matrix_constants {
    126   // TODO: (?)
    127 };
    128 
    129 namespace in_class_template {
    130   // FIXME: member data templates of class templates are not well supported yet.
    131 
    132   template<typename T>
    133   class D0 {
    134     template<typename U> static U Data;
    135     template<typename U> static const U Data<U*> = U();
    136   };
    137 
    138   template<typename T>
    139   class D1 {
    140     template<typename U> static U Data;
    141     template<typename U> static U* Data<U*>;
    142   };
    143   template<typename T>
    144   template<typename U> U* D1<T>::Data<U*> = (U*)(0);
    145 
    146   namespace to_be_fixed {
    147     // FIXME: The following generate runtime exceptions!
    148 
    149     //template<>
    150     //template<typename U> U* D1<float>::Data<U*> = (U*)(0) + 1;
    151     //template const int D0<float>::Data<int*>;
    152     //template int* D1<float>::Data<int*>;
    153   }
    154 }
    155 
    156 namespace in_nested_classes {
    157   // TODO:
    158 }
    159 
    160