2009-12-16 04:14:24 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2009-03-24 07:06:20 +08:00
template < typename T >
class X {
public :
2009-03-24 08:38:23 +08:00
void f ( T x ) ; // expected-error{{argument may not have 'void' type}}
2009-03-24 07:06:20 +08:00
void g ( T * ) ;
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
llvm-svn: 101029
2010-04-12 15:48:19 +08:00
static int h ( T , T ) ; // expected-error {{argument may not have 'void' type}}
2009-03-24 07:06:20 +08:00
} ;
int identity ( int x ) { return x ; }
void test ( X < int > * xi , int * ip , X < int ( int ) > * xf ) {
xi - > f ( 17 ) ;
xi - > g ( ip ) ;
xf - > f ( & identity ) ;
xf - > g ( identity ) ;
X < int > : : h ( 17 , 25 ) ;
X < int ( int ) > : : h ( identity , & identity ) ;
}
void test_bad ( ) {
2010-03-10 19:27:22 +08:00
X < void > xv ; // expected-note{{in instantiation of template class 'X<void>' requested here}}
2009-03-24 07:06:20 +08:00
}
template < typename T , typename U >
class Overloading {
public :
int & f ( T , T ) ; // expected-note{{previous declaration is here}}
float & f ( T , U ) ; // expected-error{{functions that differ only in their return type cannot be overloaded}}
} ;
void test_ovl ( Overloading < int , long > * oil , int i , long l ) {
int & ir = oil - > f ( i , i ) ;
float & fr = oil - > f ( i , l ) ;
}
void test_ovl_bad ( ) {
2010-03-10 19:27:22 +08:00
Overloading < float , float > off ; // expected-note{{in instantiation of template class 'Overloading<float, float>' requested here}}
2009-03-24 07:06:20 +08:00
}
2009-03-24 08:15:49 +08:00
template < typename T >
class HasDestructor {
2009-03-25 00:43:20 +08:00
public :
2009-03-24 08:15:49 +08:00
virtual ~ HasDestructor ( ) = 0 ;
} ;
int i = sizeof ( HasDestructor < int > ) ; // FIXME: forces instantiation, but
// the code below should probably instantiate by itself.
int abstract_destructor [ __is_abstract ( HasDestructor < int > ) ? 1 : - 1 ] ;
2009-03-25 00:43:20 +08:00
template < typename T >
class Constructors {
public :
Constructors ( const T & ) ;
Constructors ( const Constructors & other ) ;
} ;
void test_constructors ( ) {
Constructors < int > ci1 ( 17 ) ;
Constructors < int > ci2 = ci1 ;
}
2009-03-25 08:34:44 +08:00
template < typename T >
struct ConvertsTo {
operator T ( ) ;
} ;
void test_converts_to ( ConvertsTo < int > ci , ConvertsTo < int * > cip ) {
int i = ci ;
int * ip = cip ;
}
2009-08-24 23:23:48 +08:00
// PR4660
template < class T > struct A0 { operator T * ( ) ; } ;
template < class T > struct A1 ;
int * a ( A0 < int > & x0 , A1 < int > & x1 ) {
int * y0 = x0 ;
2009-12-19 16:11:05 +08:00
int * y1 = x1 ; // expected-error{{no viable conversion}}
2009-08-24 23:23:48 +08:00
}
2009-11-02 01:08:18 +08:00
struct X0Base {
int & f ( ) ;
2009-11-20 08:59:20 +08:00
int & g ( int ) ;
static double & g ( double ) ;
2009-11-02 01:08:18 +08:00
} ;
template < typename T >
struct X0 : X0Base {
} ;
template < typename U >
struct X1 : X0 < U > {
2009-11-20 08:59:20 +08:00
int & f2 ( ) {
2009-12-02 06:10:20 +08:00
return X0Base : : f ( ) ;
2009-11-20 08:59:20 +08:00
}
2009-11-02 01:08:18 +08:00
} ;
void test_X1 ( X1 < int > x1i ) {
int & ir = x1i . f2 ( ) ;
}
2009-11-20 08:59:20 +08:00
template < typename U >
struct X2 : X0Base , U {
int & f2 ( ) { return X0Base : : f ( ) ; }
} ;
template < typename T >
struct X3 {
void test ( T x ) {
double & d1 = X0Base : : g ( x ) ;
}
} ;
template struct X3 < double > ;
2010-04-14 09:27:20 +08:00
// Don't try to instantiate this, it's invalid.
namespace test1 {
template < class T > class A { } ;
template < class T > class B {
void foo ( A < test1 : : Undeclared > & a ) / / expected - error { { no member named ' Undeclared ' in namespace ' test1 ' } }
{ }
} ;
template class B < int > ;
}
2010-04-28 00:10:10 +08:00
namespace PR6947 {
template < class T >
struct X {
int f0 ( )
{
typedef void ( X : : * impl_fun_ptr ) ( ) ;
impl_fun_ptr pImpl = & X : : template
f0_impl1 < int > ;
}
private :
int f1 ( ) {
}
template < class Processor >
void f0_impl1 ( )
{
}
} ;
char g0 ( ) {
X < int > pc ;
pc . f0 ( ) ;
}
}
2010-05-03 23:32:18 +08:00
namespace PR7022 {
template < typename >
struct X1
{
typedef int state_t ( ) ;
state_t g ;
} ;
template < typename U = X1 < int > > struct X2
{
X2 ( U = U ( ) )
{
}
} ;
void m ( void )
{
typedef X2 < > X2_type ;
X2_type c ;
}
2012-07-13 12:12:04 +08:00
}
2010-05-03 23:32:18 +08:00
2012-07-13 12:12:04 +08:00
namespace SameSignatureAfterInstantiation {
template < typename T > struct S {
void f ( T * ) ; // expected-note {{previous}}
2013-12-14 09:07:05 +08:00
void f ( const T * ) ; // expected-error-re {{multiple overloads of 'f' instantiate to the same signature 'void (const int *){{( __attribute__\(\(thiscall\)\))?}}'}}
2012-07-13 12:12:04 +08:00
} ;
S < const int > s ; // expected-note {{instantiation}}
2010-05-03 23:32:18 +08:00
}
2015-01-02 09:33:12 +08:00
namespace PR22040 {
template < typename T > struct Foobar {
2018-03-16 21:36:56 +08:00
template < > void bazqux ( typename T : : type ) { } // expected-error 2{{cannot be used prior to '::' because it has no members}}
2015-01-02 09:33:12 +08:00
} ;
void test ( ) {
// FIXME: we should suppress the "no member" errors
Foobar < void > : : bazqux ( ) ; // expected-error{{no member named 'bazqux' in }} expected-note{{in instantiation of template class }}
Foobar < int > : : bazqux ( ) ; // expected-error{{no member named 'bazqux' in }} expected-note{{in instantiation of template class }}
Foobar < int > : : bazqux ( 3 ) ; // expected-error{{no member named 'bazqux' in }}
}
}
2015-01-09 14:10:21 +08:00
template < typename >
struct SpecializationOfGlobalFnInClassScope {
template < >
2015-01-09 15:36:13 +08:00
void : : Fn ( ) ; // expected-error{{cannot have a qualified name}}
} ;
class AbstractClassWithGlobalFn {
template < typename >
void : : f ( ) ; // expected-error{{cannot have a qualified name}}
virtual void f1 ( ) = 0 ;
2015-01-09 14:10:21 +08:00
} ;