1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3template<typename T> class A;
4
5extern "C++" {
6  template<typename T> class B;
7}
8
9namespace N {
10  template<typename T> class C;
11}
12
13extern "C" {
14  template<typename T> class D; // expected-error{{templates must have C++ linkage}}
15}
16
17extern "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
24template<class U> class A; // expected-note{{previous template declaration is here}}
25
26template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}
27
28template<int N> class NonTypeTemplateParm;
29
30typedef int INT;
31
32template<INT M> class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}}
33
34template<long> class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}}
35
36template<template<typename T> class X> class TemplateTemplateParm;
37
38template<template<class> class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \
39      // expected-note{{previous template template parameter is here}}
40
41template<typename> class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}}
42
43template<template<typename T, int> class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}}
44
45template<typename T>
46struct test {}; // expected-note{{previous definition}}
47
48template<typename T>
49struct test : T {}; // expected-error{{redefinition}}
50
51class X {
52public:
53  template<typename T> class C;
54};
55
56void f() {
57  template<typename T> class X; // expected-error{{expression}}
58}
59
60template<typename T> class X1 var; // expected-warning{{variable templates are a C++1y extension}} \
61                                   // expected-error {{variable has incomplete type 'class X1'}} \
62                                   // expected-note {{forward declaration of 'X1'}}
63
64namespace M {
65}
66
67template<typename T> class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}}
68
69namespace 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 {
77     Bar() {}
78   };
79  };
80
81  void pr8001() {
82    Foo<int>::Baz x;
83    Foo<int>::Bar<int> y(x);
84  }
85}
86
87namespace 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
107namespace 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