aboutsummaryrefslogtreecommitdiff
path: root/test/SemaTemplate/class-template-decl.cpp
blob: b721aab35464599d2dd197e5b068831953effc3d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// RUN: %clang_cc1 -fsyntax-only -verify %s

template<typename T> class A;

extern "C++" {
  template<typename T> class B;
}

namespace N {
  template<typename T> class C;
}

extern "C" {
  template<typename T> class D; // expected-error{{templates must have C++ linkage}}
}

extern "C" {
  class PR17968 {
    template<typename T> class D; // expected-error{{templates must have C++ linkage}}
    template<typename T> void f(); // expected-error{{templates must have C++ linkage}}
  };
}

template<class U> class A; // expected-note{{previous template declaration is here}}

template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}

template<int N> class NonTypeTemplateParm;

typedef int INT;

template<INT M> class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}}

template<long> class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}}

template<template<typename T> class X> class TemplateTemplateParm;

template<template<class> class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \
      // expected-note{{previous template template parameter is here}}

template<typename> class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}}

template<template<typename T, int> class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}}

template<typename T>
struct test {}; // expected-note{{previous definition}}

template<typename T>
struct test : T {}; // expected-error{{redefinition}}

class X {
public:
  template<typename T> class C;
};

void f() {
  template<typename T> class X; // expected-error{{expression}}
}

template<typename T> class X1 var; // expected-warning{{variable templates are a C++1y extension}} \
                                   // expected-error {{variable has incomplete type 'class X1'}} \
                                   // expected-note {{forward declaration of 'X1'}}

namespace M {
}

template<typename T> class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}}

namespace PR8001 {
  template<typename T1>
  struct Foo {
    template<typename T2> class Bar;
    typedef Bar<T1> Baz;

   template<typename T2>
   struct Bar {
     Bar() {}
   };
  };

  void pr8001() {
    Foo<int>::Baz x;
    Foo<int>::Bar<int> y(x);
  }
}

namespace rdar9676205 {
  template <unsigned, class _Tp> class tuple_element;

  template <class _T1, class _T2> class pair;

  template <class _T1, class _T2>
  class tuple_element<0, pair<_T1, _T2> >
  {
    template <class _Tp>
    struct X
    {
      template <class _Up, bool = X<_Up>::value>
      struct Y
        : public X<_Up>,
          public Y<_Up>
      { };
    };
  };
}

namespace redecl {
  int A; // expected-note {{here}}
  template<typename T> struct A; // expected-error {{different kind of symbol}}

  int B; // expected-note {{here}}
  template<typename T> struct B { // expected-error {{different kind of symbol}}
  };

  template<typename T> struct F;
  template<typename T> struct K;

  int G, H; // expected-note {{here}}

  struct S {
    int C; // expected-note {{here}}
    template<typename T> struct C; // expected-error {{different kind of symbol}}

    int D; // expected-note {{here}}
    template<typename T> struct D { // expected-error {{different kind of symbol}}
    };

    int E;
    template<typename T> friend struct E { // expected-error {{cannot define a type in a friend}}
    };

    int F;
    template<typename T> friend struct F; // ok, redecl::F

    template<typename T> struct G; // ok

    template<typename T> friend struct H; // expected-error {{different kind of symbol}}

    int I, J, K;

    struct U {
      template<typename T> struct I; // ok
      template<typename T> struct J { // ok
      };
      template<typename T> friend struct K; // ok, redecl::K
    };
  };
}