]> granicus.if.org Git - clang/commitdiff
[modules] Fix some more cases where we used to reject a conflict between two
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 17 Nov 2015 03:02:41 +0000 (03:02 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 17 Nov 2015 03:02:41 +0000 (03:02 +0000)
declarations that are not simultaneously visible, and where at least one of
them has internal/no linkage.

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

include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaLookup.cpp
test/Modules/Inputs/no-linkage/decls.h
test/Modules/no-linkage.cpp

index 7c2fa0498987827c1d3c48d62476859604483145..090559e0a29f7ee88ecc243b950ec1acb86a5b59 100644 (file)
@@ -279,6 +279,7 @@ class Sema {
     // with internal linkage.
     return isVisible(Old) || New->isExternallyVisible();
   }
+  bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New);
 
 public:
   typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
index 5123601d8a6126931b78c329a59d845d130ccbd0..5215a7e0dc450a91e7c033719d62d551e894b43b 100644 (file)
@@ -1834,8 +1834,7 @@ static void filterNonConflictingPreviousTypedefDecls(Sema &S,
         continue;
     }
 
-    if (!Old->isExternallyVisible())
-      Filter.erase();
+    Filter.erase();
   }
 
   Filter.done();
@@ -3344,6 +3343,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
   if (New->isInvalidDecl())
     return;
 
+  if (!shouldLinkPossiblyHiddenDecl(Previous, New))
+    return;
+
   VarTemplateDecl *NewTemplate = New->getDescribedVarTemplate();
 
   // Verify the old decl was also a variable or variable template.
@@ -3375,9 +3377,6 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
     return New->setInvalidDecl();
   }
 
-  if (!shouldLinkPossiblyHiddenDecl(Old, New))
-    return;
-
   // Ensure the template parameters are compatible.
   if (NewTemplate &&
       !TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
index b7278904185a80d7856fcaa6508ccc4115afddb0..eb010e9e39a93b16b18748c8f06944053ae1a0ea 100644 (file)
@@ -8684,9 +8684,11 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc,
   assert(!R.isAmbiguous() && !R.empty());
 
   // Check if we have a previous declaration with the same name.
-  NamedDecl *PrevDecl = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName,
-                                         ForRedeclaration);
-  if (PrevDecl && !isDeclInScope(PrevDecl, CurContext, S))
+  LookupResult PrevR(*this, Alias, AliasLoc, LookupOrdinaryName,
+                     ForRedeclaration);
+  LookupQualifiedName(PrevR, CurContext->getRedeclContext());
+  NamedDecl *PrevDecl = PrevR.getAsSingle<NamedDecl>();
+  if (PrevDecl && !isVisible(PrevDecl))
     PrevDecl = nullptr;
 
   NamedDecl *ND = R.getFoundDecl();
index 7236e99942beaed8bf456018909a612f1c072acb..9b5d511818e81b8b96d41144850e7e1efcc4d414 100644 (file)
@@ -1547,6 +1547,14 @@ bool Sema::isVisibleSlow(const NamedDecl *D) {
   return LookupResult::isVisible(*this, const_cast<NamedDecl*>(D));
 }
 
+bool Sema::shouldLinkPossiblyHiddenDecl(LookupResult &R, const NamedDecl *New) {
+  for (auto *D : R) {
+    if (isVisible(D))
+      return true;
+  }
+  return New->isExternallyVisible();
+}
+
 /// \brief Retrieve the visible declaration corresponding to D, if any.
 ///
 /// This routine determines whether the declaration D is visible in the current
index 9e18e10ce99dce1374e2bd69e44d2ce56863671a..c8d6de55f74e8712fa4c726d042b13ff2c553eaf 100644 (file)
@@ -3,3 +3,9 @@ namespace NS = RealNS;
 typedef int Typedef;
 using AliasDecl = int;
 using RealNS::UsingDecl;
+struct Struct {};
+extern int Variable;
+namespace AnotherNS {}
+enum X { Enumerator };
+void Overloads();
+void Overloads(int);
index d4a9eaba403e2483661deff4bb82771c8f19072b..1ec8f4075e47a6e798a0131cd38d9b96a3a6c014 100644 (file)
@@ -7,11 +7,24 @@ namespace NS { int n; } // expected-note {{candidate}}
 struct Typedef { int n; }; // expected-note {{candidate}}
 int AliasDecl; // expected-note {{candidate}}
 int UsingDecl; // expected-note {{candidate}}
+namespace RealNS = NS; // expected-note {{candidate}}
+typedef int Struct; // expected-note {{candidate}}
+enum { Variable }; // expected-note {{candidate}}
+const int AnotherNS = 0; // expected-note {{candidate}}
+const int Enumerator = 0; // expected-note {{candidate}}
+static int Overloads; // expected-note {{candidate}}
 
+// expected-note@decls.h:1 {{candidate}}
 // expected-note@decls.h:2 {{candidate}}
 // expected-note@decls.h:3 {{candidate}}
 // expected-note@decls.h:4 {{candidate}}
 // expected-note@decls.h:5 {{candidate}}
+// expected-note@decls.h:6 {{candidate}}
+// expected-note@decls.h:7 {{candidate}}
+// expected-note@decls.h:8 {{candidate}}
+// expected-note@decls.h:9 {{candidate}}
+// expected-note@decls.h:10 {{candidate}}
+// expected-note@decls.h:11 {{candidate}}
 
 void use(int);
 void use_things() {
@@ -19,6 +32,12 @@ void use_things() {
   use(NS::n);
   use(AliasDecl);
   use(UsingDecl);
+  use(RealNS::n);
+  use(Struct(0));
+  use(Variable);
+  use(AnotherNS);
+  use(Enumerator);
+  use(Overloads);
 }
 
 #include "decls.h"
@@ -28,4 +47,10 @@ void use_things_again() {
   use(NS::n); // expected-error {{ambiguous}}
   use(AliasDecl); // expected-error {{ambiguous}}
   use(UsingDecl); // expected-error {{ambiguous}}
+  use(RealNS::n); // expected-error {{ambiguous}}
+  use(Struct(0)); // expected-error {{ambiguous}}
+  use(Variable); // expected-error {{ambiguous}}
+  use(AnotherNS); // expected-error {{ambiguous}}
+  use(Enumerator); // expected-error {{ambiguous}}
+  use(Overloads); // expected-error {{ambiguous}}
 }