@@ -4535,30 +4535,35 @@ namespace {
4535
4535
}
4536
4536
4537
4537
template <typename T, typename U>
4538
- T *resolveSwiftDeclImpl (const U *decl, Identifier name, bool hasCustomName,
4539
- ModuleDecl *overlay) {
4538
+ T *resolveSwiftDeclImpl (const U *decl, Identifier name,
4539
+ bool hasKnownSwiftName, ModuleDecl *overlay) {
4540
4540
const auto &languageVersion =
4541
4541
Impl.SwiftContext .LangOpts .EffectiveLanguageVersion ;
4542
4542
4543
- // None = not enough information
4544
- // true/false = definitive answer
4545
- auto isMatch = [&](const T *singleResult) -> Optional<bool > {
4543
+ auto isMatch = [&](const T *singleResult, bool baseNameMatches) -> bool {
4546
4544
const DeclAttributes &attrs = singleResult->getAttrs ();
4547
4545
4548
4546
// Skip versioned variants.
4549
4547
if (attrs.isUnavailableInSwiftVersion (languageVersion))
4550
4548
return false ;
4551
4549
4552
- // If Clang decl has a custom Swift name, then `name` is that name.
4553
- if (hasCustomName)
4554
- return None;
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;
4555
4560
4556
4561
// Skip if a different name is used for Objective-C.
4557
4562
if (auto objcAttr = attrs.getAttribute <ObjCAttr>())
4558
4563
if (auto objcName = objcAttr->getName ())
4559
4564
return objcName->getSimpleName () == name;
4560
4565
4561
- return None ;
4566
+ return baseNameMatches ;
4562
4567
};
4563
4568
4564
4569
// First look at Swift types with the same name.
@@ -4567,38 +4572,26 @@ namespace {
4567
4572
T *found = nullptr ;
4568
4573
for (auto result : results) {
4569
4574
if (auto singleResult = dyn_cast<T>(result)) {
4570
- // Eliminate false positives (Swift name matches but Obj-C name doesn't).
4571
- Optional<bool > matched = isMatch (singleResult);
4572
- if (matched.hasValue () && !*matched)
4573
- continue ;
4574
-
4575
- // Skip if type not exposed to Objective-C.
4576
- if (!hasCustomName && !singleResult->isObjC ())
4577
- continue ;
4578
-
4579
- if (found)
4580
- return nullptr ;
4581
-
4582
- found = singleResult;
4575
+ if (isMatch (singleResult, /* baseNameMatches=*/ true )) {
4576
+ if (found)
4577
+ return nullptr ;
4578
+ found = singleResult;
4579
+ }
4583
4580
}
4584
4581
}
4585
4582
4586
- if (!found && !hasCustomName) {
4587
- // Try harder to find match with custom Objective-C name.
4588
- // Only positive matches can be used, since we've already eliminated
4589
- // all native Swift types with the same native name.
4583
+ if (!found && !hasKnownSwiftName) {
4584
+ // Try harder to find a match looking at just custom Objective-C names.
4590
4585
SmallVector<Decl *, 64 > results;
4591
4586
overlay->getTopLevelDecls (results);
4592
4587
for (auto result : results) {
4593
4588
if (auto singleResult = dyn_cast<T>(result)) {
4594
- Optional<bool > matched = isMatch (singleResult);
4595
- if (!(matched.hasValue () && *matched))
4596
- continue ;
4597
-
4598
- if (found)
4599
- return nullptr ;
4600
-
4601
- found = singleResult;
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
+ }
4602
4595
}
4603
4596
}
4604
4597
}
@@ -4611,17 +4604,17 @@ namespace {
4611
4604
}
4612
4605
4613
4606
template <typename T, typename U>
4614
- T *resolveSwiftDecl (const U *decl, Identifier name, bool hasCustomName,
4615
- ClangModuleUnit *clangModule) {
4607
+ T *resolveSwiftDecl (const U *decl, Identifier name,
4608
+ bool hasKnownSwiftName, ClangModuleUnit *clangModule) {
4616
4609
if (auto overlay = clangModule->getOverlayModule ())
4617
- return resolveSwiftDeclImpl<T>(decl, name, hasCustomName , overlay);
4610
+ return resolveSwiftDeclImpl<T>(decl, name, hasKnownSwiftName , overlay);
4618
4611
if (clangModule == Impl.ImportedHeaderUnit ) {
4619
4612
// Use an index-based loop because new owners can come in as we're
4620
4613
// iterating.
4621
4614
for (size_t i = 0 ; i < Impl.ImportedHeaderOwners .size (); ++i) {
4622
4615
ModuleDecl *owner = Impl.ImportedHeaderOwners [i];
4623
- if (T *result = resolveSwiftDeclImpl<T>(decl, name, hasCustomName,
4624
- owner))
4616
+ if (T *result = resolveSwiftDeclImpl<T>(decl, name,
4617
+ hasKnownSwiftName, owner))
4625
4618
return result;
4626
4619
}
4627
4620
}
@@ -4634,7 +4627,7 @@ namespace {
4634
4627
if (!importer::hasNativeSwiftDecl (decl))
4635
4628
return false ;
4636
4629
auto wrapperUnit = cast<ClangModuleUnit>(dc->getModuleScopeContext ());
4637
- swiftDecl = resolveSwiftDecl<T>(decl, name, /* hasCustomName =*/ true ,
4630
+ swiftDecl = resolveSwiftDecl<T>(decl, name, /* hasCustomSwiftName =*/ true ,
4638
4631
wrapperUnit);
4639
4632
return true ;
4640
4633
}
@@ -4664,14 +4657,15 @@ namespace {
4664
4657
*correctSwiftName);
4665
4658
4666
4659
Identifier name = importedName.getDeclName ().getBaseIdentifier ();
4667
- bool hasCustomName = importedName.hasCustomName ();
4660
+ bool hasKnownSwiftName = importedName.hasCustomName ();
4668
4661
4669
4662
// FIXME: Figure out how to deal with incomplete protocols, since that
4670
4663
// notion doesn't exist in Swift.
4671
4664
if (!decl->hasDefinition ()) {
4672
4665
// Check if this protocol is implemented in its overlay.
4673
4666
if (auto clangModule = Impl.getClangModuleForDecl (decl, true ))
4674
- if (auto native = resolveSwiftDecl<ProtocolDecl>(decl, name, hasCustomName,
4667
+ if (auto native = resolveSwiftDecl<ProtocolDecl>(decl, name,
4668
+ hasKnownSwiftName,
4675
4669
clangModule))
4676
4670
return native;
4677
4671
@@ -4783,13 +4777,13 @@ namespace {
4783
4777
*correctSwiftName);
4784
4778
4785
4779
auto name = importedName.getDeclName ().getBaseIdentifier ();
4786
- bool hasCustomName = importedName.hasCustomName ();
4780
+ bool hasKnownSwiftName = importedName.hasCustomName ();
4787
4781
4788
4782
if (!decl->hasDefinition ()) {
4789
4783
// Check if this class is implemented in its overlay.
4790
4784
if (auto clangModule = Impl.getClangModuleForDecl (decl, true )) {
4791
4785
if (auto native = resolveSwiftDecl<ClassDecl>(decl, name,
4792
- hasCustomName ,
4786
+ hasKnownSwiftName ,
4793
4787
clangModule)) {
4794
4788
return native;
4795
4789
}
0 commit comments