xref: /aosp_15_r20/external/clang/test/SemaTemplate/class-template-decl.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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