@@ -2914,7 +2914,57 @@ static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces,
2914
2914
while (!Ctx->isFileContext () || Ctx->isInlineNamespace ())
2915
2915
Ctx = Ctx->getParent ();
2916
2916
2917
- Namespaces.insert (Ctx->getPrimaryContext ());
2917
+ // Actually it is fine to always do `Namespaces.insert(Ctx);` simply. But it
2918
+ // may cause more allocations in Namespaces and more unnecessary lookups. So
2919
+ // we'd like to insert the representative namespace only.
2920
+ DeclContext *PrimaryCtx = Ctx->getPrimaryContext ();
2921
+ Decl *PrimaryD = cast<Decl>(PrimaryCtx);
2922
+ Decl *D = cast<Decl>(Ctx);
2923
+ ASTContext &AST = D->getASTContext ();
2924
+
2925
+ // TODO: Technically it is better to insert one namespace per module. e.g.,
2926
+ //
2927
+ // ```
2928
+ // //--- first.cppm
2929
+ // export module first;
2930
+ // namespace ns { ... } // first namespace
2931
+ //
2932
+ // //--- m-partA.cppm
2933
+ // export module m:partA;
2934
+ // import first;
2935
+ //
2936
+ // namespace ns { ... }
2937
+ // namespace ns { ... }
2938
+ //
2939
+ // //--- m-partB.cppm
2940
+ // export module m:partB;
2941
+ // import first;
2942
+ // import :partA;
2943
+ //
2944
+ // namespace ns { ... }
2945
+ // namespace ns { ... }
2946
+ //
2947
+ // ...
2948
+ //
2949
+ // //--- m-partN.cppm
2950
+ // export module m:partN;
2951
+ // import first;
2952
+ // import :partA;
2953
+ // ...
2954
+ // import :part$(N-1);
2955
+ //
2956
+ // namespace ns { ... }
2957
+ // namespace ns { ... }
2958
+ //
2959
+ // consume(ns::any_decl); // the lookup
2960
+ // ```
2961
+ //
2962
+ // We should only insert once for all namespaces in module m.
2963
+ if (D->isInNamedModule () &&
2964
+ !AST.isInSameModule (D->getOwningModule (), PrimaryD->getOwningModule ()))
2965
+ Namespaces.insert (Ctx);
2966
+ else
2967
+ Namespaces.insert (PrimaryCtx);
2918
2968
}
2919
2969
2920
2970
// Add the associated classes and namespaces for argument-dependent
0 commit comments