1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 3 namespace PR5907 { 4 template<typename T> struct identity { typedef T type; }; 5 struct A { A(); }; 6 identity<A>::type::A() { } 7 8 struct B { void f(); }; 9 template<typename T> struct C { typedef B type; }; 10 11 void C<int>::type::f() { } 12 } 13 14 namespace PR9421 { 15 namespace N { template<typename T> struct S { void f(); }; } 16 typedef N::S<int> T; 17 namespace N { template<> void T::f() {} } 18 } 19 20 namespace PR8277 { 21 template< typename S > 22 struct C 23 { 24 template< int > 25 void F( void ) 26 { 27 } 28 }; 29 30 template< typename S > 31 struct D 32 { 33 typedef C< int > A; 34 }; 35 36 typedef D< int >::A A; 37 38 template<> 39 template<> 40 void A::F< 0 >( void ) 41 { 42 } 43 } 44 45 namespace PR8277b { 46 template<typename S> struct C { 47 void f(); 48 }; 49 template<typename S> struct D { 50 typedef C<int> A; 51 }; 52 template<> void D<int>::A::f() { 53 } 54 } 55 56 namespace PR8708 { 57 template<typename T> struct A { 58 template<typename U> struct B { 59 // #2 60 void f(); 61 }; 62 }; 63 64 // #A specialize the member template for 65 // implicit instantiation of A<int>, 66 // leaving the member template "unspecialized" 67 // (14.7.3/16). Specialization uses the syntax 68 // for explicit specialization (14.7.3/14) 69 template<> template<typename U> 70 struct A<int>::B { 71 // #1 72 void g(); 73 }; 74 75 // #1 define its function g. There is an enclosing 76 // class template, so we write template<> for each 77 // specialized template (14.7.3/15). 78 template<> template<typename U> 79 void A<int>::B<U>::g() { } 80 81 // #2 define the unspecialized member template's 82 // f 83 template<typename T> template<typename U> 84 void A<T>::B<U>::f() { } 85 86 87 // specialize the member template again, now 88 // specializing the member too. This specializes 89 // #A 90 template<> template<> 91 struct A<int>::B<int> { 92 // #3 93 void h(); 94 }; 95 96 // defines #3. There is no enclosing class template, so 97 // we write no "template<>". 98 void A<int>::B<int>::h() { } 99 100 void test() { 101 // calls #1 102 A<int>::B<float> a; a.g(); 103 104 // calls #2 105 A<float>::B<int> b; b.f(); 106 107 // calls #3 108 A<int>::B<int> c; c.h(); 109 } 110 } 111 112 namespace PR9482 { 113 namespace N1 { 114 template <typename T> struct S { 115 void foo() {} 116 }; 117 } 118 119 namespace N2 { 120 typedef N1::S<int> X; 121 } 122 123 namespace N1 { 124 template<> void N2::X::foo() {} 125 } 126 } 127 128 namespace PR9668 { 129 namespace First 130 { 131 template<class T> 132 class Bar 133 { 134 protected: 135 136 static const bool static_bool; 137 }; 138 } 139 140 namespace Second 141 { 142 class Foo; 143 } 144 145 typedef First::Bar<Second::Foo> Special; 146 147 namespace 148 First 149 { 150 template<> 151 const bool Special::static_bool(false); 152 } 153 } 154 155 namespace PR9877 { 156 template<int> 157 struct X 158 { 159 struct Y; 160 }; 161 162 template<> struct X<0>::Y { static const int Z = 1; }; 163 template<> struct X<1>::Y { static const int Z = 1; }; 164 165 const int X<0>::Y::Z; 166 template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}} 167 } 168 169 namespace PR9913 { 170 template<class,class=int>struct S; 171 template<class X>struct S<X> { 172 template<class T> class F; 173 }; 174 175 template<class A> 176 template<class B> 177 class S<A>::F{}; 178 } 179 180 namespace template_class_spec_perClassDecl_nested 181 { 182 template <typename T1> struct A { 183 template <typename T2> struct B { 184 template <typename T3> struct C { 185 static void foo(); 186 }; 187 }; 188 }; 189 190 template <> struct A<int> { 191 template <typename T2> struct B { 192 template <typename T3> struct C { 193 static void foo(); 194 }; 195 }; 196 }; 197 198 template <> template <typename T3> struct A<int>::B<int>::C { 199 static void foo(); 200 }; 201 202 template <> template <> struct A<int>::B<int>::C<int> { 203 static void foo(); 204 }; 205 206 template <> template<> template <typename T2> struct A<bool>::B<bool>::C { 207 static void foo(); 208 }; 209 } 210