Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
      3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
      4 template<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \
      5                                                  // expected-note{{explicitly specialized}}
      6 
      7 template<> struct A<double, double>; // expected-note{{forward declaration}}
      8 
      9 template<> struct A<float, float> {  // expected-note{{previous definition}}
     10   int x;
     11 };
     12 
     13 template<> struct A<float> { // expected-note{{previous definition}}
     14   int y;
     15 };
     16 
     17 int test_specs(A<float, float> *a1, A<float, int> *a2) {
     18   return a1->x + a2->y;
     19 }
     20 
     21 int test_incomplete_specs(A<double, double> *a1,
     22                           A<double> *a2)
     23 {
     24   (void)a1->x; // expected-error{{member access into incomplete type}}
     25   (void)a2->x; // expected-error{{implicit instantiation of undefined template 'A<double, int>'}}
     26 }
     27 
     28 typedef float FLOAT;
     29 
     30 template<> struct A<float, FLOAT>;
     31 
     32 template<> struct A<FLOAT, float> { }; // expected-error{{redefinition}}
     33 
     34 template<> struct A<float, int> { }; // expected-error{{redefinition}}
     35 
     36 template<typename T, typename U = int> struct X;
     37 
     38 template <> struct X<int, int> { int foo(); }; // #1
     39 template <> struct X<float> { int bar(); };  // #2
     40 
     41 typedef int int_type;
     42 void testme(X<int_type> *x1, X<float, int> *x2) {
     43   (void)x1->foo(); // okay: refers to #1
     44   (void)x2->bar(); // okay: refers to #2
     45 }
     46 
     47 // Make sure specializations are proper classes.
     48 template<>
     49 struct A<char> {
     50   A();
     51 };
     52 
     53 A<char>::A() { }
     54 
     55 // Make sure we can see specializations defined before the primary template.
     56 namespace N{
     57   template<typename T> struct A0;
     58 }
     59 
     60 namespace N {
     61   template<>
     62   struct A0<void> {
     63     typedef void* pointer;
     64   };
     65 }
     66 
     67 namespace N {
     68   template<typename T>
     69   struct A0 {
     70     void foo(A0<void>::pointer p = 0);
     71   };
     72 }
     73 
     74 // Diagnose specialization errors
     75 struct A<double> { }; // expected-error{{template specialization requires 'template<>'}}
     76 
     77 template<> struct ::A<double>;
     78 
     79 namespace N {
     80   template<typename T> struct B; // expected-note {{explicitly specialized}}
     81 #if __cplusplus <= 199711L
     82   // expected-note@-2 {{explicitly specialized}}
     83 #endif
     84 
     85   template<> struct ::N::B<char>; // okay
     86   template<> struct ::N::B<short>; // okay
     87   template<> struct ::N::B<int>; // okay
     88 
     89   int f(int);
     90 }
     91 
     92 template<> struct N::B<int> { }; // okay
     93 
     94 template<> struct N::B<float> { };
     95 #if __cplusplus <= 199711L
     96 // expected-warning@-2 {{first declaration of class template specialization of 'B' outside namespace 'N' is a C++11 extension}}
     97 #endif
     98 
     99 
    100 namespace M {
    101   template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
    102 
    103   template<> struct ::A<long double>; // expected-error{{must occur at global scope}}
    104 }
    105 
    106 template<> struct N::B<char> {
    107   int testf(int x) { return f(x); }
    108 };
    109 
    110 // PR5264
    111 template <typename T> class Foo;
    112 Foo<int>* v;
    113 Foo<int>& F() { return *v; }
    114 template <typename T> class Foo {};
    115 Foo<int> x;
    116 
    117 
    118 // Template template parameters
    119 template<template<class T> class Wibble>
    120 class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}}
    121 
    122 namespace rdar9676205 {
    123   template<typename T>
    124   struct X {
    125     template<typename U>
    126     struct X<U*> { // expected-error{{explicit specialization of 'X' in class scope}}
    127     };
    128   };
    129 
    130 }
    131 
    132 namespace PR18009 {
    133   template <typename T> struct A {
    134     template <int N, int M> struct S;
    135     template <int N> struct S<N, sizeof(T)> {};
    136   };
    137   A<int>::S<8, sizeof(int)> a; // ok
    138 
    139   template <typename T> struct B {
    140     template <int N, int M> struct S; // expected-note {{declared here}}
    141     template <int N> struct S<N, sizeof(T) +
    142         N // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
    143         > {};
    144   };
    145   B<int>::S<8, sizeof(int) + 8> s; // expected-error {{undefined}}
    146 
    147   template<int A> struct outer {
    148     template<int B, int C> struct inner {};
    149     template<int C> struct inner<A * 2, C> {};
    150   };
    151 }
    152 
    153 namespace PR16519 {
    154   template<typename T, T...N> struct integer_sequence { typedef T value_type; };
    155 #if __cplusplus <= 199711L
    156   // expected-warning@-2 {{variadic templates are a C++11 extension}}
    157 #endif
    158 
    159   template<typename T> struct __make_integer_sequence;
    160   template<typename T, T N> using make_integer_sequence = typename __make_integer_sequence<T>::template make<N, N % 2>::type;
    161 #if __cplusplus <= 199711L
    162   // expected-warning@-2 {{alias declarations are a C++11 extension}}
    163 #endif
    164 
    165   template<typename T, typename T::value_type ...Extra> struct __make_integer_sequence_impl;
    166 #if __cplusplus <= 199711L
    167   // expected-warning@-2 {{variadic templates are a C++11 extension}}
    168 #endif
    169 
    170   template<typename T, T ...N, T ...Extra> struct __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> {
    171 #if __cplusplus <= 199711L
    172   // expected-warning@-2 2 {{variadic templates are a C++11 extension}}
    173 #endif
    174     typedef integer_sequence<T, N..., sizeof...(N) + N..., Extra...> type;
    175   };
    176 
    177   template<typename T> struct __make_integer_sequence {
    178     template<T N, T Parity, typename = void> struct make;
    179     template<typename Dummy> struct make<0, 0, Dummy> { typedef integer_sequence<T> type; };
    180     template<typename Dummy> struct make<1, 1, Dummy> { typedef integer_sequence<T, 0> type; };
    181     template<T N, typename Dummy> struct make<N, 0, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2> > {};
    182     template<T N, typename Dummy> struct make<N, 1, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2>, N - 1> {};
    183   };
    184 
    185   using X = make_integer_sequence<int, 5>;
    186 #if __cplusplus <= 199711L
    187   // expected-warning@-2 {{alias declarations are a C++11 extension}}
    188 #endif
    189 
    190   using X = integer_sequence<int, 0, 1, 2, 3, 4>;
    191 #if __cplusplus <= 199711L
    192   // expected-warning@-2 {{alias declarations are a C++11 extension}}
    193 #endif
    194 }
    195 
    196 namespace DefaultArgVsPartialSpec {
    197   // Check that the diagnostic points at the partial specialization, not just at
    198   // the default argument.
    199   template<typename T, int N =
    200       sizeof(T) // expected-note {{template parameter is used in default argument declared here}}
    201   > struct X {};
    202   template<typename T> struct X<T> {}; // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
    203 
    204   template<typename T,
    205       T N = 0 // expected-note {{template parameter is declared here}}
    206   > struct S;
    207   template<typename T> struct S<T> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}
    208 }
    209