1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -verify %s
2f4a2713aSLionel Sambuc
3f4a2713aSLionel Sambuc template<typename T> class A;
4f4a2713aSLionel Sambuc
5f4a2713aSLionel Sambuc extern "C++" {
6f4a2713aSLionel Sambuc template<typename T> class B;
7f4a2713aSLionel Sambuc }
8f4a2713aSLionel Sambuc
9f4a2713aSLionel Sambuc namespace N {
10f4a2713aSLionel Sambuc template<typename T> class C;
11f4a2713aSLionel Sambuc }
12f4a2713aSLionel Sambuc
13f4a2713aSLionel Sambuc extern "C" {
14f4a2713aSLionel Sambuc template<typename T> class D; // expected-error{{templates must have C++ linkage}}
15f4a2713aSLionel Sambuc }
16f4a2713aSLionel Sambuc
17*0a6a1f1dSLionel Sambuc extern "C" {
18*0a6a1f1dSLionel Sambuc class PR17968 {
19*0a6a1f1dSLionel Sambuc template<typename T> class D; // expected-error{{templates must have C++ linkage}}
20*0a6a1f1dSLionel Sambuc template<typename T> void f(); // expected-error{{templates must have C++ linkage}}
21*0a6a1f1dSLionel Sambuc };
22*0a6a1f1dSLionel Sambuc }
23*0a6a1f1dSLionel Sambuc
24f4a2713aSLionel Sambuc template<class U> class A; // expected-note{{previous template declaration is here}}
25f4a2713aSLionel Sambuc
26f4a2713aSLionel Sambuc template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}
27f4a2713aSLionel Sambuc
28f4a2713aSLionel Sambuc template<int N> class NonTypeTemplateParm;
29f4a2713aSLionel Sambuc
30f4a2713aSLionel Sambuc typedef int INT;
31f4a2713aSLionel Sambuc
32f4a2713aSLionel Sambuc template<INT M> class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}}
33f4a2713aSLionel Sambuc
34f4a2713aSLionel Sambuc template<long> class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}}
35f4a2713aSLionel Sambuc
36f4a2713aSLionel Sambuc template<template<typename T> class X> class TemplateTemplateParm;
37f4a2713aSLionel Sambuc
38f4a2713aSLionel Sambuc template<template<class> class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \
39f4a2713aSLionel Sambuc // expected-note{{previous template template parameter is here}}
40f4a2713aSLionel Sambuc
41f4a2713aSLionel Sambuc template<typename> class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}}
42f4a2713aSLionel Sambuc
43f4a2713aSLionel Sambuc template<template<typename T, int> class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}}
44f4a2713aSLionel Sambuc
45f4a2713aSLionel Sambuc template<typename T>
46f4a2713aSLionel Sambuc struct test {}; // expected-note{{previous definition}}
47f4a2713aSLionel Sambuc
48f4a2713aSLionel Sambuc template<typename T>
49f4a2713aSLionel Sambuc struct test : T {}; // expected-error{{redefinition}}
50f4a2713aSLionel Sambuc
51f4a2713aSLionel Sambuc class X {
52f4a2713aSLionel Sambuc public:
53f4a2713aSLionel Sambuc template<typename T> class C;
54f4a2713aSLionel Sambuc };
55f4a2713aSLionel Sambuc
f()56f4a2713aSLionel Sambuc void f() {
57f4a2713aSLionel Sambuc template<typename T> class X; // expected-error{{expression}}
58f4a2713aSLionel Sambuc }
59f4a2713aSLionel Sambuc
60*0a6a1f1dSLionel Sambuc template<typename T> class X1 var; // expected-warning{{variable templates are a C++14 extension}} \
61f4a2713aSLionel Sambuc // expected-error {{variable has incomplete type 'class X1'}} \
62f4a2713aSLionel Sambuc // expected-note {{forward declaration of 'X1'}}
63f4a2713aSLionel Sambuc
64f4a2713aSLionel Sambuc namespace M {
65f4a2713aSLionel Sambuc }
66f4a2713aSLionel Sambuc
67f4a2713aSLionel Sambuc template<typename T> class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}}
68f4a2713aSLionel Sambuc
69f4a2713aSLionel Sambuc namespace PR8001 {
70f4a2713aSLionel Sambuc template<typename T1>
71f4a2713aSLionel Sambuc struct Foo {
72f4a2713aSLionel Sambuc template<typename T2> class Bar;
73f4a2713aSLionel Sambuc typedef Bar<T1> Baz;
74f4a2713aSLionel Sambuc
75f4a2713aSLionel Sambuc template<typename T2>
76f4a2713aSLionel Sambuc struct Bar {
BarPR8001::Foo::Bar77f4a2713aSLionel Sambuc Bar() {}
78f4a2713aSLionel Sambuc };
79f4a2713aSLionel Sambuc };
80f4a2713aSLionel Sambuc
pr8001()81f4a2713aSLionel Sambuc void pr8001() {
82f4a2713aSLionel Sambuc Foo<int>::Baz x;
83f4a2713aSLionel Sambuc Foo<int>::Bar<int> y(x);
84f4a2713aSLionel Sambuc }
85f4a2713aSLionel Sambuc }
86f4a2713aSLionel Sambuc
87f4a2713aSLionel Sambuc namespace rdar9676205 {
88f4a2713aSLionel Sambuc template <unsigned, class _Tp> class tuple_element;
89f4a2713aSLionel Sambuc
90f4a2713aSLionel Sambuc template <class _T1, class _T2> class pair;
91f4a2713aSLionel Sambuc
92f4a2713aSLionel Sambuc template <class _T1, class _T2>
93f4a2713aSLionel Sambuc class tuple_element<0, pair<_T1, _T2> >
94f4a2713aSLionel Sambuc {
95f4a2713aSLionel Sambuc template <class _Tp>
96f4a2713aSLionel Sambuc struct X
97f4a2713aSLionel Sambuc {
98f4a2713aSLionel Sambuc template <class _Up, bool = X<_Up>::value>
99f4a2713aSLionel Sambuc struct Y
100f4a2713aSLionel Sambuc : public X<_Up>,
101f4a2713aSLionel Sambuc public Y<_Up>
102f4a2713aSLionel Sambuc { };
103f4a2713aSLionel Sambuc };
104f4a2713aSLionel Sambuc };
105f4a2713aSLionel Sambuc }
106f4a2713aSLionel Sambuc
107f4a2713aSLionel Sambuc namespace redecl {
108f4a2713aSLionel Sambuc int A; // expected-note {{here}}
109f4a2713aSLionel Sambuc template<typename T> struct A; // expected-error {{different kind of symbol}}
110f4a2713aSLionel Sambuc
111f4a2713aSLionel Sambuc int B; // expected-note {{here}}
112f4a2713aSLionel Sambuc template<typename T> struct B { // expected-error {{different kind of symbol}}
113f4a2713aSLionel Sambuc };
114f4a2713aSLionel Sambuc
115f4a2713aSLionel Sambuc template<typename T> struct F;
116f4a2713aSLionel Sambuc template<typename T> struct K;
117f4a2713aSLionel Sambuc
118f4a2713aSLionel Sambuc int G, H; // expected-note {{here}}
119f4a2713aSLionel Sambuc
120f4a2713aSLionel Sambuc struct S {
121f4a2713aSLionel Sambuc int C; // expected-note {{here}}
122f4a2713aSLionel Sambuc template<typename T> struct C; // expected-error {{different kind of symbol}}
123f4a2713aSLionel Sambuc
124f4a2713aSLionel Sambuc int D; // expected-note {{here}}
125f4a2713aSLionel Sambuc template<typename T> struct D { // expected-error {{different kind of symbol}}
126f4a2713aSLionel Sambuc };
127f4a2713aSLionel Sambuc
128f4a2713aSLionel Sambuc int E;
129f4a2713aSLionel Sambuc template<typename T> friend struct E { // expected-error {{cannot define a type in a friend}}
130f4a2713aSLionel Sambuc };
131f4a2713aSLionel Sambuc
132f4a2713aSLionel Sambuc int F;
133f4a2713aSLionel Sambuc template<typename T> friend struct F; // ok, redecl::F
134f4a2713aSLionel Sambuc
135f4a2713aSLionel Sambuc template<typename T> struct G; // ok
136f4a2713aSLionel Sambuc
137f4a2713aSLionel Sambuc template<typename T> friend struct H; // expected-error {{different kind of symbol}}
138f4a2713aSLionel Sambuc
139f4a2713aSLionel Sambuc int I, J, K;
140f4a2713aSLionel Sambuc
141f4a2713aSLionel Sambuc struct U {
142f4a2713aSLionel Sambuc template<typename T> struct I; // ok
143f4a2713aSLionel Sambuc template<typename T> struct J { // ok
144f4a2713aSLionel Sambuc };
145f4a2713aSLionel Sambuc template<typename T> friend struct K; // ok, redecl::K
146f4a2713aSLionel Sambuc };
147f4a2713aSLionel Sambuc };
148f4a2713aSLionel Sambuc }
149