Author: Chuanqi Xu
Date: 2025-07-03T19:03:52+08:00
New Revision: 5f62c791061d5fb39e3686126042e4a090132efc

URL: 
https://github.com/llvm/llvm-project/commit/5f62c791061d5fb39e3686126042e4a090132efc
DIFF: 
https://github.com/llvm/llvm-project/commit/5f62c791061d5fb39e3686126042e4a090132efc.diff

LOG: [C++20] [Modules] Use current named module to do module local lookup

See the attached test for the motiviation.

Previously we dependent on the module ownership of the decl context to
perform module local lookup. But if the lookup is unqualified, we may
perform the lookup with canonical decl, which belongs to the incorrect
named module

Added: 
    clang/test/Modules/ModulesLocalNamespace.cppm

Modified: 
    clang/lib/Serialization/ASTReader.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 486971818f109..d42847a03cb11 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -8564,14 +8564,22 @@ bool ASTReader::FindExternalVisibleDeclsByName(const 
DeclContext *DC,
     Find(It->second.Table, Name);
   }
 
-  if (auto *NamedModule =
-          OriginalDC ? cast<Decl>(OriginalDC)->getTopLevelOwningNamedModule()
-                     : nullptr) {
+  auto FindModuleLocalLookup = [&, this](Module *NamedModule) {
     if (auto It = ModuleLocalLookups.find(DC); It != ModuleLocalLookups.end()) 
{
       ++NumModuleLocalVisibleDeclContexts;
       Find(It->second.Table, std::make_pair(Name, NamedModule));
     }
-  }
+  };
+  if (auto *NamedModule =
+          OriginalDC ? cast<Decl>(OriginalDC)->getTopLevelOwningNamedModule()
+                     : nullptr)
+    FindModuleLocalLookup(NamedModule);
+  // See clang/test/Modules/ModulesLocalNamespace.cppm for the motiviation 
case.
+  // We're going to find a decl but the decl context of the lookup is
+  // unspecified. In this case, the OriginalDC may be the decl context in other
+  // module.
+  if (ContextObj && ContextObj->getCurrentNamedModule())
+    FindModuleLocalLookup(ContextObj->getCurrentNamedModule());
 
   if (auto It = TULocalLookups.find(DC); It != TULocalLookups.end()) {
     ++NumTULocalVisibleDeclContexts;

diff  --git a/clang/test/Modules/ModulesLocalNamespace.cppm 
b/clang/test/Modules/ModulesLocalNamespace.cppm
new file mode 100644
index 0000000000000..9e05597809752
--- /dev/null
+++ b/clang/test/Modules/ModulesLocalNamespace.cppm
@@ -0,0 +1,47 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/m-a.cppm -emit-module-interface -o %t/m-a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-module-interface -o %t/m-b.pcm \
+// RUN:     -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 %t/b.cpp -fsyntax-only -verify 
-fprebuilt-module-path=%t
+
+//--- a.cppm
+export module a;
+namespace aa {
+
+}
+
+//--- m-a.cppm
+export module m:a;
+namespace aa {
+struct A {};
+}
+
+//--- b.cppm
+module m:b;
+import :a;
+
+namespace bb {
+struct B {
+    void func(aa::A);
+};
+}
+
+//--- b.cpp
+// expected-no-diagnostics
+module m:b.impl;
+import a;
+import :b;
+
+namespace bb {
+using namespace aa;
+
+void B::func(A) {} 
+
+}
+
+
+


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to