diff options
author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
---|---|---|
committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/SemaTemplate/friend-template.cpp | |
parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/SemaTemplate/friend-template.cpp')
-rw-r--r-- | clang/test/SemaTemplate/friend-template.cpp | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/friend-template.cpp b/clang/test/SemaTemplate/friend-template.cpp new file mode 100644 index 0000000..9c95fa0 --- /dev/null +++ b/clang/test/SemaTemplate/friend-template.cpp @@ -0,0 +1,245 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// PR5057 +namespace test0 { + namespace std { + class X { + public: + template<typename T> friend struct Y; + }; + } + + namespace std { + template<typename T> struct Y {}; + } +} + +namespace test1 { + template<typename T> void f1(T) { } // expected-note{{here}} + + class X { + template<typename T> friend void f0(T); + template<typename T> friend void f1(T); + }; + + template<typename T> void f0(T) { } + template<typename T> void f1(T) { } // expected-error{{redefinition}} +} + +// PR4768 +namespace test2 { + template<typename T> struct X0 { + template<typename U> friend struct X0; + }; + + template<typename T> struct X0<T*> { + template<typename U> friend struct X0; + }; + + template<> struct X0<int> { + template<typename U> friend struct X0; + }; + + template<typename T> struct X1 { + template<typename U> friend void f2(U); + template<typename U> friend void f3(U); + }; + + template<typename U> void f2(U); + + X1<int> x1i; + X0<int*> x0ip; + + template<> void f2(int); + + // FIXME: Should this declaration of f3 be required for the specialization of + // f3<int> (further below) to work? GCC and EDG don't require it, we do... + template<typename U> void f3(U); + + template<> void f3(int); +} + +// PR5332 +namespace test3 { + template <typename T> class Foo { + template <typename U> + friend class Foo; + }; + + Foo<int> foo; + + template<typename T, T Value> struct X2a; + + template<typename T, int Size> struct X2b; + + template<typename T> + class X3 { + template<typename U, U Value> friend struct X2a; + + // FIXME: the redeclaration note ends up here because redeclaration + // lookup ends up finding the friend target from X3<int>. + template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \ + // expected-note {{previous non-type template parameter with type 'int' is here}} + }; + + X3<int> x3i; // okay + + X3<long> x3l; // expected-note {{in instantiation}} +} + +// PR5716 +namespace test4 { + template<typename> struct A { + template<typename T> friend void f(const A<T>&); + }; + + template<typename T> void f(const A<T>&) { + int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}} + } + + void f() { + f(A<int>()); // expected-note {{in instantiation of function template specialization}} + } +} + +namespace test5 { + class outer { + class foo; + template <typename T> friend struct cache; + }; + class outer::foo { + template <typename T> friend struct cache; + }; +} + +// PR6022 +namespace PR6022 { + template <class T1, class T2 , class T3 > class A; + + namespace inner { + template<class T1, class T2, class T3, class T> + A<T1, T2, T3>& f0(A<T1, T2, T3>&, T); + } + + template<class T1, class T2, class T3> + class A { + template<class U1, class U2, class U3, class T> + friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T); + }; +} + +namespace FriendTemplateDefinition { + template<unsigned > struct int_c { }; + + template<typename T> + struct X { + template<unsigned N> + friend void f(X, int_c<N>) { + int value = N; + }; + }; + + void test_X(X<int> x, int_c<5> i5) { + f(x, i5); + } +} + +namespace PR7013a { + template<class > struct X0 + { + typedef int type; + }; + template<typename > struct X1 + { + }; + template<typename , typename T> struct X2 + { + typename T::type e; + }; + namespace N + { + template <typename = int, typename = X1<int> > struct X3 + { + template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B); + }; + template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B) + { + X2<int, Tr> s; + } + } + int n() + { + X2<int, X0<int> > ngs; + N::X3<> b; + op(ngs, b); + return 0; + } +} + +namespace PR7013b { + template<class > struct X0 + { + typedef int type; + }; + template<typename > struct X1 + { + }; + template<typename , typename T> struct X2 + { + typename T::type e; + }; + namespace N + { + template <typename = X1<int> > struct X3 + { + template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B); + }; + template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B) + { + X2<int, Tr> s; + } + } + int n() + { + X2<int, X0<int> > ngs; + N::X3<> b; + op(ngs, b); + return 0; + } + +} + +namespace PR8649 { + template<typename T, typename U, unsigned N> + struct X { + template<unsigned M> friend class X<T, U, M>; // expected-error{{partial specialization cannot be declared as a friend}} + }; + + X<int, float, 7> x; +} + +// Don't crash, and error on invalid friend type template. +namespace friend_type_template_no_tag { + template <typename T> struct S { + template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}} + }; + template struct S<int>; +} + +namespace PR10660 { + struct A { + template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}} + }; +} + +namespace rdar11147355 { + template <class T> + struct A { + template <class U> class B; + template <class S> template <class U> friend class A<S>::B; + }; + + template <class S> template <class U> class A<S>::B { + }; + + A<double>::B<double> ab; +} |