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