@@ -770,6 +770,42 @@ ModuleDecl *Decl::getModuleContext() const {
770770 return getDeclContext ()->getParentModule ();
771771}
772772
773+ // / If `decl` is an imported Cxx decl, returns the actual module that the decl
774+ // / was imported from. This is necessary to compensate for the way that
775+ // / Cxx `namespace` declarations are imported. Since namespaces can span
776+ // / multiple Clang modules, the corresponding decls and all of their members get
777+ // / associated with the Clang imported header module (named `__ObjC`). This
778+ // / utility reaches through the Clang AST to find the actual module that members
779+ // / of namespaces originated from.
780+ static ModuleDecl *getModuleContextForNameLookupForCxxDecl (const Decl *decl) {
781+ auto &ctx = decl->getASTContext ();
782+ if (!ctx.LangOpts .EnableCXXInterop )
783+ return nullptr ;
784+
785+ if (!decl->hasClangNode ())
786+ return nullptr ;
787+
788+ auto parentModule = decl->getModuleContext ();
789+
790+ // We only need to look for the real parent module when the existing parent
791+ // is the imported header module.
792+ if (!parentModule->isClangHeaderImportModule ())
793+ return nullptr ;
794+
795+ auto clangModule = decl->getClangDecl ()->getOwningModule ();
796+ if (!clangModule)
797+ return nullptr ;
798+
799+ return ctx.getClangModuleLoader ()->getWrapperForModule (clangModule);
800+ }
801+
802+ ModuleDecl *Decl::getModuleContextForNameLookup () const {
803+ if (auto parentModule = getModuleContextForNameLookupForCxxDecl (this ))
804+ return parentModule;
805+
806+ return getModuleContext ();
807+ }
808+
773809// / Retrieve the diagnostic engine for diagnostics emission.
774810DiagnosticEngine &Decl::getDiags () const {
775811 return getASTContext ().Diags ;
@@ -3946,7 +3982,7 @@ ValueDecl::getSatisfiedProtocolRequirements(bool Sorted) const {
39463982std::optional<AttributedImport<ImportedModule>>
39473983ValueDecl::findImport (const DeclContext *fromDC) const {
39483984 // If the type is from the current module, there's no import.
3949- auto module = getModuleContext ();
3985+ auto module = getModuleContextForNameLookup ();
39503986 if (module == fromDC->getParentModule ())
39513987 return std::nullopt ;
39523988
0 commit comments