Improve the diagnostic you get when making a qualified member access

with a qualifier referencing a different type.

llvm-svn: 102409
This commit is contained in:
John McCall 2010-04-27 01:43:38 +00:00
parent 2408e32096
commit 1e67dd6b2f
5 changed files with 10 additions and 13 deletions

View File

@ -564,6 +564,8 @@ def err_non_virtual_pure : Error<
def err_implicit_object_parameter_init : Error< def err_implicit_object_parameter_init : Error<
"cannot initialize object parameter of type %0 with an expression " "cannot initialize object parameter of type %0 with an expression "
"of type %1">; "of type %1">;
def err_qualified_member_of_unrelated : Error<
"%q0 is not a member of class %1">;
def note_field_decl : Note<"member is declared here">; def note_field_decl : Note<"member is declared here">;
def note_ivar_decl : Note<"ivar is declared here">; def note_ivar_decl : Note<"ivar is declared here">;
@ -2565,9 +2567,7 @@ def err_base_init_direct_and_virtual : Error<
"base class initializer %0 names both a direct base class and an " "base class initializer %0 names both a direct base class and an "
"inherited virtual base class">; "inherited virtual base class">;
def err_not_direct_base_or_virtual : Error< def err_not_direct_base_or_virtual : Error<
"type %0 is not a direct or virtual base of '%1'">; "type %0 is not a direct or virtual base of %1">;
def err_not_direct_base_or_virtual_multi : Error<
"type %0 is not a direct or virtual base of '%1'">;
def err_in_class_initializer_non_integral_type : Error< def err_in_class_initializer_non_integral_type : Error<
"in-class initializer has non-integral, non-enumeration type %0">; "in-class initializer has non-integral, non-enumeration type %0">;

View File

@ -1406,7 +1406,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
// mem-initializer is ill-formed. // mem-initializer is ill-formed.
if (!DirectBaseSpec && !VirtualBaseSpec) if (!DirectBaseSpec && !VirtualBaseSpec)
return Diag(BaseLoc, diag::err_not_direct_base_or_virtual) return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
<< BaseType << ClassDecl->getNameAsCString() << BaseType << Context.getTypeDeclType(ClassDecl)
<< BaseTInfo->getTypeLoc().getSourceRange(); << BaseTInfo->getTypeLoc().getSourceRange();
CXXBaseSpecifier *BaseSpec CXXBaseSpecifier *BaseSpec

View File

@ -2499,11 +2499,8 @@ static void DiagnoseQualifiedMemberReference(Sema &SemaRef,
if (!BaseExpr) if (!BaseExpr)
return DiagnoseInstanceReference(SemaRef, SS, R); return DiagnoseInstanceReference(SemaRef, SS, R);
// FIXME: this is an exceedingly lame diagnostic for some of the more SemaRef.Diag(R.getNameLoc(), diag::err_qualified_member_of_unrelated)
// complicated cases here. << SS.getRange() << R.getRepresentativeDecl() << BaseType;
DeclContext *DC = R.getRepresentativeDecl()->getDeclContext();
SemaRef.Diag(R.getNameLoc(), diag::err_not_direct_base_or_virtual)
<< SS.getRange() << DC << BaseType;
} }
// Check whether the declarations we found through a nested-name // Check whether the declarations we found through a nested-name

View File

@ -48,7 +48,7 @@ namespace C
a.A::sub::x(); a.A::sub::x();
a.A::B::base::x(); a.A::B::base::x();
a.bad::x(); // expected-error{{type 'bad' is not a direct or virtual base of ''A::sub''}} a.bad::x(); // expected-error{{'bad::x' is not a member of class 'A::sub'}}
a->foo(); a->foo();
a->member::foo(); a->member::foo();
@ -69,7 +69,7 @@ namespace C
a->A::sub::x(); a->A::sub::x();
a->A::B::base::x(); a->A::B::base::x();
a->bad::x(); // expected-error{{type 'bad' is not a direct or virtual base of ''A::sub''}} a->bad::x(); // expected-error{{'bad::x' is not a member of class 'A::sub'}}
(*a)->foo(); (*a)->foo();
(*a)->member::foo(); (*a)->member::foo();
@ -107,7 +107,7 @@ namespace C
a.A::B::base::x(); a.A::B::base::x();
a->A::member::foo(); a->A::member::foo();
a.bad::x(); // expected-error{{direct or virtual}} a.bad::x(); // expected-error{{'bad::x' is not a member of class 'A::sub'}}
} }
void test_fun5() { void test_fun5() {

View File

@ -43,7 +43,7 @@ namespace test1 {
int a; int a;
template<typename T> struct B : A<T> { template<typename T> struct B : A<T> {
void f() { void f() {
a = 0; // expected-error {{type 'test1::O' is not a direct or virtual base of ''test1::O::B<int>''}} a = 0; // expected-error {{'test1::O::a' is not a member of class 'test1::O::B<int>'}}
} }
}; };
}; };