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