From 1e67dd6b2f6acd5e49551579335bce5d9c501dc9 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 27 Apr 2010 01:43:38 +0000 Subject: [PATCH] Improve the diagnostic you get when making a qualified member access with a qualifier referencing a different type. llvm-svn: 102409 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 +++--- clang/lib/Sema/SemaDeclCXX.cpp | 2 +- clang/lib/Sema/SemaExpr.cpp | 7 ++----- clang/test/SemaCXX/qual-id-test.cpp | 6 +++--- clang/test/SemaTemplate/instantiate-member-expr.cpp | 2 +- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 029b5ae99a25..94f1df164375 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -564,6 +564,8 @@ def err_non_virtual_pure : Error< def err_implicit_object_parameter_init : Error< "cannot initialize object parameter of type %0 with an expression " "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_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 " "inherited virtual base class">; def err_not_direct_base_or_virtual : Error< - "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'">; + "type %0 is not a direct or virtual base of %1">; def err_in_class_initializer_non_integral_type : Error< "in-class initializer has non-integral, non-enumeration type %0">; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index eee857438687..f6ff40010ceb 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1406,7 +1406,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, // mem-initializer is ill-formed. if (!DirectBaseSpec && !VirtualBaseSpec) return Diag(BaseLoc, diag::err_not_direct_base_or_virtual) - << BaseType << ClassDecl->getNameAsCString() + << BaseType << Context.getTypeDeclType(ClassDecl) << BaseTInfo->getTypeLoc().getSourceRange(); CXXBaseSpecifier *BaseSpec diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 3cfe53c65a3c..088ca96edd61 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2499,11 +2499,8 @@ static void DiagnoseQualifiedMemberReference(Sema &SemaRef, if (!BaseExpr) return DiagnoseInstanceReference(SemaRef, SS, R); - // FIXME: this is an exceedingly lame diagnostic for some of the more - // complicated cases here. - DeclContext *DC = R.getRepresentativeDecl()->getDeclContext(); - SemaRef.Diag(R.getNameLoc(), diag::err_not_direct_base_or_virtual) - << SS.getRange() << DC << BaseType; + SemaRef.Diag(R.getNameLoc(), diag::err_qualified_member_of_unrelated) + << SS.getRange() << R.getRepresentativeDecl() << BaseType; } // Check whether the declarations we found through a nested-name diff --git a/clang/test/SemaCXX/qual-id-test.cpp b/clang/test/SemaCXX/qual-id-test.cpp index 4846e72e5926..e5c730677561 100644 --- a/clang/test/SemaCXX/qual-id-test.cpp +++ b/clang/test/SemaCXX/qual-id-test.cpp @@ -48,7 +48,7 @@ namespace C a.A::sub::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->member::foo(); @@ -69,7 +69,7 @@ namespace C a->A::sub::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)->member::foo(); @@ -107,7 +107,7 @@ namespace C a.A::B::base::x(); 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() { diff --git a/clang/test/SemaTemplate/instantiate-member-expr.cpp b/clang/test/SemaTemplate/instantiate-member-expr.cpp index fe5588d57cd4..188705ce2139 100644 --- a/clang/test/SemaTemplate/instantiate-member-expr.cpp +++ b/clang/test/SemaTemplate/instantiate-member-expr.cpp @@ -43,7 +43,7 @@ namespace test1 { int a; template struct B : A { void f() { - a = 0; // expected-error {{type 'test1::O' is not a direct or virtual base of ''test1::O::B''}} + a = 0; // expected-error {{'test1::O::a' is not a member of class 'test1::O::B'}} } }; };