@@ -639,8 +639,9 @@ void ModuleDecl::lookupObjCMethods(
639639 FORWARD (lookupObjCMethods, (selector, results));
640640}
641641
642- void ModuleDecl::lookupImportedSPIGroups (const ModuleDecl *importedModule,
643- SmallVectorImpl<Identifier> &spiGroups) const {
642+ void ModuleDecl::lookupImportedSPIGroups (
643+ const ModuleDecl *importedModule,
644+ llvm::SmallSetVector<Identifier, 4 > &spiGroups) const {
644645 FORWARD (lookupImportedSPIGroups, (importedModule, spiGroups));
645646}
646647
@@ -2190,31 +2191,50 @@ bool SourceFile::isImportedImplementationOnly(const ModuleDecl *module) const {
21902191 return !imports.isImportedBy (module , getParentModule ());
21912192}
21922193
2193- void SourceFile::lookupImportedSPIGroups (const ModuleDecl *importedModule,
2194- SmallVectorImpl<Identifier> &spiGroups) const {
2194+ bool ModuleDecl::isImportedImplementationOnly (const ModuleDecl *module ) const {
2195+ auto &imports = getASTContext ().getImportCache ();
2196+
2197+ // Look through non-implementation-only imports to see if module is imported
2198+ // in some other way. Otherwise we assume it's implementation-only imported.
2199+ ModuleDecl::ImportFilter filter;
2200+ filter |= ModuleDecl::ImportFilterKind::Public;
2201+ filter |= ModuleDecl::ImportFilterKind::Private;
2202+ filter |= ModuleDecl::ImportFilterKind::SPIAccessControl;
2203+ filter |= ModuleDecl::ImportFilterKind::ShadowedBySeparateOverlay;
2204+ SmallVector<ModuleDecl::ImportedModule, 4 > results;
2205+ getImportedModules (results, filter);
2206+
2207+ for (auto &desc : results) {
2208+ if (imports.isImportedBy (module , desc.second ))
2209+ return false ;
2210+ }
2211+
2212+ return true ;
2213+ }
2214+
2215+ void SourceFile::lookupImportedSPIGroups (
2216+ const ModuleDecl *importedModule,
2217+ llvm::SmallSetVector<Identifier, 4 > &spiGroups) const {
21952218 for (auto &import : Imports) {
21962219 if (import .importOptions .contains (ImportFlags::SPIAccessControl) &&
21972220 importedModule == std::get<ModuleDecl*>(import .module )) {
21982221 auto importedSpis = import .spiGroups ;
2199- spiGroups.append (importedSpis.begin (), importedSpis.end ());
2222+ spiGroups.insert (importedSpis.begin (), importedSpis.end ());
22002223 }
22012224 }
22022225}
22032226
22042227bool SourceFile::isImportedAsSPI (const ValueDecl *targetDecl) const {
22052228 auto targetModule = targetDecl->getModuleContext ();
2206- SmallVector <Identifier, 4 > importedSPIGroups;
2229+ llvm::SmallSetVector <Identifier, 4 > importedSPIGroups;
22072230 lookupImportedSPIGroups (targetModule, importedSPIGroups);
22082231 if (importedSPIGroups.empty ()) return false ;
22092232
22102233 auto declSPIGroups = targetDecl->getSPIGroups ();
22112234
2212- // Note: If we reach a point where there are many SPI imports or SPI groups
2213- // on decls we could optimize this further by using a set.
2214- for (auto importedSPI : importedSPIGroups)
2215- for (auto declSPI : declSPIGroups)
2216- if (importedSPI == declSPI)
2217- return true ;
2235+ for (auto declSPI : declSPIGroups)
2236+ if (importedSPIGroups.count (declSPI))
2237+ return true ;
22182238
22192239 return false ;
22202240}
0 commit comments