1db64e7e9SNemanja Ivanovic // RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s
2cd72ba97SDouglas Gregor
3a6488343SRichard Smith template<typename T> class A {};
4cd72ba97SDouglas Gregor
5cd72ba97SDouglas Gregor extern "C++" {
6a6488343SRichard Smith template<typename T> class B {};
7a6488343SRichard Smith template<typename T> class A<T *>;
8a6488343SRichard Smith template<> class A<int[1]>;
9a6488343SRichard Smith template class A<int[2]>;
10a6488343SRichard Smith template<typename T> class B<T *>;
11a6488343SRichard Smith template<> class B<int[1]>;
12a6488343SRichard Smith template class B<int[2]>;
13cd72ba97SDouglas Gregor }
14cd72ba97SDouglas Gregor
15cd72ba97SDouglas Gregor namespace N {
16cd72ba97SDouglas Gregor template<typename T> class C;
17cd72ba97SDouglas Gregor }
18cd72ba97SDouglas Gregor
19a6488343SRichard Smith extern "C" { // expected-note 3 {{extern "C" language linkage specification begins here}}
20cd72ba97SDouglas Gregor template<typename T> class D; // expected-error{{templates must have C++ linkage}}
21a6488343SRichard Smith template<typename T> class A<T **>; // expected-error{{templates must have C++ linkage}}
22a6488343SRichard Smith template<> class A<int[3]>; // expected-error{{templates must have C++ linkage}}
23a6488343SRichard Smith template class A<int[4]>; // OK (surprisingly) FIXME: Should we warn on this?
24cd72ba97SDouglas Gregor }
25cd72ba97SDouglas Gregor
26560ae565SAlex Lorenz extern "C" { // expected-note 2 {{extern "C" language linkage specification begins here}}
2735e6fee3SBenjamin Kramer class PR17968 {
2835e6fee3SBenjamin Kramer template<typename T> class D; // expected-error{{templates must have C++ linkage}}
2935e6fee3SBenjamin Kramer template<typename T> void f(); // expected-error{{templates must have C++ linkage}}
3035e6fee3SBenjamin Kramer };
3135e6fee3SBenjamin Kramer }
3235e6fee3SBenjamin Kramer
33f9aa5260SDouglas Gregor template<class U> class A; // expected-note{{previous template declaration is here}}
34cd72ba97SDouglas Gregor
35cd72ba97SDouglas Gregor template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}
36cd72ba97SDouglas Gregor
37cd72ba97SDouglas Gregor template<int N> class NonTypeTemplateParm;
38cd72ba97SDouglas Gregor
39cd72ba97SDouglas Gregor typedef int INT;
40cd72ba97SDouglas Gregor
41810d330cSChris Lattner template<INT M> class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}}
42cd72ba97SDouglas Gregor
43cd72ba97SDouglas Gregor template<long> class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}}
44cd72ba97SDouglas Gregor
45cd72ba97SDouglas Gregor template<template<typename T> class X> class TemplateTemplateParm;
46cd72ba97SDouglas Gregor
47cd72ba97SDouglas Gregor template<template<class> class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \
48cd72ba97SDouglas Gregor // expected-note{{previous template template parameter is here}}
49cd72ba97SDouglas Gregor
50cd72ba97SDouglas Gregor template<typename> class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}}
51cd72ba97SDouglas Gregor
52cd72ba97SDouglas Gregor template<template<typename T, int> class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}}
53cd72ba97SDouglas Gregor
5471a5718fSDouglas Gregor template<typename T>
5571a5718fSDouglas Gregor struct test {}; // expected-note{{previous definition}}
5671a5718fSDouglas Gregor
5771a5718fSDouglas Gregor template<typename T>
5871a5718fSDouglas Gregor struct test : T {}; // expected-error{{redefinition}}
5971a5718fSDouglas Gregor
60cd72ba97SDouglas Gregor class X {
61cd72ba97SDouglas Gregor public:
62cd72ba97SDouglas Gregor template<typename T> class C;
63cd72ba97SDouglas Gregor };
64cd72ba97SDouglas Gregor
f()65cd72ba97SDouglas Gregor void f() {
66866ad5d8SDouglas Gregor template<typename T> class X; // expected-error{{expression}}
67cd72ba97SDouglas Gregor }
684ebb7f3eSDouglas Gregor
6936bb6d5dSTim Northover template<typename T> class X1 var; // expected-error {{variable has incomplete type 'class X1'}} \
7039a1e507SLarisse Voufo // expected-note {{forward declaration of 'X1'}}
71ce40e2efSDouglas Gregor
72ce40e2efSDouglas Gregor namespace M {
73ce40e2efSDouglas Gregor }
74ce40e2efSDouglas Gregor
75ce40e2efSDouglas Gregor template<typename T> class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}}
7661478916SNick Lewycky
7761478916SNick Lewycky namespace PR8001 {
7861478916SNick Lewycky template<typename T1>
7961478916SNick Lewycky struct Foo {
8061478916SNick Lewycky template<typename T2> class Bar;
8161478916SNick Lewycky typedef Bar<T1> Baz;
8261478916SNick Lewycky
8361478916SNick Lewycky template<typename T2>
8461478916SNick Lewycky struct Bar {
BarPR8001::Foo::Bar8561478916SNick Lewycky Bar() {}
8661478916SNick Lewycky };
8761478916SNick Lewycky };
8861478916SNick Lewycky
pr8001()8961478916SNick Lewycky void pr8001() {
9061478916SNick Lewycky Foo<int>::Baz x;
9161478916SNick Lewycky Foo<int>::Bar<int> y(x);
9261478916SNick Lewycky }
9361478916SNick Lewycky }
94fbf87525SDouglas Gregor
954109afa1SDouglas Gregor namespace rdar9676205 {
964109afa1SDouglas Gregor template <unsigned, class _Tp> class tuple_element;
974109afa1SDouglas Gregor
984109afa1SDouglas Gregor template <class _T1, class _T2> class pair;
994109afa1SDouglas Gregor
1004109afa1SDouglas Gregor template <class _T1, class _T2>
1014109afa1SDouglas Gregor class tuple_element<0, pair<_T1, _T2> >
1024109afa1SDouglas Gregor {
1034109afa1SDouglas Gregor template <class _Tp>
1044109afa1SDouglas Gregor struct X
1054109afa1SDouglas Gregor {
1064109afa1SDouglas Gregor template <class _Up, bool = X<_Up>::value>
1074109afa1SDouglas Gregor struct Y
1084109afa1SDouglas Gregor : public X<_Up>,
1094109afa1SDouglas Gregor public Y<_Up>
1104109afa1SDouglas Gregor { };
1114109afa1SDouglas Gregor };
1124109afa1SDouglas Gregor };
1134109afa1SDouglas Gregor }
1146483d22fSRichard Smith
1156483d22fSRichard Smith namespace redecl {
1166483d22fSRichard Smith int A; // expected-note {{here}}
1176483d22fSRichard Smith template<typename T> struct A; // expected-error {{different kind of symbol}}
1186483d22fSRichard Smith
1199f2a7b2eSRichard Smith int B; // expected-note {{here}}
1206483d22fSRichard Smith template<typename T> struct B { // expected-error {{different kind of symbol}}
1216483d22fSRichard Smith };
1226483d22fSRichard Smith
1236483d22fSRichard Smith template<typename T> struct F;
1246483d22fSRichard Smith template<typename T> struct K;
1256483d22fSRichard Smith
1269f2a7b2eSRichard Smith int G, H; // expected-note {{here}}
1276483d22fSRichard Smith
1286483d22fSRichard Smith struct S {
1296483d22fSRichard Smith int C; // expected-note {{here}}
1306483d22fSRichard Smith template<typename T> struct C; // expected-error {{different kind of symbol}}
1316483d22fSRichard Smith
1329f2a7b2eSRichard Smith int D; // expected-note {{here}}
1336483d22fSRichard Smith template<typename T> struct D { // expected-error {{different kind of symbol}}
1346483d22fSRichard Smith };
1356483d22fSRichard Smith
1366483d22fSRichard Smith int E;
1376483d22fSRichard Smith template<typename T> friend struct E { // expected-error {{cannot define a type in a friend}}
1386483d22fSRichard Smith };
1396483d22fSRichard Smith
1406483d22fSRichard Smith int F;
1416483d22fSRichard Smith template<typename T> friend struct F; // ok, redecl::F
1426483d22fSRichard Smith
1436483d22fSRichard Smith template<typename T> struct G; // ok
1446483d22fSRichard Smith
1456483d22fSRichard Smith template<typename T> friend struct H; // expected-error {{different kind of symbol}}
1466483d22fSRichard Smith
1476483d22fSRichard Smith int I, J, K;
1486483d22fSRichard Smith
1496483d22fSRichard Smith struct U {
1506483d22fSRichard Smith template<typename T> struct I; // ok
1516483d22fSRichard Smith template<typename T> struct J { // ok
1526483d22fSRichard Smith };
1536483d22fSRichard Smith template<typename T> friend struct K; // ok, redecl::K
1546483d22fSRichard Smith };
1556483d22fSRichard Smith };
1566483d22fSRichard Smith }
1578e1a913cSDavid Majnemer
1588e1a913cSDavid Majnemer extern "C" template <typename T> // expected-error{{templates must have C++ linkage}}
DontCrashOnThis()159560ae565SAlex Lorenz void DontCrashOnThis() { // expected-note@-1 {{extern "C" language linkage specification begins here}}
1608e1a913cSDavid Majnemer T &pT = T();
1618e1a913cSDavid Majnemer pT;
1628e1a913cSDavid Majnemer }
163ac9f5a9cSRichard Smith
164ac9f5a9cSRichard Smith namespace abstract_dependent_class {
165ac9f5a9cSRichard Smith template<typename T> struct A {
166ac9f5a9cSRichard Smith virtual A<T> *clone() = 0; // expected-note {{pure virtual}}
167ac9f5a9cSRichard Smith };
clone()168ac9f5a9cSRichard Smith template<typename T> A<T> *A<T>::clone() { return new A<T>; } // expected-error {{abstract class type 'A<T>'}}
169ac9f5a9cSRichard Smith }
170*4b388859SRichard Smith
171*4b388859SRichard Smith namespace qualified_out_of_line {
172*4b388859SRichard Smith struct rbnode {};
173*4b388859SRichard Smith template<typename T, typename U> struct pair {};
174*4b388859SRichard Smith template<typename K, typename V> struct rbtree {
175*4b388859SRichard Smith using base = rbnode;
176*4b388859SRichard Smith pair<base, base> f();
177*4b388859SRichard Smith };
178*4b388859SRichard Smith template<typename K, typename V>
179*4b388859SRichard Smith pair<typename rbtree<K, V>::base, typename rbtree<K, V>::base>
f()180*4b388859SRichard Smith rbtree<K, V>::f() {
181*4b388859SRichard Smith return {};
182*4b388859SRichard Smith }
183*4b388859SRichard Smith }
184