2014-07-09 05:35:03 +08:00
// RUN: %clang_cc1 -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
2011-09-07 08:14:57 +08:00
template < class T >
class A {
public :
void f ( T a ) { } // expected-note {{must qualify identifier to find this declaration in dependent base class}}
void g ( ) ; // expected-note {{must qualify identifier to find this declaration in dependent base class}}
} ;
template < class T >
class B : public A < T > {
public :
void z ( T a )
{
f ( a ) ; // expected-warning {{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
g ( ) ; // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
}
} ;
template class B < int > ; // expected-note {{requested here}}
template class B < char > ;
void test ( )
{
B < int > b ;
b . z ( 3 ) ;
}
2013-04-29 16:45:27 +08:00
struct A2 {
template < class T > void f ( T ) {
XX ; //expected-error {{use of undeclared identifier 'XX'}}
A2 : : XX ; //expected-error {{no member named 'XX' in 'A2'}}
}
} ;
template void A2 : : f ( int ) ;
template < class T0 >
struct A3 {
template < class T1 > void f ( T1 ) {
XX ; //expected-error {{use of undeclared identifier 'XX'}}
}
} ;
template void A3 < int > : : f ( int ) ;
template < class T0 >
struct A4 {
void f ( char ) {
XX ; //expected-error {{use of undeclared identifier 'XX'}}
}
} ;
template class A4 < int > ;
2011-11-11 08:12:11 +08:00
namespace lookup_dependent_bases_id_expr {
template < class T > class A {
public :
int var ;
} ;
template < class T >
class B : public A < T > {
public :
void f ( ) {
2014-06-11 08:01:28 +08:00
var = 3 ; // expected-warning {{use of undeclared identifier 'var'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}}
2011-11-11 08:12:11 +08:00
}
} ;
template class B < int > ;
}
2011-09-07 08:14:57 +08:00
2011-11-16 07:33:34 +08:00
namespace lookup_dependent_base_class_static_function {
template < class T >
class A {
public :
static void static_func ( ) ; // expected-note {{must qualify identifier to find this declaration in dependent base class}}
void func ( ) ; // expected-note {{must qualify identifier to find this declaration in dependent base class}}
} ;
template < class T >
class B : public A < T > {
public :
static void z2 ( ) {
static_func ( ) ; // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
2011-11-17 11:44:24 +08:00
func ( ) ; // expected-warning {{use of identifier 'func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
2011-11-16 07:33:34 +08:00
}
} ;
template class B < int > ; // expected-note {{requested here}}
}
2011-11-17 11:44:24 +08:00
namespace lookup_dependent_base_class_default_argument {
template < class T >
class A {
public :
static int f1 ( ) ; // expected-note {{must qualify identifier to find this declaration in dependent base class}}
int f2 ( ) ; // expected-note {{must qualify identifier to find this declaration in dependent base class}}
} ;
template < class T >
class B : public A < T > {
public :
void g1 ( int p = f1 ( ) ) ; // expected-warning {{use of identifier 'f1' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
void g2 ( int p = f2 ( ) ) ; // expected-warning {{use of identifier 'f2' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
} ;
void foo ( )
{
B < int > b ;
b . g1 ( ) ; // expected-note {{required here}}
b . g2 ( ) ; // expected-note {{required here}}
}
2011-11-25 09:10:54 +08:00
}
namespace lookup_dependent_base_class_friend {
template < class T >
class B {
public :
static void g ( ) ; // expected-note {{must qualify identifier to find this declaration in dependent base class}}
} ;
template < class T >
class A : public B < T > {
public :
friend void foo ( A < T > p ) {
g ( ) ; // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
}
} ;
int main2 ( )
{
A < int > a ;
foo ( a ) ; // expected-note {{requested here}}
}
}
2011-12-03 23:55:29 +08:00
namespace lookup_dependent_base_no_typo_correction {
class C {
public :
int m_hWnd ;
} ;
template < class T >
class A : public T {
public :
void f ( int hWnd ) {
2014-06-11 08:01:28 +08:00
m_hWnd = 1 ; // expected-warning {{use of undeclared identifier 'm_hWnd'; unqualified lookup into dependent bases of class template 'A' is a Microsoft extension}}
2011-12-03 23:55:29 +08:00
}
} ;
template class A < C > ;
}
2012-06-21 04:21:42 +08:00
namespace PR12701 {
class A { } ;
class B { } ;
template < class T >
class Base {
public :
2013-12-06 00:25:25 +08:00
bool base_fun ( void * p ) { return false ; } // expected-note {{must qualify identifier to find this declaration in dependent base class}}
2012-06-21 04:21:42 +08:00
operator T * ( ) const { return 0 ; }
} ;
template < class T >
class Container : public Base < T > {
public :
template < typename S >
bool operator = ( const Container < S > & rhs ) {
return base_fun ( rhs ) ; // expected-warning {{use of identifier 'base_fun' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
}
} ;
void f ( ) {
Container < A > text_provider ;
Container < B > text_provider2 ;
text_provider2 = text_provider ; // expected-note {{in instantiation of function template specialization}}
}
} // namespace PR12701
2013-10-16 02:38:02 +08:00
namespace PR16014 {
struct A {
int a ;
static int sa ;
} ;
template < typename T > struct B : T {
2014-06-11 08:01:28 +08:00
int foo ( ) { return a ; } // expected-warning {{lookup into dependent bases}}
int * bar ( ) { return & a ; } // expected-warning {{lookup into dependent bases}}
2013-10-16 02:38:02 +08:00
int baz ( ) { return T : : a ; }
int T : : * qux ( ) { return & T : : a ; }
static int T : : * stuff ( ) { return & T : : a ; }
static int stuff1 ( ) { return T : : sa ; }
static int * stuff2 ( ) { return & T : : sa ; }
2014-06-11 08:01:28 +08:00
static int stuff3 ( ) { return sa ; } // expected-warning {{lookup into dependent bases}}
static int * stuff4 ( ) { return & sa ; } // expected-warning {{lookup into dependent bases}}
2013-10-16 02:38:02 +08:00
} ;
template < typename T > struct C : T {
2014-06-11 08:01:28 +08:00
int foo ( ) { return b ; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
int * bar ( ) { return & b ; } // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
2013-10-16 02:38:02 +08:00
int baz ( ) { return T : : b ; } // expected-error {{no member named 'b' in 'PR16014::A'}}
int T : : * qux ( ) { return & T : : b ; } // expected-error {{no member named 'b' in 'PR16014::A'}}
2014-08-15 07:34:52 +08:00
int T : : * fuz ( ) { return & U : : a ; } / / expected - error { { use of undeclared identifier ' U ' } } \
// expected-warning {{unqualified lookup into dependent bases of class template 'C'}}
2013-10-16 02:38:02 +08:00
} ;
template struct B < A > ;
2013-12-14 09:07:05 +08:00
template struct C < A > ; // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}
2013-10-16 02:38:02 +08:00
template < typename T > struct D : T {
struct Inner {
int foo ( ) {
// FIXME: MSVC can find this in D's base T! Even worse, if ::sa exists,
// clang will use it instead.
return sa ; // expected-error {{use of undeclared identifier 'sa'}}
}
} ;
} ;
template struct D < A > ;
}
2014-03-26 04:31:28 +08:00
namespace PR19233 {
template < class T >
struct A : T {
void foo ( ) {
: : undef ( ) ; // expected-error {{no member named 'undef' in the global namespace}}
}
void bar ( ) {
: : UndefClass : : undef ( ) ; // expected-error {{no member named 'UndefClass' in the global namespace}}
}
void baz ( ) {
2014-08-15 07:34:52 +08:00
B : : qux ( ) ; / / expected - error { { use of undeclared identifier ' B ' } } \
// expected-warning {{unqualified lookup into dependent bases of class template 'A'}}
2014-03-26 04:31:28 +08:00
}
} ;
struct B { void qux ( ) ; } ;
struct C : B { } ;
template struct A < C > ; // No error! B is a base of A<C>, and qux is available.
struct D { } ;
template struct A < D > ; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}
}
2014-06-11 08:01:28 +08:00
namespace nonmethod_missing_this {
template < typename T > struct Base { int y = 42 ; } ;
template < typename T > struct Derived : Base < T > {
int x = y ; // expected-warning {{lookup into dependent bases}}
auto foo ( int j ) - > decltype ( y * j ) { // expected-warning {{lookup into dependent bases}}
return y * j ; // expected-warning {{lookup into dependent bases}}
}
int bar ( ) {
return [ & ] { return y ; } ( ) ; // expected-warning {{lookup into dependent bases}}
}
} ;
template struct Derived < int > ;
}
2014-07-09 04:05:48 +08:00
namespace typedef_in_base {
template < typename T > struct A { typedef T NameFromBase ; } ;
template < typename T > struct B : A < T > {
NameFromBase m ; // expected-warning {{found via unqualified lookup into dependent bases}}
} ;
static_assert ( sizeof ( B < int > ) = = 4 , " " ) ;
}
namespace struct_in_base {
template < typename T > struct A { struct NameFromBase { } ; } ;
template < typename T > struct B : A < T > {
NameFromBase m ; // expected-warning {{found via unqualified lookup into dependent bases}}
} ;
static_assert ( sizeof ( B < int > ) = = 1 , " " ) ;
}
namespace enum_in_base {
template < typename T > struct A { enum NameFromBase { X } ; } ;
template < typename T > struct B : A < T > {
NameFromBase m ; // expected-warning {{found via unqualified lookup into dependent bases}}
} ;
static_assert ( sizeof ( B < int > ) = = sizeof ( A < int > : : NameFromBase ) , " " ) ;
}
namespace two_types_in_base {
template < typename T > struct A { typedef T NameFromBase ; } ;
template < typename T > struct B { struct NameFromBase { T m ; } ; } ;
template < typename T > struct C : A < T > , B < T > {
NameFromBase m ; // expected-error {{unknown type name 'NameFromBase'}}
} ;
static_assert ( sizeof ( C < int > ) = = 4 , " " ) ;
}
namespace type_and_decl_in_base {
template < typename T > struct A { typedef T NameFromBase ; } ;
template < typename T > struct B { static const T NameFromBase = 42 ; } ;
template < typename T > struct C : A < T > , B < T > {
NameFromBase m ; // expected-error {{unknown type name 'NameFromBase'}}
} ;
}
namespace classify_type_from_base {
template < typename T > struct A { struct NameFromBase { } ; } ;
template < typename T > struct B : A < T > {
A < NameFromBase > m ; // expected-warning {{found via unqualified lookup into dependent bases}}
} ;
}
namespace classify_nontype_from_base {
// MSVC does not do lookup of non-type declarations from dependent template base
// classes. The extra lookup only applies to types.
template < typename T > struct A { void NameFromBase ( ) { } } ;
template < void ( * F ) ( ) > struct B { } ;
template < typename T > struct C : A < T > {
B < C : : NameFromBase > a ; // correct
B < NameFromBase > b ; // expected-error {{use of undeclared identifier 'NameFromBase'}}
} ;
}
namespace template_in_base {
template < typename T > struct A {
template < typename U > struct NameFromBase { U x ; } ;
} ;
template < typename T > struct B : A < T > {
// Correct form.
typename B : : template NameFromBase < T > m ;
} ;
template < typename T > struct C : A < T > {
// Incorrect form.
NameFromBase < T > m ; // expected-error {{unknown type name 'NameFromBase'}}
//expected-error@-1 {{expected member name or ';' after declaration specifiers}}
} ;
}
namespace type_in_inner_class_in_base {
template < typename T >
struct A {
struct B { typedef T NameFromBase ; } ;
} ;
template < typename T >
struct C : A < T > : : B { NameFromBase m ; } ; // expected-error {{unknown type name 'NameFromBase'}}
}
namespace type_in_inner_template_class_in_base {
template < typename T >
struct A {
template < typename U > struct B { typedef U InnerType ; } ;
} ;
template < typename T >
struct C : A < T > : : template B < T > {
NameFromBase m ; // expected-error {{unknown type name 'NameFromBase'}}
} ;
}
namespace have_nondependent_base {
template < typename T >
struct A {
// Nothing, lookup should fail.
} ;
template < typename T >
struct B : A < T > { NameFromBase m ; } ; // expected-error {{unknown type name 'NameFromBase'}}
struct C : A < int > { NameFromBase m ; } ; // expected-error {{unknown type name 'NameFromBase'}}
}
2014-07-09 05:35:03 +08:00
namespace type_in_base_of_dependent_base {
struct A { typedef int NameFromBase ; } ;
template < typename T >
struct B : A { } ;
// FIXME: MSVC accepts this.
template < typename T >
struct C : B < T > { NameFromBase m ; } ; // expected-error {{unknown type name 'NameFromBase'}}
}
2014-07-09 04:05:48 +08:00
namespace lookup_in_function_contexts {
template < typename T > struct A { typedef T NameFromBase ; } ;
template < typename T >
struct B : A < T > {
// expected-warning@+1 {{lookup into dependent bases}}
static auto lateSpecifiedFunc ( ) - > decltype ( NameFromBase ( ) ) {
return { } ;
}
static void memberFunc ( ) {
2014-07-09 05:35:03 +08:00
NameFromBase x ; // expected-warning {{lookup into dependent bases}}
2014-07-09 04:05:48 +08:00
}
static void funcLocalClass ( ) {
struct X {
2014-07-09 05:35:03 +08:00
NameFromBase x ; // expected-warning {{lookup into dependent bases}}
2014-07-09 04:05:48 +08:00
} y ;
}
void localClassMethod ( ) {
struct X {
void bar ( ) {
2014-07-09 05:35:03 +08:00
NameFromBase m ; // expected-warning {{lookup into dependent bases}}
2014-07-09 04:05:48 +08:00
}
} x ;
x . bar ( ) ;
}
static void funcLambda ( ) {
auto l = [ ] ( ) {
2014-07-09 05:35:03 +08:00
NameFromBase x ; // expected-warning {{lookup into dependent bases}}
2014-07-09 04:05:48 +08:00
} ;
l ( ) ;
}
static constexpr int constexprFunc ( ) {
2014-07-09 05:35:03 +08:00
NameFromBase x = { } ; // expected-warning {{lookup into dependent bases}}
2014-07-09 04:05:48 +08:00
return sizeof ( x ) ;
}
static auto autoFunc ( ) {
2014-07-09 05:35:03 +08:00
NameFromBase x ; // expected-warning {{lookup into dependent bases}}
2014-07-09 04:05:48 +08:00
return x ;
}
} ;
// Force us to parse the methods.
template struct B < int > ;
}
namespace function_template_deduction {
// Overloaded function templates.
template < int N > int f ( ) { return N ; }
template < typename T > int f ( ) { return sizeof ( T ) ; }
// Dependent base class with type.
template < typename T >
struct A { typedef T NameFromBase ; } ;
template < typename T >
struct B : A < T > {
// expected-warning@+1 {{found via unqualified lookup into dependent bases}}
int x = f < NameFromBase > ( ) ;
} ;
// Dependent base class with enum.
template < typename T > struct C { enum { NameFromBase = 4 } ; } ;
template < typename T > struct D : C < T > {
// expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
int x = f < NameFromBase > ( ) ;
} ;
}
2014-08-15 07:34:52 +08:00
namespace function_template_undef_impl {
template < class T >
void f ( ) {
Undef : : staticMethod ( ) ; // expected-error {{use of undeclared identifier 'Undef'}}
UndefVar . method ( ) ; // expected-error {{use of undeclared identifier 'UndefVar'}}
}
}