mirror of https://github.com/microsoft/clang.git
[modules] Fix some more cases where we used to reject a conflict between two
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
This commit is contained in:
parent
f7d4ef04b8
commit
b795ce04a7
|
@ -279,6 +279,7 @@ class Sema {
|
||||||
// with internal linkage.
|
// with internal linkage.
|
||||||
return isVisible(Old) || New->isExternallyVisible();
|
return isVisible(Old) || New->isExternallyVisible();
|
||||||
}
|
}
|
||||||
|
bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
|
typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
|
||||||
|
|
|
@ -1834,8 +1834,7 @@ static void filterNonConflictingPreviousTypedefDecls(Sema &S,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Old->isExternallyVisible())
|
Filter.erase();
|
||||||
Filter.erase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Filter.done();
|
Filter.done();
|
||||||
|
@ -3344,6 +3343,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
|
||||||
if (New->isInvalidDecl())
|
if (New->isInvalidDecl())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!shouldLinkPossiblyHiddenDecl(Previous, New))
|
||||||
|
return;
|
||||||
|
|
||||||
VarTemplateDecl *NewTemplate = New->getDescribedVarTemplate();
|
VarTemplateDecl *NewTemplate = New->getDescribedVarTemplate();
|
||||||
|
|
||||||
// Verify the old decl was also a variable or variable template.
|
// 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();
|
return New->setInvalidDecl();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shouldLinkPossiblyHiddenDecl(Old, New))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Ensure the template parameters are compatible.
|
// Ensure the template parameters are compatible.
|
||||||
if (NewTemplate &&
|
if (NewTemplate &&
|
||||||
!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
|
!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
|
||||||
|
|
|
@ -8684,9 +8684,11 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc,
|
||||||
assert(!R.isAmbiguous() && !R.empty());
|
assert(!R.isAmbiguous() && !R.empty());
|
||||||
|
|
||||||
// Check if we have a previous declaration with the same name.
|
// Check if we have a previous declaration with the same name.
|
||||||
NamedDecl *PrevDecl = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName,
|
LookupResult PrevR(*this, Alias, AliasLoc, LookupOrdinaryName,
|
||||||
ForRedeclaration);
|
ForRedeclaration);
|
||||||
if (PrevDecl && !isDeclInScope(PrevDecl, CurContext, S))
|
LookupQualifiedName(PrevR, CurContext->getRedeclContext());
|
||||||
|
NamedDecl *PrevDecl = PrevR.getAsSingle<NamedDecl>();
|
||||||
|
if (PrevDecl && !isVisible(PrevDecl))
|
||||||
PrevDecl = nullptr;
|
PrevDecl = nullptr;
|
||||||
|
|
||||||
NamedDecl *ND = R.getFoundDecl();
|
NamedDecl *ND = R.getFoundDecl();
|
||||||
|
|
|
@ -1547,6 +1547,14 @@ bool Sema::isVisibleSlow(const NamedDecl *D) {
|
||||||
return LookupResult::isVisible(*this, const_cast<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.
|
/// \brief Retrieve the visible declaration corresponding to D, if any.
|
||||||
///
|
///
|
||||||
/// This routine determines whether the declaration D is visible in the current
|
/// This routine determines whether the declaration D is visible in the current
|
||||||
|
|
|
@ -3,3 +3,9 @@ namespace NS = RealNS;
|
||||||
typedef int Typedef;
|
typedef int Typedef;
|
||||||
using AliasDecl = int;
|
using AliasDecl = int;
|
||||||
using RealNS::UsingDecl;
|
using RealNS::UsingDecl;
|
||||||
|
struct Struct {};
|
||||||
|
extern int Variable;
|
||||||
|
namespace AnotherNS {}
|
||||||
|
enum X { Enumerator };
|
||||||
|
void Overloads();
|
||||||
|
void Overloads(int);
|
||||||
|
|
|
@ -7,11 +7,24 @@ namespace NS { int n; } // expected-note {{candidate}}
|
||||||
struct Typedef { int n; }; // expected-note {{candidate}}
|
struct Typedef { int n; }; // expected-note {{candidate}}
|
||||||
int AliasDecl; // expected-note {{candidate}}
|
int AliasDecl; // expected-note {{candidate}}
|
||||||
int UsingDecl; // 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:2 {{candidate}}
|
||||||
// expected-note@decls.h:3 {{candidate}}
|
// expected-note@decls.h:3 {{candidate}}
|
||||||
// expected-note@decls.h:4 {{candidate}}
|
// expected-note@decls.h:4 {{candidate}}
|
||||||
// expected-note@decls.h:5 {{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(int);
|
||||||
void use_things() {
|
void use_things() {
|
||||||
|
@ -19,6 +32,12 @@ void use_things() {
|
||||||
use(NS::n);
|
use(NS::n);
|
||||||
use(AliasDecl);
|
use(AliasDecl);
|
||||||
use(UsingDecl);
|
use(UsingDecl);
|
||||||
|
use(RealNS::n);
|
||||||
|
use(Struct(0));
|
||||||
|
use(Variable);
|
||||||
|
use(AnotherNS);
|
||||||
|
use(Enumerator);
|
||||||
|
use(Overloads);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "decls.h"
|
#include "decls.h"
|
||||||
|
@ -28,4 +47,10 @@ void use_things_again() {
|
||||||
use(NS::n); // expected-error {{ambiguous}}
|
use(NS::n); // expected-error {{ambiguous}}
|
||||||
use(AliasDecl); // expected-error {{ambiguous}}
|
use(AliasDecl); // expected-error {{ambiguous}}
|
||||||
use(UsingDecl); // 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}}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue