Skip to content

Commit 2d5b727

Browse files
committed
[Clang Importer] Support multiple alternate decls
ImportDecl has an alternate decl quasi-escape-hatch where it can create alternative declarations for the same original Clang node. But, it was limited at one, which worked accidentally in the case of VisitObjCMethodDecl's attempts at importing a factory-init-suppressed root-class method that points to the imported-as-init Swift declaration. This commit changes that to a TinyPtrVector, to support the upcoming occasional case where we have more.
1 parent cddb225 commit 2d5b727

File tree

3 files changed

+24
-23
lines changed

3 files changed

+24
-23
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,7 +2196,7 @@ void ClangModuleUnit::lookupObjCMethods(
21962196
results.push_back(func);
21972197

21982198
// If there is an alternate declaration, also look at it.
2199-
if (auto alternate = owner.Impl.getAlternateDecl(imported)) {
2199+
for (auto alternate : owner.Impl.getAlternateDecls(imported)) {
22002200
if (auto func = dyn_cast<AbstractFunctionDecl>(alternate))
22012201
results.push_back(func);
22022202
}
@@ -2585,7 +2585,7 @@ void ClangImporter::Implementation::lookupValue(
25852585

25862586
// If there is an alternate declaration and the name matches,
25872587
// report this result.
2588-
if (auto alternate = getAlternateDecl(decl)) {
2588+
for (auto alternate : getAlternateDecls(decl)) {
25892589
if (alternate->getFullName().matchesRef(name) &&
25902590
alternate->getDeclContext()->isModuleScopeContext()) {
25912591
consumer.foundDecl(alternate, DeclVisibilityKind::VisibleAtTopLevel);
@@ -2649,7 +2649,7 @@ void ClangImporter::Implementation::lookupObjCMembers(
26492649

26502650
// Check for an alternate declaration; if it's name matches,
26512651
// report it.
2652-
if (auto alternate = getAlternateDecl(decl)) {
2652+
for (auto alternate : getAlternateDecls(decl)) {
26532653
if (alternate->getFullName().matchesRef(name)) {
26542654
consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup);
26552655
matchedAny = true;

lib/ClangImporter/ImportDecl.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3360,13 +3360,13 @@ namespace {
33603360
// declaration.
33613361
if (auto imported = VisitObjCMethodDecl(decl, dc,
33623362
/*forceClassMethod=*/true))
3363-
Impl.setAlternateDecl(result, cast<ValueDecl>(imported));
3363+
Impl.addAlternateDecl(result, cast<ValueDecl>(imported));
33643364
} else if (auto factory = importFactoryMethodAsConstructor(
33653365
result, decl, selector, dc)) {
33663366
// We imported the factory method as an initializer, so
33673367
// record it as an alternate declaration.
33683368
if (*factory)
3369-
Impl.setAlternateDecl(result, *factory);
3369+
Impl.addAlternateDecl(result, *factory);
33703370
}
33713371

33723372
}
@@ -4971,7 +4971,7 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
49714971
SourceLoc());
49724972

49734973
// Make the property the alternate declaration for the getter.
4974-
Impl.setAlternateDecl(swiftGetter, property);
4974+
Impl.addAlternateDecl(swiftGetter, property);
49754975

49764976
return property;
49774977
}
@@ -5021,7 +5021,7 @@ SwiftDeclConverter::importFactoryMethodAsConstructor(
50215021
/// Record the initializer as an alternative declaration for the
50225022
/// member.
50235023
if (result) {
5024-
Impl.setAlternateDecl(member, result);
5024+
Impl.addAlternateDecl(member, result);
50255025

50265026
if (swift3Name)
50275027
markAsSwift2Variant(result, *swift3Name);
@@ -5736,7 +5736,7 @@ SwiftDeclConverter::importSubscript(Decl *decl,
57365736
TypeLoc::withoutLoc(elementContextTy), dc);
57375737

57385738
/// Record the subscript as an alternative declaration.
5739-
Impl.setAlternateDecl(associateWithSetter ? setter : getter, subscript);
5739+
Impl.addAlternateDecl(associateWithSetter ? setter : getter, subscript);
57405740

57415741
subscript->makeComputed(SourceLoc(), getterThunk, setterThunk, nullptr,
57425742
SourceLoc());
@@ -5934,8 +5934,8 @@ void SwiftDeclConverter::importObjCMembers(
59345934
continue;
59355935

59365936
if (auto objcMethod = dyn_cast<clang::ObjCMethodDecl>(nd)) {
5937-
// If there is an alternate declaration for this member, add it.
5938-
if (auto alternate = Impl.getAlternateDecl(member)) {
5937+
// If there is are alternate declarations for this member, add it.
5938+
for (auto alternate : Impl.getAlternateDecls(member)) {
59395939
if (alternate->getDeclContext() == member->getDeclContext() &&
59405940
knownMembers.insert(alternate).second)
59415941
members.push_back(alternate);
@@ -6063,7 +6063,7 @@ void SwiftDeclConverter::importMirroredProtocolMembers(
60636063
Impl.importMirroredDecl(objcMethod, dc, useSwift2Name, proto)) {
60646064
members.push_back(imported);
60656065

6066-
if (auto alternate = Impl.getAlternateDecl(imported))
6066+
for (auto alternate : Impl.getAlternateDecls(imported))
60676067
if (imported->getDeclContext() == alternate->getDeclContext())
60686068
members.push_back(alternate);
60696069
}
@@ -6542,7 +6542,7 @@ ClangImporter::Implementation::importDeclImpl(const clang::NamedDecl *ClangDecl,
65426542
if (Result) {
65436543
finalizeDecl(Result);
65446544

6545-
if (auto alternate = getAlternateDecl(Result))
6545+
for (auto alternate : getAlternateDecls(Result))
65466546
finalizeDecl(alternate);
65476547
}
65486548

@@ -6793,7 +6793,7 @@ ClangImporter::Implementation::importMirroredDecl(const clang::NamedDecl *decl,
67936793
updateMirroredDecl(result);
67946794

67956795
// Update the alternate declaration as well.
6796-
if (auto alternate = getAlternateDecl(result))
6796+
for (auto alternate : getAlternateDecls(result))
67976797
updateMirroredDecl(alternate);
67986798
}
67996799
if (result || !converter.hadForwardDeclaration())
@@ -7193,7 +7193,7 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) {
71937193
// Add the member.
71947194
ext->addMember(member);
71957195

7196-
if (auto alternate = getAlternateDecl(member)) {
7196+
for (auto alternate : getAlternateDecls(member)) {
71977197
ext->addMember(alternate);
71987198
}
71997199

lib/ClangImporter/ImporterImpl.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
430430
/// A mapping from imported declarations to their "alternate" declarations,
431431
/// for cases where a single Clang declaration is imported to two
432432
/// different Swift declarations.
433-
llvm::DenseMap<Decl *, ValueDecl *> AlternateDecls;
433+
llvm::DenseMap<Decl *, TinyPtrVector<ValueDecl *>> AlternateDecls;
434434

435435
public:
436436
/// \brief Keep track of enum constant values that have been imported.
@@ -447,18 +447,19 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
447447

448448
/// Retrieve the alternative declaration for the given imported
449449
/// Swift declaration.
450-
ValueDecl *getAlternateDecl(Decl *decl) {
450+
TinyPtrVector<ValueDecl *> getAlternateDecls(Decl *decl) {
451451
auto known = AlternateDecls.find(decl);
452-
if (known == AlternateDecls.end()) return nullptr;
452+
if (known == AlternateDecls.end()) return {};
453453
return known->second;
454454
}
455455

456-
/// Set the alternative decl
457-
void setAlternateDecl(Decl *forDecl, ValueDecl *altDecl) {
458-
assert((!AlternateDecls.count(forDecl) ||
459-
AlternateDecls[forDecl] == altDecl) &&
460-
"clobbering already-set alternative");
461-
AlternateDecls[forDecl] = altDecl;
456+
/// Add an alternative decl
457+
void addAlternateDecl(Decl *forDecl, ValueDecl *altDecl) {
458+
auto &vec = AlternateDecls[forDecl];
459+
for (auto alt : vec)
460+
if (alt == altDecl)
461+
return;
462+
vec.push_back(altDecl);
462463
}
463464

464465
private:

0 commit comments

Comments
 (0)