diff options
author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2025-01-24 10:51:10 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-24 10:51:10 +0800 |
commit | 378dcf61014b787b3542b917f6296c9fb5ec490c (patch) | |
tree | 9d6d0227abee0f139c8371dbf445bc5187ec137d /clang/lib/Sema/SemaLookup.cpp | |
parent | 0ef39a882bb342982929d2c856d7865de147a3c7 (diff) | |
download | llvm-378dcf61014b787b3542b917f6296c9fb5ec490c.zip llvm-378dcf61014b787b3542b917f6296c9fb5ec490c.tar.gz llvm-378dcf61014b787b3542b917f6296c9fb5ec490c.tar.bz2 |
[C++20] [Modules] Fix may-be incorrect ADL for module local entities (#123931)
Close https://github.com/llvm/llvm-project/issues/123815
See the comments for details. We can't get primary context arbitrarily
since the redecl may have different context and information.
There is a TODO for modules specific case, I'd like to make it after
this PR.
Diffstat (limited to 'clang/lib/Sema/SemaLookup.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 2ed8d36..5f8ffa7 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -2914,7 +2914,57 @@ static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces, while (!Ctx->isFileContext() || Ctx->isInlineNamespace()) Ctx = Ctx->getParent(); - Namespaces.insert(Ctx->getPrimaryContext()); + // Actually it is fine to always do `Namespaces.insert(Ctx);` simply. But it + // may cause more allocations in Namespaces and more unnecessary lookups. So + // we'd like to insert the representative namespace only. + DeclContext *PrimaryCtx = Ctx->getPrimaryContext(); + Decl *PrimaryD = cast<Decl>(PrimaryCtx); + Decl *D = cast<Decl>(Ctx); + ASTContext &AST = D->getASTContext(); + + // TODO: Technically it is better to insert one namespace per module. e.g., + // + // ``` + // //--- first.cppm + // export module first; + // namespace ns { ... } // first namespace + // + // //--- m-partA.cppm + // export module m:partA; + // import first; + // + // namespace ns { ... } + // namespace ns { ... } + // + // //--- m-partB.cppm + // export module m:partB; + // import first; + // import :partA; + // + // namespace ns { ... } + // namespace ns { ... } + // + // ... + // + // //--- m-partN.cppm + // export module m:partN; + // import first; + // import :partA; + // ... + // import :part$(N-1); + // + // namespace ns { ... } + // namespace ns { ... } + // + // consume(ns::any_decl); // the lookup + // ``` + // + // We should only insert once for all namespaces in module m. + if (D->isInNamedModule() && + !AST.isInSameModule(D->getOwningModule(), PrimaryD->getOwningModule())) + Namespaces.insert(Ctx); + else + Namespaces.insert(PrimaryCtx); } // Add the associated classes and namespaces for argument-dependent |