@@ -4535,24 +4535,64 @@ namespace {
4535
4535
}
4536
4536
4537
4537
template <typename T, typename U>
4538
- T *resolveSwiftDeclImpl (const U *decl, Identifier name, ModuleDecl *overlay) {
4538
+ T *resolveSwiftDeclImpl (const U *decl, Identifier name,
4539
+ bool hasKnownSwiftName, ModuleDecl *overlay) {
4539
4540
const auto &languageVersion =
4540
4541
Impl.SwiftContext .LangOpts .EffectiveLanguageVersion ;
4541
4542
4543
+ auto isMatch = [&](const T *singleResult, bool baseNameMatches) -> bool {
4544
+ const DeclAttributes &attrs = singleResult->getAttrs ();
4545
+
4546
+ // Skip versioned variants.
4547
+ if (attrs.isUnavailableInSwiftVersion (languageVersion))
4548
+ return false ;
4549
+
4550
+ // Skip if type not exposed to Objective-C.
4551
+ // If the base name doesn't match, then a matching
4552
+ // custom name in an @objc attribute is required.
4553
+ if (baseNameMatches && !singleResult->isObjC ())
4554
+ return false ;
4555
+
4556
+ // If Clang decl has a custom Swift name, then we know that
4557
+ // `name` is the base name we're looking for.
4558
+ if (hasKnownSwiftName)
4559
+ return baseNameMatches;
4560
+
4561
+ // Skip if a different name is used for Objective-C.
4562
+ if (auto objcAttr = attrs.getAttribute <ObjCAttr>())
4563
+ if (auto objcName = objcAttr->getName ())
4564
+ return objcName->getSimpleName () == name;
4565
+
4566
+ return baseNameMatches;
4567
+ };
4568
+
4569
+ // First look at Swift types with the same name.
4542
4570
SmallVector<ValueDecl *, 4 > results;
4543
4571
overlay->lookupValue (name, NLKind::QualifiedLookup, results);
4544
4572
T *found = nullptr ;
4545
4573
for (auto result : results) {
4546
4574
if (auto singleResult = dyn_cast<T>(result)) {
4547
- // Skip versioned variants.
4548
- const DeclAttributes &attrs = singleResult-> getAttrs ();
4549
- if (attrs. isUnavailableInSwiftVersion (languageVersion))
4550
- continue ;
4551
-
4552
- if (found)
4553
- return nullptr ;
4575
+ if ( isMatch (singleResult, /* baseNameMatches= */ true )) {
4576
+ if (found)
4577
+ return nullptr ;
4578
+ found = singleResult ;
4579
+ }
4580
+ }
4581
+ }
4554
4582
4555
- found = singleResult;
4583
+ if (!found && !hasKnownSwiftName) {
4584
+ // Try harder to find a match looking at just custom Objective-C names.
4585
+ SmallVector<Decl *, 64 > results;
4586
+ overlay->getTopLevelDecls (results);
4587
+ for (auto result : results) {
4588
+ if (auto singleResult = dyn_cast<T>(result)) {
4589
+ // The base name _could_ match but it's irrelevant here.
4590
+ if (isMatch (singleResult, /* baseNameMatches=*/ false )) {
4591
+ if (found)
4592
+ return nullptr ;
4593
+ found = singleResult;
4594
+ }
4595
+ }
4556
4596
}
4557
4597
}
4558
4598
@@ -4565,15 +4605,16 @@ namespace {
4565
4605
4566
4606
template <typename T, typename U>
4567
4607
T *resolveSwiftDecl (const U *decl, Identifier name,
4568
- ClangModuleUnit *clangModule) {
4608
+ bool hasKnownSwiftName, ClangModuleUnit *clangModule) {
4569
4609
if (auto overlay = clangModule->getOverlayModule ())
4570
- return resolveSwiftDeclImpl<T>(decl, name, overlay);
4610
+ return resolveSwiftDeclImpl<T>(decl, name, hasKnownSwiftName, overlay);
4571
4611
if (clangModule == Impl.ImportedHeaderUnit ) {
4572
4612
// Use an index-based loop because new owners can come in as we're
4573
4613
// iterating.
4574
4614
for (size_t i = 0 ; i < Impl.ImportedHeaderOwners .size (); ++i) {
4575
4615
ModuleDecl *owner = Impl.ImportedHeaderOwners [i];
4576
- if (T *result = resolveSwiftDeclImpl<T>(decl, name, owner))
4616
+ if (T *result = resolveSwiftDeclImpl<T>(decl, name,
4617
+ hasKnownSwiftName, owner))
4577
4618
return result;
4578
4619
}
4579
4620
}
@@ -4586,7 +4627,8 @@ namespace {
4586
4627
if (!importer::hasNativeSwiftDecl (decl))
4587
4628
return false ;
4588
4629
auto wrapperUnit = cast<ClangModuleUnit>(dc->getModuleScopeContext ());
4589
- swiftDecl = resolveSwiftDecl<T>(decl, name, wrapperUnit);
4630
+ swiftDecl = resolveSwiftDecl<T>(decl, name, /* hasCustomSwiftName=*/ true ,
4631
+ wrapperUnit);
4590
4632
return true ;
4591
4633
}
4592
4634
@@ -4615,13 +4657,15 @@ namespace {
4615
4657
*correctSwiftName);
4616
4658
4617
4659
Identifier name = importedName.getDeclName ().getBaseIdentifier ();
4660
+ bool hasKnownSwiftName = importedName.hasCustomName ();
4618
4661
4619
4662
// FIXME: Figure out how to deal with incomplete protocols, since that
4620
4663
// notion doesn't exist in Swift.
4621
4664
if (!decl->hasDefinition ()) {
4622
4665
// Check if this protocol is implemented in its overlay.
4623
4666
if (auto clangModule = Impl.getClangModuleForDecl (decl, true ))
4624
4667
if (auto native = resolveSwiftDecl<ProtocolDecl>(decl, name,
4668
+ hasKnownSwiftName,
4625
4669
clangModule))
4626
4670
return native;
4627
4671
@@ -4733,11 +4777,13 @@ namespace {
4733
4777
*correctSwiftName);
4734
4778
4735
4779
auto name = importedName.getDeclName ().getBaseIdentifier ();
4780
+ bool hasKnownSwiftName = importedName.hasCustomName ();
4736
4781
4737
4782
if (!decl->hasDefinition ()) {
4738
4783
// Check if this class is implemented in its overlay.
4739
4784
if (auto clangModule = Impl.getClangModuleForDecl (decl, true )) {
4740
4785
if (auto native = resolveSwiftDecl<ClassDecl>(decl, name,
4786
+ hasKnownSwiftName,
4741
4787
clangModule)) {
4742
4788
return native;
4743
4789
}
0 commit comments