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