Skip to content

Commit ca40f9b

Browse files
committed
[modules] When considering merging a newly-declared typedef into an imported
one, perform the import if the types match even if the imported declaration is hidden. Otherwise, NamedDecl::declarationReplaces will drop one of the name lookup entries, making the typedef effectively inaccessible from one of the modules that declared it. llvm-svn: 215306
1 parent 502dca7 commit ca40f9b

File tree

7 files changed

+79
-1
lines changed

7 files changed

+79
-1
lines changed

clang/lib/Sema/SemaDecl.cpp

+38-1
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,43 @@ static void filterNonConflictingPreviousDecls(ASTContext &context,
17251725
filter.done();
17261726
}
17271727

1728+
/// Typedef declarations don't have linkage, but they still denote the same
1729+
/// entity if their types are the same.
1730+
/// FIXME: This is notionally doing the same thing as ASTReaderDecl's
1731+
/// isSameEntity.
1732+
static void filterNonConflictingPreviousTypedefDecls(ASTContext &Context,
1733+
TypedefNameDecl *Decl,
1734+
LookupResult &Previous) {
1735+
// This is only interesting when modules are enabled.
1736+
if (!Context.getLangOpts().Modules)
1737+
return;
1738+
1739+
// Empty sets are uninteresting.
1740+
if (Previous.empty())
1741+
return;
1742+
1743+
LookupResult::Filter Filter = Previous.makeFilter();
1744+
while (Filter.hasNext()) {
1745+
NamedDecl *Old = Filter.next();
1746+
1747+
// Non-hidden declarations are never ignored.
1748+
if (!Old->isHidden())
1749+
continue;
1750+
1751+
// Declarations of the same entity are not ignored, even if they have
1752+
// different linkages.
1753+
if (auto *OldTD = dyn_cast<TypedefNameDecl>(Old))
1754+
if (Context.hasSameType(OldTD->getUnderlyingType(),
1755+
Decl->getUnderlyingType()))
1756+
continue;
1757+
1758+
if (!Old->isExternallyVisible())
1759+
Filter.erase();
1760+
}
1761+
1762+
Filter.done();
1763+
}
1764+
17281765
bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
17291766
QualType OldType;
17301767
if (TypedefNameDecl *OldTypedef = dyn_cast<TypedefNameDecl>(Old))
@@ -4835,7 +4872,7 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD,
48354872
// in an outer scope, it isn't the same thing.
48364873
FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/false,
48374874
/*AllowInlineNamespace*/false);
4838-
filterNonConflictingPreviousDecls(Context, NewTD, Previous);
4875+
filterNonConflictingPreviousTypedefDecls(Context, NewTD, Previous);
48394876
if (!Previous.empty()) {
48404877
Redeclaration = true;
48414878
MergeTypedefNameDecl(NewTD, Previous);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef A1_H
2+
#define A1_H
3+
namespace llvm {
4+
class MachineBasicBlock;
5+
template <class NodeT> class DomTreeNodeBase;
6+
typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
7+
}
8+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#ifndef A2_H
2+
#define A2_H
3+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef B1_H
2+
#define B1_H
3+
#include "a2.h"
4+
namespace llvm {
5+
class MachineBasicBlock;
6+
template <class NodeT> class DomTreeNodeBase;
7+
typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
8+
}
9+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#ifndef B2_H
2+
#define B2_H
3+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module A {
2+
module A1 { header "a1.h" export * }
3+
module A2 { header "a2.h" export * }
4+
}
5+
6+
module B {
7+
module B1 { header "b1.h" export * }
8+
module B2 { header "b2.h" export * }
9+
}

clang/test/Modules/merge-typedefs.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: rm -rf %t
2+
// RUN: %clang_cc1 -x c++ -I%S/Inputs/merge-typedefs -verify %s
3+
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x c++ -I%S/Inputs/merge-typedefs -verify %s
4+
5+
#include "b2.h"
6+
#include "a1.h"
7+
8+
// expected-no-diagnostics
9+
llvm::MachineDomTreeNode *p;

0 commit comments

Comments
 (0)