r204082 - Don't fold together the name lookup entries for two declarations if they are

Richard Smith richard-llvm at metafoo.co.uk
Mon Mar 17 14:46:03 PDT 2014


Author: rsmith
Date: Mon Mar 17 16:46:03 2014
New Revision: 204082

URL: http://llvm.org/viewvc/llvm-project?rev=204082&view=rev
Log:
Don't fold together the name lookup entries for two declarations if they are
declared in different namespaces in the same inline namespace set.

Modified:
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
    cfe/trunk/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=204082&r1=204081&r2=204082&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Mar 17 16:46:03 2014
@@ -1381,6 +1381,7 @@ bool NamedDecl::declarationReplaces(Name
   if (isa<ObjCMethodDecl>(this))
     return false;
 
+  // FIXME: Is this correct if one of the decls comes from an inline namespace?
   if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
     return true;
 
@@ -1407,14 +1408,19 @@ bool NamedDecl::declarationReplaces(Name
 
   // A typedef of an Objective-C class type can replace an Objective-C class
   // declaration or definition, and vice versa.
+  // FIXME: Is this correct if one of the decls comes from an inline namespace?
   if ((isa<TypedefNameDecl>(this) && isa<ObjCInterfaceDecl>(OldD)) ||
       (isa<ObjCInterfaceDecl>(this) && isa<TypedefNameDecl>(OldD)))
     return true;
-  
+
   // For non-function declarations, if the declarations are of the
-  // same kind then this must be a redeclaration, or semantic analysis
-  // would not have given us the new declaration.
-  return this->getKind() == OldD->getKind();
+  // same kind and have the same parent then this must be a redeclaration,
+  // or semantic analysis would not have given us the new declaration.
+  // Note that inline namespaces can give us two declarations with the same
+  // name and kind in the same scope but different contexts.
+  return this->getKind() == OldD->getKind() &&
+         this->getDeclContext()->getRedeclContext()->Equals(
+             OldD->getDeclContext()->getRedeclContext());
 }
 
 bool NamedDecl::hasLinkage() const {

Modified: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp?rev=204082&r1=204081&r2=204082&view=diff
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp Mon Mar 17 16:46:03 2014
@@ -63,3 +63,14 @@ void test3() {
   Numbers2::f(f);
   Numbers2::g(f); // expected-error {{no viable conversion from 'float' to 'Numbers::Number'}}
 }
+
+namespace inline_ns {
+  int x; // expected-note 2{{found}}
+  inline namespace A { // expected-warning {{C++11}}
+    int x; // expected-note 2{{found}}
+    int y; // expected-note 2{{found}}
+  }
+  int y; // expected-note 2{{found}}
+  int k1 = x + y; // expected-error 2{{ambiguous}}
+  int k2 = inline_ns::x + inline_ns::y; // expected-error 2{{ambiguous}}
+}

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp?rev=204082&r1=204081&r2=204082&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp Mon Mar 17 16:46:03 2014
@@ -30,9 +30,12 @@ namespace inline_namespaces {
     inline namespace M {
       void f(); // expected-note {{possible target}}
       void g();
-      extern int m, n;
-      struct S; struct T;
-      enum E : int; enum F : int;
+      extern int m; // expected-note {{candidate}}
+      extern int n;
+      struct S; // expected-note {{candidate}}
+      struct T;
+      enum E : int; // expected-note {{candidate}}
+      enum F : int;
       template<typename T> void ft(); // expected-note {{here}}
       template<typename T> void gt(); // expected-note {{here}}
       template<typename T> extern int mt; // expected-note {{here}} expected-warning {{extension}}
@@ -44,16 +47,14 @@ namespace inline_namespaces {
     // When named by unqualified-id, we do *not* look in the inline namespace
     // set.
     void f() {} // expected-note {{possible target}}
-    int m;
-    struct S {};
-    enum E : int {};
+    int m; // expected-note {{candidate}}
+    struct S {}; // expected-note {{candidate}}
+    enum E : int {}; // expected-note {{candidate}}
 
     static_assert(&f != &M::f, ""); // expected-error {{reference to overloaded function could not be resolved}}
-    static_assert(&m != &M::m, "");
-    typedef S X; // expected-note {{previous}}
-    typedef M::S X; // expected-error {{different type}}
-    typedef E Y; // expected-note {{previous}}
-    typedef M::E Y; // expected-error {{different type}}
+    static_assert(&m != &M::m, ""); // expected-error {{ambiguous}}
+    typedef S X; // expected-error {{ambiguous}}
+    typedef E Y; // expected-error {{ambiguous}}
 
     // When named by (unqualified) template-id, we do look in the inline
     // namespace set.  See [namespace.def]p8, [temp.explicit]p3,





More information about the cfe-commits mailing list