Repository: apple/swift
File: lib/ClangImporter/ImportDecl.cpp (C++)

Code before:
    ///
    /// Pass \p hasKnownSwiftName when the Clang declaration is annotated with NS_SWIFT_NAME or similar,
    /// such that the @objc provided name is known.
    template <typename T, typename U>
    T* hasNonLocalNativeSwiftDecl(U *decl, Identifier name, bool hasKnownSwiftName) {
      assert(!decl->hasDefinition() && "This method is only intended to be used on incomplete Clang types");

      // We intentionally do not consider if the declaration has a clang::ExternalSourceSymbolAttr
      // attribute, since we can't know if the corresponding Swift definition is "local" (ie.
      // in the overlay or bridging header owner) or not.

      // Check first if the Swift definition is "local"
      auto owningClangModule = Impl.getClangModuleForDecl(decl, /*allowForwardDeclaration*/ true);
      if (owningClangModule && resolveSwiftDecl<T>(decl, name, hasKnownSwiftName, owningClangModule))
        return nullptr;

      // If not, check all imported Swift modules for a definition
      if (auto mainModule = Impl.SwiftContext.MainModule) {
        llvm::SmallVector<ValueDecl *> results;
        llvm::SmallVector<ImportedModule> importedModules;

        mainModule->getImportedModules(importedModules,
                                       ModuleDecl::getImportFilterAll());

        llvm::SmallSet<ModuleDecl *, 16> seenModules;
        for (auto &import : importedModules) {
          if (import.importedModule->isNonSwiftModule())
            continue;
          if (!seenModules.insert(import.importedModule).second)
            continue;

          if (T *result = resolveSwiftDeclImpl<T>(
                  decl, name, hasKnownSwiftName, import.importedModule,
                  /*allowObjCMismatchFallback*/ false, /*cacheResult*/ false))
            return result;
        }
      }

      return nullptr;
    }

    template <typename T, typename U>
    bool hasNativeSwiftDecl(const U *decl, Identifier name,
                            const DeclContext *dc, T *&swiftDecl,
                            bool hasKnownSwiftName = true) {
      if (!importer::hasNativeSwiftDecl(decl))
        return false;
      auto wrapperUnit = cast<ClangModuleUnit>(dc->getModuleScopeContext());
      swiftDecl = resolveSwiftDecl<T>(decl, name, hasKnownSwiftName,
                                      wrapperUnit);
      return true;

Review comment (refactor):
Open question: should `getImportedModules()` deduplicate the modules instead?

Code after:
    /// a Clang module, the Swift overlay for that module does not count as "non-local". Similarly,
    /// if the Clang node is in a bridging header, any owners of that header also do not count as
    /// "non-local". This is intended to find @objc exposed Swift declarations in a different module
    /// that share the name as the forward declaration.
    ///
    /// Pass \p hasKnownSwiftName when the Clang declaration is annotated with NS_SWIFT_NAME or similar,
    /// such that the @objc provided name is known.
    template <typename T, typename U>
    T* hasNonLocalNativeSwiftDecl(U *decl, Identifier name, bool hasKnownSwiftName) {
      assert(!decl->hasDefinition() && "This method is only intended to be used on incomplete Clang types");

      // We intentionally do not consider if the declaration has a clang::ExternalSourceSymbolAttr
      // attribute, since we can't know if the corresponding Swift definition is "local" (ie.
      // in the overlay or bridging header owner) or not.

      // Check first if the Swift definition is "local"
      auto owningClangModule = Impl.getClangModuleForDecl(decl, /*allowForwardDeclaration*/ true);
      if (owningClangModule && resolveSwiftDecl<T>(decl, name, hasKnownSwiftName, owningClangModule))
        return nullptr;

      // If not, check all imported Swift modules for a definition
      if (auto mainModule = Impl.SwiftContext.MainModule) {
        llvm::SmallVector<ValueDecl *> results;
        llvm::SmallVector<ImportedModule> importedModules;

        mainModule->getImportedModules(importedModules,
                                       ModuleDecl::getImportFilterAll());

        llvm::SmallSet<ModuleDecl *, 16> seenModules;
        for (auto &import : importedModules) {
          if (import.importedModule->isNonSwiftModule())
            continue;
          if (!seenModules.insert(import.importedModule).second) {
            ++NumSkippedDuplicateImportedSwiftModulesForForwardDeclaredObjCTypes;
            continue;
          }

          if (T *result = resolveSwiftDeclImpl<T>(
                  decl, name, hasKnownSwiftName, import.importedModule,
                  /*allowObjCMismatchFallback*/ false, /*cacheResult*/ false))
            return result;
        }
      }

      return nullptr;
    }

    template <typename T, typename U>
    bool hasNativeSwiftDecl(const U *decl, Identifier name,
                            const DeclContext *dc, T *&swiftDecl,
                            bool hasKnownSwiftName = true) {