Skip to content

Commit e6e127b

Browse files
committed
ClangImporter: Tighten up isMethodAlreadyImported()
Allow two methods to be imported with the same selector, as long as they have different Swift DeclNames. This is required for lazy mirrored protocol member loading to work correctly, so that the same declarations are imported regardless of name lookup order. The commit for the mirrored protocol member change will have test cases that cover this behavior.
1 parent 0895235 commit e6e127b

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4091,8 +4091,8 @@ namespace {
40914091

40924092
/// Check whether we have already imported a method with the given
40934093
/// selector in the given context.
4094-
bool isMethodAlreadyImported(ObjCSelector selector, bool isInstance,
4095-
const DeclContext *dc,
4094+
bool isMethodAlreadyImported(ObjCSelector selector, ImportedName importedName,
4095+
bool isInstance, const DeclContext *dc,
40964096
llvm::function_ref<bool(AbstractFunctionDecl *fn)> filter) {
40974097
// We only need to perform this check for classes.
40984098
auto classDecl
@@ -4108,6 +4108,7 @@ namespace {
41084108
for (auto decl : classDecl->lookupDirect(selector, isInstance)) {
41094109
if ((decl->getClangDecl()
41104110
|| !decl->getDeclContext()->getParentSourceFile())
4111+
&& importedName.getDeclName() == decl->getFullName()
41114112
&& filter(decl)) {
41124113
result = true;
41134114
break;
@@ -4175,25 +4176,25 @@ namespace {
41754176
}
41764177
}
41774178

4179+
ImportedName importedName;
4180+
Optional<ImportedName> correctSwiftName;
4181+
importedName = importFullName(decl, correctSwiftName);
4182+
if (!importedName)
4183+
return nullptr;
4184+
41784185
// Check whether another method with the same selector has already been
41794186
// imported into this context.
41804187
ObjCSelector selector = Impl.importSelector(decl->getSelector());
41814188
bool isInstance = decl->isInstanceMethod() && !forceClassMethod;
41824189
if (isActiveSwiftVersion()) {
4183-
if (isMethodAlreadyImported(selector, isInstance, dc,
4190+
if (isMethodAlreadyImported(selector, importedName, isInstance, dc,
41844191
[&](AbstractFunctionDecl *fn) {
41854192
return isAcceptableResult(fn, accessorInfo);
41864193
})) {
41874194
return nullptr;
41884195
}
41894196
}
41904197

4191-
ImportedName importedName;
4192-
Optional<ImportedName> correctSwiftName;
4193-
importedName = importFullName(decl, correctSwiftName);
4194-
if (!importedName)
4195-
return nullptr;
4196-
41974198
// Normal case applies when we're importing an older name, or when we're
41984199
// not an init
41994200
if (!isFactoryInit(importedName)) {
@@ -6096,10 +6097,15 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
60966097
if (known != Impl.Constructors.end())
60976098
return known->second;
60986099

6100+
Optional<ImportedName> correctSwiftName;
6101+
auto importedName = importFullName(objcMethod, correctSwiftName);
6102+
if (!importedName)
6103+
return nullptr;
6104+
60996105
// Check whether there is already a method with this selector.
61006106
auto selector = Impl.importSelector(objcMethod->getSelector());
61016107
if (isActiveSwiftVersion() &&
6102-
isMethodAlreadyImported(selector, /*isInstance=*/true, dc,
6108+
isMethodAlreadyImported(selector, importedName, /*isInstance=*/true, dc,
61036109
[](AbstractFunctionDecl *fn) {
61046110
return true;
61056111
}))
@@ -6110,10 +6116,6 @@ ConstructorDecl *SwiftDeclConverter::importConstructor(
61106116
objcMethod->param_end()};
61116117

61126118
bool variadic = objcMethod->isVariadic();
6113-
Optional<ImportedName> correctSwiftName;
6114-
auto importedName = importFullName(objcMethod, correctSwiftName);
6115-
if (!importedName)
6116-
return nullptr;
61176119

61186120
// If we dropped the variadic, handle it now.
61196121
if (importedName.droppedVariadic()) {

0 commit comments

Comments
 (0)