@@ -3031,33 +3031,25 @@ void ClangImporter::loadObjCMethods(
30313031
30323032 // Collect the set of visible Objective-C methods with this selector.
30333033 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 );
30393034
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 );
30473040
3041+ if (objcMethod) {
30483042 // If we found a property accessor, import the property.
30493043 if (objcMethod->isPropertyAccessor ())
30503044 (void )Impl.importDecl (objcMethod->findPropertyDecl (true ),
30513045 Impl.CurrentVersion );
30523046
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 ));
30573049 }
30583050
30593051 // If we didn't find anything, we're done.
3060- if (foundMethods. empty () )
3052+ if (method == nullptr )
30613053 return ;
30623054
30633055 // If we did find something, it might be a duplicate of something we found
@@ -3066,10 +3058,9 @@ void ClangImporter::loadObjCMethods(
30663058 // FIXME: We shouldn't need to do this.
30673059 llvm::SmallPtrSet<AbstractFunctionDecl *, 4 > known;
30683060 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);
30733064}
30743065
30753066void
@@ -3730,52 +3721,19 @@ void ClangImporter::Implementation::lookupAllObjCMembers(
37303721 }
37313722}
37323723
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-
37543724Optional<TinyPtrVector<ValueDecl *>>
37553725ClangImporter::Implementation::loadNamedMembers (
37563726 const IterableDeclContext *IDC, DeclBaseName N, uint64_t contextData) {
37573727
37583728 auto *D = IDC->getDecl ();
3759- auto *DC = cast<DeclContext>(D );
3729+ auto *DC = D-> getInnermostDeclContext ( );
37603730 auto *CD = D->getClangDecl ();
37613731 auto *CDC = cast<clang::DeclContext>(CD);
37623732 assert (CD && " loadNamedMembers on a Decl without a clangDecl" );
37633733
37643734 auto *nominal = DC->getSelfNominalTypeDecl ();
37653735 auto effectiveClangContext = getEffectiveClangContext (nominal);
37663736
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-
37793737 // There are 3 cases:
37803738 //
37813739 // - The decl is from a bridging header, CMO is Some(nullptr)
@@ -3799,7 +3757,16 @@ ClangImporter::Implementation::loadNamedMembers(
37993757
38003758 assert (isa<clang::ObjCContainerDecl>(CD) || isa<clang::NamespaceDecl>(CD));
38013759
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);
38033770
38043771 TinyPtrVector<ValueDecl *> Members;
38053772 for (auto entry : table->lookup (SerializedSwiftName (N),
@@ -3829,7 +3796,7 @@ ClangImporter::Implementation::loadNamedMembers(
38293796 auto member = entry.get <clang::NamedDecl *>();
38303797 if (!isVisibleClangEntry (member)) continue ;
38313798
3832- // Skip Decls from different clang::DeclContexts
3799+ // Skip Decls from different clang::DeclContexts
38333800 if (member->getDeclContext () != CDC) continue ;
38343801
38353802 SmallVector<Decl*, 4 > tmp;
@@ -3853,6 +3820,16 @@ ClangImporter::Implementation::loadNamedMembers(
38533820 Members.push_back (cast<ValueDecl>(ctor));
38543821 }
38553822 }
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+
38563833 return Members;
38573834}
38583835
0 commit comments