forked from OSchip/llvm-project
[modules] Make IndirectFieldDecl mergeable to avoid lookup ambiguity when the same anonymous union is defined across multiple modules.
llvm-svn: 243940
This commit is contained in:
parent
215df9ed98
commit
8cbd895947
|
@ -2499,7 +2499,8 @@ public:
|
|||
/// IndirectFieldDecl - An instance of this class is created to represent a
|
||||
/// field injected from an anonymous union/struct into the parent scope.
|
||||
/// IndirectFieldDecl are always implicit.
|
||||
class IndirectFieldDecl : public ValueDecl {
|
||||
class IndirectFieldDecl : public ValueDecl,
|
||||
public Mergeable<IndirectFieldDecl> {
|
||||
void anchor() override;
|
||||
NamedDecl **Chaining;
|
||||
unsigned ChainingSize;
|
||||
|
@ -2537,6 +2538,9 @@ public:
|
|||
return dyn_cast<VarDecl>(*chain_begin());
|
||||
}
|
||||
|
||||
IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
|
||||
const IndirectFieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == IndirectField; }
|
||||
|
|
|
@ -1178,6 +1178,8 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
|
|||
|
||||
for (unsigned I = 0; I != FD->ChainingSize; ++I)
|
||||
FD->Chaining[I] = ReadDeclAs<NamedDecl>(Record, Idx);
|
||||
|
||||
mergeMergeable(FD);
|
||||
}
|
||||
|
||||
ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) {
|
||||
|
@ -2638,6 +2640,13 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
|
|||
return X->getASTContext().hasSameType(FDX->getType(), FDY->getType());
|
||||
}
|
||||
|
||||
// Indirect fields with the same target field match.
|
||||
if (auto *IFDX = dyn_cast<IndirectFieldDecl>(X)) {
|
||||
auto *IFDY = cast<IndirectFieldDecl>(Y);
|
||||
return IFDX->getAnonField()->getCanonicalDecl() ==
|
||||
IFDY->getAnonField()->getCanonicalDecl();
|
||||
}
|
||||
|
||||
// Enumerators with the same name match.
|
||||
if (isa<EnumConstantDecl>(X))
|
||||
// FIXME: Also check the value is odr-equivalent.
|
||||
|
|
|
@ -103,3 +103,11 @@ namespace RedeclDifferentDeclKind {
|
|||
typedef X X;
|
||||
using RedeclDifferentDeclKind::X;
|
||||
}
|
||||
|
||||
namespace Anon {
|
||||
struct X {
|
||||
union {
|
||||
int n;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ template<typename T, int N, template<typename> class K> struct J;
|
|||
J<> post_j2;
|
||||
FriendDefArg::Y<int> friend_def_arg;
|
||||
FriendDefArg::D<> friend_def_arg_d;
|
||||
int post_anon_x_n = Anon::X().n;
|
||||
|
||||
MergeFunctionTemplateSpecializations::X<int>::Q<char> xiqc;
|
||||
|
||||
|
|
Loading…
Reference in New Issue