2017-04-18 04:57:40 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2009-09-26 14:47:28 +08:00
// PR5057
2009-12-12 04:51:23 +08:00
namespace test0 {
namespace std {
class X {
public :
template < typename T > friend struct Y ;
} ;
}
namespace std {
template < typename T > struct Y { } ;
}
2009-09-26 14:47:28 +08:00
}
2009-12-12 04:51:23 +08:00
namespace test1 {
2009-09-28 08:08:27 +08:00
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}}
}
2009-10-10 05:11:42 +08:00
// PR4768
2009-12-12 04:51:23 +08:00
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 ;
} ;
2009-10-10 05:11:42 +08:00
2009-12-12 04:51:23 +08:00
template < > struct X0 < int > {
template < typename U > friend struct X0 ;
} ;
2009-10-13 22:39:41 +08:00
2009-12-12 04:51:23 +08:00
template < typename T > struct X1 {
template < typename U > friend void f2 ( U ) ;
template < typename U > friend void f3 ( U ) ;
} ;
2009-10-13 22:39:41 +08:00
2009-12-12 04:51:23 +08:00
template < typename U > void f2 ( U ) ;
2009-10-13 22:39:41 +08:00
2009-12-12 04:51:23 +08:00
X1 < int > x1i ;
X0 < int * > x0ip ;
2009-10-13 22:39:41 +08:00
2009-12-12 04:51:23 +08:00
template < > void f2 ( int ) ;
2009-10-13 22:39:41 +08:00
2009-12-12 04:51:23 +08:00
// 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 ) ;
2009-10-13 22:39:41 +08:00
2009-12-12 04:51:23 +08:00
template < > void f3 ( int ) ;
}
2009-10-31 05:07:27 +08:00
// PR5332
2009-12-12 04:51:23 +08:00
namespace test3 {
template < typename T > class Foo {
template < typename U >
friend class Foo ;
} ;
2009-10-31 06:42:42 +08:00
2009-12-12 04:51:23 +08:00
Foo < int > foo ;
2009-10-31 06:42:42 +08:00
2009-12-12 04:51:23 +08:00
template < typename T , T Value > struct X2a ;
2017-04-18 04:57:40 +08:00
template < typename T , int Size > struct X2b ;
2009-10-31 06:42:42 +08:00
2009-12-12 04:51:23 +08:00
template < typename T >
class X3 {
template < typename U , U Value > friend struct X2a ;
2017-04-18 04:57:40 +08:00
// 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}}
2009-12-12 04:51:23 +08:00
} ;
2009-10-31 06:42:42 +08:00
2009-12-12 04:51:23 +08:00
X3 < int > x3i ; // okay
2009-10-31 06:42:42 +08:00
2010-03-25 14:39:04 +08:00
X3 < long > x3l ; // expected-note {{in instantiation}}
2009-12-12 04:51:23 +08:00
}
2009-12-15 07:19:40 +08:00
// PR5716
namespace test4 {
template < typename > struct A {
template < typename T > friend void f ( const A < T > & ) ;
} ;
template < typename T > void f ( const A < T > & ) {
2011-01-04 12:44:35 +08:00
int a [ sizeof ( T ) ? - 1 : - 1 ] ; // expected-error {{array with a negative size}}
2009-12-15 07:19:40 +08:00
}
void f ( ) {
f ( A < int > ( ) ) ; // expected-note {{in instantiation of function template specialization}}
}
}
2009-12-18 19:25:59 +08:00
namespace test5 {
class outer {
class foo ;
template < typename T > friend struct cache ;
} ;
class outer : : foo {
template < typename T > friend struct cache ;
} ;
}
2010-01-17 02:09:52 +08:00
// 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 ) ;
} ;
}
2010-04-28 12:52:24 +08:00
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 ) ;
}
}
2010-05-04 07:29:10 +08:00
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 ;
}
}
2010-12-21 16:14:57 +08:00
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 ;
}
2011-05-04 02:35:10 +08:00
// 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 > ;
}
2011-10-20 23:58:54 +08:00
namespace PR10660 {
struct A {
template < > friend class B ; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
} ;
}
2012-03-31 00:20:47 +08:00
namespace rdar11147355 {
2013-11-09 02:59:56 +08:00
template < class T >
2012-03-31 00:20:47 +08:00
struct A {
template < class U > class B ;
2013-11-09 02:59:56 +08:00
template < class S > template < class U > friend class A < S > : : B ; // expected-warning {{dependent nested name specifier 'A<S>::' for friend template declaration is not supported; ignoring this friend declaration}}
private :
int n ; // expected-note {{here}}
2012-03-31 00:20:47 +08:00
} ;
2013-11-09 02:59:56 +08:00
2012-03-31 00:20:47 +08:00
template < class S > template < class U > class A < S > : : B {
2013-11-09 02:59:56 +08:00
public :
// FIXME: This should be permitted.
int f ( A < S * > a ) { return a . n ; } // expected-error {{private}}
} ;
2012-03-31 00:20:47 +08:00
A < double > : : B < double > ab ;
2013-11-09 02:59:56 +08:00
A < double * > a ;
int k = ab . f ( a ) ; // expected-note {{instantiation of}}
2012-03-31 00:20:47 +08:00
}
2012-04-20 15:12:26 +08:00
namespace RedeclUnrelated {
struct S {
int packaged_task ;
template < typename > class future {
template < typename > friend class packaged_task ;
} ;
future < void > share ;
} ;
}
namespace PR12557 {
template < typename >
struct Foo ;
template < typename Foo_ >
struct Bar {
typedef Foo_ Foo ; // expected-note {{previous}}
template < typename > friend struct Foo ; // expected-error {{redefinition of 'Foo' as different kind of symbol}}
} ;
Bar < int > b ;
}
2012-04-22 10:13:50 +08:00
namespace PR12585 {
struct A { } ;
template < typename > struct B {
template < typename > friend class A : : does_not_exist ; / / \
// expected-error {{friend declaration of 'does_not_exist' does not match any declaration in 'PR12585::A'}}
} ;
struct C {
template < typename > struct D ;
} ;
template < typename > class E {
int n ;
template < typename > friend struct C : : D ;
} ;
template < typename T > struct C : : D {
int f ( ) {
return E < int > ( ) . n ;
}
} ;
int n = C : : D < void * > ( ) . f ( ) ;
struct F {
2017-04-18 04:57:40 +08:00
template < int > struct G ;
2012-04-22 10:13:50 +08:00
} ;
template < typename T > struct H {
2017-04-18 04:57:40 +08:00
// FIXME: As with cases above, the note here is on an unhelpful declaration,
// and should point to the declaration of G within F.
2012-04-22 10:13:50 +08:00
template < T > friend struct F : : G ; / / \
2017-04-18 04:57:40 +08:00
/ / expected - error { { different type ' char ' in template redeclaration } } \
// expected-note {{previous}}
2012-04-22 10:13:50 +08:00
} ;
H < int > h1 ; // ok
H < char > h2 ; // expected-note {{instantiation}}
}
2013-03-14 13:13:41 +08:00
// Ensure that we can still instantiate a friend function template
// after the friend declaration is instantiated during the delayed
// parsing of a member function, but before the friend function has
// been parsed.
namespace rdar12350696 {
template < class T > struct A {
void foo ( ) {
A < int > a ;
}
template < class U > friend void foo ( const A < U > & a ) {
int array [ sizeof ( T ) = = sizeof ( U ) ? - 1 : 1 ] ; // expected-error {{negative size}}
}
} ;
void test ( ) {
A < int > b ;
foo ( b ) ; // expected-note {{in instantiation}}
}
}