]> granicus.if.org Git - clang/commitdiff
Improve diagnostics when an elaborated-type-specifer containing a
authorDouglas Gregor <dgregor@apple.com>
Wed, 31 Mar 2010 23:17:41 +0000 (23:17 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 31 Mar 2010 23:17:41 +0000 (23:17 +0000)
nested-name-specifier (e.g., "class T::foo") fails to find a tag
member in the scope nominated by the
nested-name-specifier. Previously, we gave a bland

  error: 'Nested' does not name a tag member in the specified scope

which didn't actually say where we were looking, which was rather
horrible when the nested-name-specifier was instantiated. Now, we give
something a bit better:

  error: no class named 'Nested' in 'NoDepBase<T>'

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100060 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
lib/Sema/TreeTransform.h
test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
test/SemaCXX/nested-name-spec.cpp
test/SemaTemplate/dependent-base-classes.cpp
test/SemaTemplate/instantiate-declref.cpp

index 24391649d13be2757e7805f2c3bedce7d51e03b0..4e177fbb1813eb85744279c424eadb739fde3ba1 100644 (file)
@@ -2182,7 +2182,7 @@ def err_invalid_declarator_global_scope : Error<
 def err_invalid_declarator_in_function : Error<
   "definition or redeclaration of %0 not allowed inside a function">;
 def err_not_tag_in_scope : Error<
-  "%0 does not name a tag member in the specified scope">;
+  "no %select{struct|union|class|enum}0 named %1 in %2">;
 
 def err_cannot_form_pointer_to_member_of_reference_type : Error<
   "cannot form a pointer-to-member to member %0 of reference type %1">;
index eef73d8d7f5b127f75a365db17f51749fbf6ec1b..f3d0dcff20c783b0e4ef767c1da262ee0430eb03 100644 (file)
@@ -4786,7 +4786,8 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
       }
 
       // A tag 'foo::bar' must already exist.
-      Diag(NameLoc, diag::err_not_tag_in_scope) << Name << SS.getRange();
+      Diag(NameLoc, diag::err_not_tag_in_scope) 
+        << Kind << Name << DC << SS.getRange();
       Name = 0;
       Invalid = true;
       goto CreateNewDecl;
index 9777569b31872a8e211bf509a39e7a3951a48d9d..3375ccc0ebcd170c23cb610162b956b000fac0ca 100644 (file)
@@ -693,7 +693,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
 
     if (!PrevClassTemplate && Qualifier) {
       SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope)
-        << Pattern->getDeclName() << Pattern->getQualifierRange();
+        << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC
+        << Pattern->getQualifierRange();
       return 0;
     }
 
index b08447e4805f48e5f876e865800a56d294ad370a..f9ffd3f41aa5bdbb58a88df54b373fba16f77f6b 100644 (file)
@@ -618,9 +618,9 @@ public:
     }
 
     if (!Tag) {
-      // FIXME: Crummy diagnostic
+      // FIXME: Would be nice to highlight just the source range.
       SemaRef.Diag(SR.getEnd(), diag::err_not_tag_in_scope)
-        << Id << SR;
+        << Kind << Id << DC;
       return QualType();
     }
     
index bfb4780cde8e2190c4127e2dc517d8ff982ba62c..c53031177323139a579919f0ad2c21e271e6083d 100644 (file)
@@ -40,10 +40,10 @@ void c2(class B<float>::Member);
 void c3(union B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
 void c4(enum B<float>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
 
-void d1(struct B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
-void d2(class B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
-void d3(union B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
-void d4(enum B<int>::Member); // expected-error {{'Member' does not name a tag member in the specified scope}}
+void d1(struct B<int>::Member); // expected-error {{no struct named 'Member' in 'B<int>'}}
+void d2(class B<int>::Member); // expected-error {{no class named 'Member' in 'B<int>'}}
+void d3(union B<int>::Member); // expected-error {{no union named 'Member' in 'B<int>'}}
+void d4(enum B<int>::Member); // expected-error {{no enum named 'Member' in 'B<int>'}}
 
 void e1(struct B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
 void e2(class B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
@@ -51,7 +51,7 @@ void e3(union B<A>::Member);
 void e4(enum B<A>::Member); // expected-error {{use of 'Member' with tag type that does not match previous declaration}}
 
 template <class T> struct C {
-  void foo(class B<T>::Member); // expected-error{{'Member' does not name a tag member in the specified scope}} \
+  void foo(class B<T>::Member); // expected-error{{no class named 'Member' in 'B<int>'}} \
                                 // expected-error{{use of 'Member' with tag type that does not match previous declaration}}
 };
 
index 8657c0dca0aec0824d3f5e063cfc7ee1fc0f097d..9a611c38ad6dad764643a5c5c8074bba51dc7773 100644 (file)
@@ -64,7 +64,7 @@ void f2() {
 A::C c1;
 struct A::C c2;
 struct S : public A::C {};
-struct A::undef; // expected-error {{'undef' does not name a tag member in the specified scope}}
+struct A::undef; // expected-error {{no struct named 'undef' in namespace 'A'}}
 
 namespace A2 {
   typedef int INT;
index 600115b5653063cdf2d48f88379e5ba67565764a..d0dd9c98fa713d005acea6ddd8a98a7192b9e048 100644 (file)
@@ -55,7 +55,7 @@ namespace PR6031 {
   template<typename T>
   struct NoDepBase {
     int foo() {
-      class NoDepBase::Nested nested; // expected-error{{'Nested' does not name a tag member in the specified scope}}
+      class NoDepBase::Nested nested; // expected-error{{no class named 'Nested' in 'NoDepBase<T>'}}
       typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{'MemberTemplate' following the 'template' keyword does not refer to a template}} \
       // FIXME: expected-error{{unqualified-id}}
       return NoDepBase::a; // expected-error{{no member named 'a' in 'NoDepBase<T>'}}
index f883b9361b66eab3ed08c0ba46030de49713f24f..2d27075bd41f40ab1afa100e2c5c87eb771c559f 100644 (file)
@@ -36,7 +36,7 @@ namespace N {
 
 typedef int INT;
 template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner;
-template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{'UeberInner' does not name a tag member}}
+template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}}
 
 namespace N2 {
   struct Outer2 {