@@ -3031,33 +3031,25 @@ void ClangImporter::loadObjCMethods(
3031
3031
3032
3032
// Collect the set of visible Objective-C methods with this selector.
3033
3033
clang::Selector clangSelector = Impl.exportSelector (selector);
3034
- SmallVector<clang::ObjCMethodDecl *, 4 > objcMethods;
3035
- auto &sema = Impl.Instance ->getSema ();
3036
- sema.CollectMultipleMethodsInGlobalPool (clangSelector, objcMethods,
3037
- isInstanceMethod,
3038
- /* CheckTheOther=*/ false );
3039
3034
3040
- // Check whether this method is in the class we care about.
3041
- SmallVector<AbstractFunctionDecl *, 4 > foundMethods;
3042
- for (auto objcMethod : objcMethods) {
3043
- // Find the owner of this method and determine whether it is the class
3044
- // we're looking for.
3045
- if (objcMethod->getClassInterface () != objcClass)
3046
- continue ;
3035
+ AbstractFunctionDecl *method = nullptr ;
3036
+ auto *objcMethod = objcClass->lookupMethod (
3037
+ clangSelector, isInstanceMethod,
3038
+ /* shallowCategoryLookup=*/ false ,
3039
+ /* followSuper=*/ false );
3047
3040
3041
+ if (objcMethod) {
3048
3042
// If we found a property accessor, import the property.
3049
3043
if (objcMethod->isPropertyAccessor ())
3050
3044
(void )Impl.importDecl (objcMethod->findPropertyDecl (true ),
3051
3045
Impl.CurrentVersion );
3052
3046
3053
- if (auto method = dyn_cast_or_null<AbstractFunctionDecl>(
3054
- Impl.importDecl (objcMethod, Impl.CurrentVersion ))) {
3055
- foundMethods.push_back (method);
3056
- }
3047
+ method = dyn_cast_or_null<AbstractFunctionDecl>(
3048
+ Impl.importDecl (objcMethod, Impl.CurrentVersion ));
3057
3049
}
3058
3050
3059
3051
// If we didn't find anything, we're done.
3060
- if (foundMethods. empty () )
3052
+ if (method == nullptr )
3061
3053
return ;
3062
3054
3063
3055
// If we did find something, it might be a duplicate of something we found
@@ -3066,10 +3058,9 @@ void ClangImporter::loadObjCMethods(
3066
3058
// FIXME: We shouldn't need to do this.
3067
3059
llvm::SmallPtrSet<AbstractFunctionDecl *, 4 > known;
3068
3060
known.insert (methods.begin (), methods.end ());
3069
- for (auto method : foundMethods) {
3070
- if (known.insert (method).second )
3071
- methods.push_back (method);
3072
- }
3061
+
3062
+ if (known.insert (method).second )
3063
+ methods.push_back (method);
3073
3064
}
3074
3065
3075
3066
void
@@ -3730,52 +3721,19 @@ void ClangImporter::Implementation::lookupAllObjCMembers(
3730
3721
}
3731
3722
}
3732
3723
3733
- // Force the members of the entire inheritance hierarchy to be loaded and
3734
- // deserialized before loading the named member of this class. This allows the
3735
- // decl members table to be warmed up and enables the correct identification of
3736
- // overrides.
3737
- //
3738
- // FIXME: Very low hanging fruit: Loading everything is extremely wasteful. We
3739
- // should be able to just load the name lazy member loading is asking for.
3740
- static void ensureSuperclassMembersAreLoaded (const ClassDecl *CD) {
3741
- if (!CD)
3742
- return ;
3743
-
3744
- CD = CD->getSuperclassDecl ();
3745
- if (!CD || !CD->hasClangNode ())
3746
- return ;
3747
-
3748
- CD->loadAllMembers ();
3749
-
3750
- for (auto *ED : const_cast <ClassDecl *>(CD)->getExtensions ())
3751
- ED->loadAllMembers ();
3752
- }
3753
-
3754
3724
Optional<TinyPtrVector<ValueDecl *>>
3755
3725
ClangImporter::Implementation::loadNamedMembers (
3756
3726
const IterableDeclContext *IDC, DeclBaseName N, uint64_t contextData) {
3757
3727
3758
3728
auto *D = IDC->getDecl ();
3759
- auto *DC = cast<DeclContext>(D );
3729
+ auto *DC = D-> getInnermostDeclContext ( );
3760
3730
auto *CD = D->getClangDecl ();
3761
3731
auto *CDC = cast<clang::DeclContext>(CD);
3762
3732
assert (CD && " loadNamedMembers on a Decl without a clangDecl" );
3763
3733
3764
3734
auto *nominal = DC->getSelfNominalTypeDecl ();
3765
3735
auto effectiveClangContext = getEffectiveClangContext (nominal);
3766
3736
3767
- // FIXME: The legacy of mirroring protocol members rears its ugly head,
3768
- // and as a result we have to bail on any @interface or @category that
3769
- // has a declared protocol conformance.
3770
- if (auto *ID = dyn_cast<clang::ObjCInterfaceDecl>(CD)) {
3771
- if (ID->protocol_begin () != ID->protocol_end ())
3772
- return None;
3773
- }
3774
- if (auto *CCD = dyn_cast<clang::ObjCCategoryDecl>(CD)) {
3775
- if (CCD->protocol_begin () != CCD->protocol_end ())
3776
- return None;
3777
- }
3778
-
3779
3737
// There are 3 cases:
3780
3738
//
3781
3739
// - The decl is from a bridging header, CMO is Some(nullptr)
@@ -3799,7 +3757,16 @@ ClangImporter::Implementation::loadNamedMembers(
3799
3757
3800
3758
assert (isa<clang::ObjCContainerDecl>(CD) || isa<clang::NamespaceDecl>(CD));
3801
3759
3802
- ensureSuperclassMembersAreLoaded (dyn_cast<ClassDecl>(D));
3760
+ // Force the members of the entire inheritance hierarchy to be loaded and
3761
+ // deserialized before loading the named member of a class. This warms up
3762
+ // ClangImporter::Implementation::MembersForNominal, used for computing
3763
+ // property overrides.
3764
+ //
3765
+ // FIXME: If getOverriddenDecl() kicked off a request for imported decls,
3766
+ // we could postpone this until overrides are actually requested.
3767
+ if (auto *classDecl = dyn_cast<ClassDecl>(D))
3768
+ if (auto *superclassDecl = classDecl->getSuperclassDecl ())
3769
+ (void ) const_cast <ClassDecl *>(superclassDecl)->lookupDirect (N);
3803
3770
3804
3771
TinyPtrVector<ValueDecl *> Members;
3805
3772
for (auto entry : table->lookup (SerializedSwiftName (N),
@@ -3829,7 +3796,7 @@ ClangImporter::Implementation::loadNamedMembers(
3829
3796
auto member = entry.get <clang::NamedDecl *>();
3830
3797
if (!isVisibleClangEntry (member)) continue ;
3831
3798
3832
- // Skip Decls from different clang::DeclContexts
3799
+ // Skip Decls from different clang::DeclContexts
3833
3800
if (member->getDeclContext () != CDC) continue ;
3834
3801
3835
3802
SmallVector<Decl*, 4 > tmp;
@@ -3853,6 +3820,16 @@ ClangImporter::Implementation::loadNamedMembers(
3853
3820
Members.push_back (cast<ValueDecl>(ctor));
3854
3821
}
3855
3822
}
3823
+
3824
+ if (!isa<ProtocolDecl>(D)) {
3825
+ if (auto *OCD = dyn_cast<clang::ObjCContainerDecl>(CD)) {
3826
+ SmallVector<Decl *, 1 > newMembers;
3827
+ importMirroredProtocolMembers (OCD, DC, N, newMembers);
3828
+ for (auto member : newMembers)
3829
+ Members.push_back (cast<ValueDecl>(member));
3830
+ }
3831
+ }
3832
+
3856
3833
return Members;
3857
3834
}
3858
3835
0 commit comments