1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
2 | template<typename T, typename U> // expected-note{{previous template}} |
3 | class X0 { |
4 | public: |
5 | typedef int size_type; |
6 | |
7 | X0(int); |
8 | ~X0(); |
9 | |
10 | void f0(const T&, const U&); |
11 | |
12 | T& operator[](int i) const; |
13 | |
14 | void f1(size_type) const; |
15 | void f2(size_type) const; |
16 | void f3(size_type) const; |
17 | void f4() ; |
18 | |
19 | operator T*() const; |
20 | |
21 | T value; |
22 | }; |
23 | |
24 | template<typename T, typename U> |
25 | void X0<T, U>::f0(const T&, const U&) { // expected-note{{previous definition}} |
26 | } |
27 | |
28 | template<class X, class Y> |
29 | X& X0<X, Y>::operator[](int i) const { |
30 | (void)i; |
31 | return value; |
32 | } |
33 | |
34 | template<class X, class Y> |
35 | void X0<X, Y>::f1(int) const { } |
36 | |
37 | template<class X, class Y> |
38 | void X0<X, Y>::f2(size_type) const { } |
39 | |
40 | template<class X, class Y, class Z> // expected-error{{too many template parameters}} |
41 | void X0<X, Y>::f3(size_type) const { |
42 | } |
43 | |
44 | template<class X, class Y> |
45 | void X0<Y, X>::f4() { } // expected-error{{does not refer}} |
46 | |
47 | // FIXME: error message should probably say, "redefinition of 'X0<T, U>::f0'" |
48 | // rather than just "redefinition of 'f0'" |
49 | template<typename T, typename U> |
50 | void X0<T, U>::f0(const T&, const U&) { // expected-error{{redefinition}} |
51 | } |
52 | |
53 | // Test out-of-line constructors, destructors |
54 | template<typename T, typename U> |
55 | X0<T, U>::X0(int x) : value(x) { } |
56 | |
57 | template<typename T, typename U> |
58 | X0<T, U>::~X0() { } |
59 | |
60 | // Test out-of-line conversion functions. |
61 | template<typename T, typename U> |
62 | X0<T, U>::operator T*() const { |
63 | return &value; |
64 | } |
65 | |
66 | namespace N { template <class X> class A {void a();}; } |
67 | namespace N { template <class X> void A<X>::a() {} } |
68 | |
69 | // PR5566 |
70 | template<typename T> |
71 | struct X1 { |
72 | template<typename U> |
73 | struct B { void f(); }; |
74 | }; |
75 | |
76 | template<typename T> |
77 | template<typename U> |
78 | void X1<T>::template B<U>::f() { } |
79 | |
80 | // PR5527 |
81 | template <template <class> class T> |
82 | class X2 { |
83 | template <class F> |
84 | class Bar { |
85 | void Func(); |
86 | }; |
87 | }; |
88 | |
89 | template <template <class> class T> |
90 | template <class F> |
91 | void X2<T>::Bar<F>::Func() {} |
92 | |
93 | // PR5528 |
94 | template <template <class> class T> |
95 | class X3 { |
96 | void F(); |
97 | }; |
98 | |
99 | template <template <class> class T> |
100 | void X3<T>::F() {} |
101 | |