[clang] 5f62c79 - [C++20] [Modules] Use current named module to do module local lookup
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 3 04:04:14 PDT 2025
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) {}
+
+}
+
+
+
More information about the cfe-commits
mailing list