1 // RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s 2 3 template<typename T> class A {}; 4 5 extern "C++" { 6 template<typename T> class B {}; 7 template<typename T> class A<T *>; 8 template<> class A<int[1]>; 9 template class A<int[2]>; 10 template<typename T> class B<T *>; 11 template<> class B<int[1]>; 12 template class B<int[2]>; 13 } 14 15 namespace N { 16 template<typename T> class C; 17 } 18 19 extern "C" { // expected-note 3 {{extern "C" language linkage specification begins here}} 20 template<typename T> class D; // expected-error{{templates must have C++ linkage}} 21 template<typename T> class A<T **>; // expected-error{{templates must have C++ linkage}} 22 template<> class A<int[3]>; // expected-error{{templates must have C++ linkage}} 23 template class A<int[4]>; // OK (surprisingly) FIXME: Should we warn on this? 24 } 25 26 extern "C" { // expected-note 2 {{extern "C" language linkage specification begins here}} 27 class PR17968 { 28 template<typename T> class D; // expected-error{{templates must have C++ linkage}} 29 template<typename T> void f(); // expected-error{{templates must have C++ linkage}} 30 }; 31 } 32 33 template<class U> class A; // expected-note{{previous template declaration is here}} 34 35 template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}} 36 37 template<int N> class NonTypeTemplateParm; 38 39 typedef int INT; 40 41 template<INT M> class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}} 42 43 template<long> class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}} 44 45 template<template<typename T> class X> class TemplateTemplateParm; 46 47 template<template<class> class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \ 48 // expected-note{{previous template template parameter is here}} 49 50 template<typename> class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}} 51 52 template<template<typename T, int> class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}} 53 54 template<typename T> 55 struct test {}; // expected-note{{previous definition}} 56 57 template<typename T> 58 struct test : T {}; // expected-error{{redefinition}} 59 60 class X { 61 public: 62 template<typename T> class C; 63 }; 64 65 void f() { 66 template<typename T> class X; // expected-error{{templates can only be declared in namespace or class scope}} 67 } 68 69 template<typename T> class X1 var; // expected-error {{variable has incomplete type 'class X1'}} \ 70 // expected-note {{forward declaration of 'X1'}} 71 72 namespace M { 73 } 74 75 template<typename T> class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}} 76 77 namespace PR8001 { 78 template<typename T1> 79 struct Foo { 80 template<typename T2> class Bar; 81 typedef Bar<T1> Baz; 82 83 template<typename T2> 84 struct Bar { 85 Bar() {} 86 }; 87 }; 88 89 void pr8001() { 90 Foo<int>::Baz x; 91 Foo<int>::Bar<int> y(x); 92 } 93 } 94 95 namespace rdar9676205 { 96 template <unsigned, class _Tp> class tuple_element; 97 98 template <class _T1, class _T2> class pair; 99 100 template <class _T1, class _T2> 101 class tuple_element<0, pair<_T1, _T2> > 102 { 103 template <class _Tp> 104 struct X 105 { 106 template <class _Up, bool = X<_Up>::value> 107 struct Y 108 : public X<_Up>, 109 public Y<_Up> 110 { }; 111 }; 112 }; 113 } 114 115 namespace redecl { 116 int A; // expected-note {{here}} 117 template<typename T> struct A; // expected-error {{different kind of symbol}} 118 119 int B; // expected-note {{here}} 120 template<typename T> struct B { // expected-error {{different kind of symbol}} 121 }; 122 123 template<typename T> struct F; 124 template<typename T> struct K; 125 126 int G, H; // expected-note {{here}} 127 128 struct S { 129 int C; // expected-note {{here}} 130 template<typename T> struct C; // expected-error {{different kind of symbol}} 131 132 int D; // expected-note {{here}} 133 template<typename T> struct D { // expected-error {{different kind of symbol}} 134 }; 135 136 int E; 137 template<typename T> friend struct E { // expected-error {{cannot define a type in a friend}} 138 }; 139 140 int F; 141 template<typename T> friend struct F; // ok, redecl::F 142 143 template<typename T> struct G; // ok 144 145 template<typename T> friend struct H; // expected-error {{different kind of symbol}} 146 147 int I, J, K; 148 149 struct U { 150 template<typename T> struct I; // ok 151 template<typename T> struct J { // ok 152 }; 153 template<typename T> friend struct K; // ok, redecl::K 154 }; 155 }; 156 } 157 158 extern "C" template <typename T> // expected-error{{templates must have C++ linkage}} 159 void DontCrashOnThis() { // expected-note@-1 {{extern "C" language linkage specification begins here}} 160 T &pT = T(); 161 pT; 162 } 163 164 namespace abstract_dependent_class { 165 template<typename T> struct A { 166 virtual A<T> *clone() = 0; // expected-note {{pure virtual}} 167 }; 168 template<typename T> A<T> *A<T>::clone() { return new A<T>; } // expected-error {{abstract class type 'A<T>'}} 169 } 170 171 namespace qualified_out_of_line { 172 struct rbnode {}; 173 template<typename T, typename U> struct pair {}; 174 template<typename K, typename V> struct rbtree { 175 using base = rbnode; 176 pair<base, base> f(); 177 }; 178 template<typename K, typename V> 179 pair<typename rbtree<K, V>::base, typename rbtree<K, V>::base> 180 rbtree<K, V>::f() { 181 return {}; 182 } 183 } 184