[cfe-commits] r91057 - in /cfe/trunk: include/clang/Basic/DiagnosticCommonKinds.td include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclObjC.cpp test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp

John McCall rjmccall at apple.com
Thu Dec 10 11:51:04 PST 2009


Author: rjmccall
Date: Thu Dec 10 13:51:03 2009
New Revision: 91057

URL: http://llvm.org/viewvc/llvm-project?rev=91057&view=rev
Log:
Improve the diagnostic when a new declaration conflicts with a using shadow
declaration.  Rename note_using_decl to note_using, which is possibly less confusing.
Add a test for non-class-scope using decl collisions and be sure to note the case
we can't diagnose yet.


Added:
    cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=91057&r1=91056&r2=91057&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Thu Dec 10 13:51:03 2009
@@ -26,8 +26,8 @@
 /// e.g. to specify the '(' when we expected a ')'.
 def note_matching : Note<"to match this '%0'">;
 
-def note_using_decl : Note<"using">;
-def note_also_found_decl : Note<"also found">;
+def note_using : Note<"using">;
+def note_also_found : Note<"also found">;
 
 // Parse && Lex
 def err_expected_colon : Error<"expected ':'">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=91057&r1=91056&r2=91057&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Dec 10 13:51:03 2009
@@ -124,10 +124,11 @@
 def note_using_decl_target : Note<"target of using declaration">;
 def note_using_decl_conflict : Note<"conflicting declaration">;
 def err_using_decl_redeclaration : Error<"redeclaration of using decl">;
-def note_previous_using_decl : Note<"previous using decl">;
 def err_using_decl_conflict : Error<
-  "%select{function|non-function}0 target of using declaration conflicts "
-  "with %select{function|non-function}1 declaration already in scope">;
+  "target of using declaration conflicts with declaration already in scope">;
+def err_using_decl_conflict_reverse : Error<
+  "declaration conflicts with target of using declaration already in scope">;
+def note_using_decl : Note<"%select{|previous }0using declaration">;
 
 def err_invalid_thread : Error<
   "'__thread' is only allowed on variable declarations">;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=91057&r1=91056&r2=91057&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Dec 10 13:51:03 2009
@@ -803,6 +803,15 @@
   else
     Old = dyn_cast<FunctionDecl>(OldD);
   if (!Old) {
+    if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(OldD)) {
+      Diag(New->getLocation(), diag::err_using_decl_conflict_reverse);
+      Diag(Shadow->getTargetDecl()->getLocation(),
+           diag::note_using_decl_target);
+      Diag(Shadow->getUsingDecl()->getLocation(),
+           diag::note_using_decl) << 0;
+      return true;
+    }
+
     Diag(New->getLocation(), diag::err_redefinition_different_kind)
       << New->getDeclName();
     Diag(OldD->getLocation(), diag::note_previous_definition);

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=91057&r1=91056&r2=91057&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Dec 10 13:51:03 2009
@@ -2995,9 +2995,7 @@
       return false;
 
     case Ovl_NonFunction:
-      Diag(Using->getLocation(), diag::err_using_decl_conflict)
-        << 0  // target decl is a function
-        << 1; // other decl is not a function
+      Diag(Using->getLocation(), diag::err_using_decl_conflict);
       break;
       
     // We found a decl with the exact signature.
@@ -3014,9 +3012,7 @@
         return true;
 
       // If we're not in a record, this is an error.
-      Diag(Using->getLocation(), diag::err_using_decl_conflict)
-        << 0  // target decl is a function
-        << 0; // other decl is a function
+      Diag(Using->getLocation(), diag::err_using_decl_conflict);
       break;
     }
 
@@ -3043,8 +3039,7 @@
     // No conflict between a tag and a non-tag.
     if (!Tag) return false;
 
-    Diag(Using->getLocation(), diag::err_using_decl_conflict)
-      << 1 << 1; // both non-functions
+    Diag(Using->getLocation(), diag::err_using_decl_conflict);
     Diag(Target->getLocation(), diag::note_using_decl_target);
     Diag(Tag->getLocation(), diag::note_using_decl_conflict);
     return true;
@@ -3053,9 +3048,7 @@
   // No conflict between a tag and a non-tag.
   if (!NonTag) return false;
 
-  Diag(Using->getLocation(), diag::err_using_decl_conflict)
-    << 1  // target not a function
-    << int(NonTag->isFunctionOrFunctionTemplate());
+  Diag(Using->getLocation(), diag::err_using_decl_conflict);
   Diag(Target->getLocation(), diag::note_using_decl_target);
   Diag(NonTag->getLocation(), diag::note_using_decl_conflict);
   return true;
@@ -3335,7 +3328,7 @@
       continue;
 
     Diag(NameLoc, diag::err_using_decl_redeclaration) << SS.getRange();
-    Diag(D->getLocation(), diag::note_previous_using_decl);
+    Diag(D->getLocation(), diag::note_using_decl) << 1;
     return true;
   }
 

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=91057&r1=91056&r2=91057&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Dec 10 13:51:03 2009
@@ -1349,10 +1349,10 @@
   }
   if (issueWarning && (MethList.Method && MethList.Next)) {
     Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
-    Diag(MethList.Method->getLocStart(), diag::note_using_decl)
+    Diag(MethList.Method->getLocStart(), diag::note_using)
       << MethList.Method->getSourceRange();
     for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
-      Diag(Next->Method->getLocStart(), diag::note_also_found_decl)
+      Diag(Next->Method->getLocStart(), diag::note_also_found)
         << Next->Method->getSourceRange();
   }
   return MethList.Method;
@@ -1413,10 +1413,10 @@
   }
   if (issueWarning && (MethList.Method && MethList.Next)) {
     Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
-    Diag(MethList.Method->getLocStart(), diag::note_using_decl)
+    Diag(MethList.Method->getLocStart(), diag::note_using)
       << MethList.Method->getSourceRange();
     for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
-      Diag(Next->Method->getLocStart(), diag::note_also_found_decl)
+      Diag(Next->Method->getLocStart(), diag::note_also_found)
         << Next->Method->getSourceRange();
   }
   return MethList.Method;

Added: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp?rev=91057&view=auto

==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp (added)
+++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp Thu Dec 10 13:51:03 2009
@@ -0,0 +1,89 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p11:
+//   If a function declaration in namespace scope or block scope has
+//   the same name and the same parameter types as a function
+//   introduced by a using-declaration, the program is
+//   ill-formed. [Note: two using-declarations may introduce functions
+//   with the same name and the same parameter types. If, for a call
+//   to an unqualified function name, function overload resolution
+//   selects the functions introduced by such using-declarations, the
+//   function call is ill-formed.
+
+namespace test0 {
+  namespace ns { void foo(); } // expected-note {{target of using declaration}}
+  int foo(); // expected-note {{conflicting declaration}}
+  using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+}
+
+namespace test1 {
+  namespace ns { void foo(); } // expected-note {{target of using declaration}}
+  using ns::foo; //expected-note {{using declaration}}
+  int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+}
+
+namespace test2 {
+  namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+  void test0() {
+    int foo(); // expected-note {{conflicting declaration}}
+    using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+  }
+
+  void test1() {
+    using ns::foo; //expected-note {{using declaration}}
+    int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+  }
+}
+
+namespace test3 {
+  namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+  class Test0 {
+    void test() {
+      int foo(); // expected-note {{conflicting declaration}}
+      using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+    }
+  };
+
+  class Test1 {
+    void test() {
+      using ns::foo; //expected-note {{using declaration}}
+      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+    }
+  };
+}
+
+namespace test4 {
+  namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+  template <typename> class Test0 {
+    void test() {
+      int foo(); // expected-note {{conflicting declaration}}
+      using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+    }
+  };
+
+  template <typename> class Test1 {
+    void test() {
+      using ns::foo; //expected-note {{using declaration}}
+      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+    }
+  };
+}
+
+// FIXME: we should be able to diagnose these, but we can't.
+namespace test5 {
+  namespace ns { void foo(int); }
+  template <typename T> class Test0 {
+    void test() {
+      int foo(T);
+      using ns::foo;
+    }
+  };
+
+  template <typename T> class Test1 {
+    void test() {
+      using ns::foo;
+      int foo(T);
+    }
+  };
+}
+





More information about the cfe-commits mailing list