[C++ interop] Single enum decl for all copies of a single namespace vs extensions

Import namespaces as EnumDecl. by pschuh · Pull Request #26339 · apple/swift · GitHub pulls namespaces in as enum decls. In Add -enable-cxx-interop flag and support for extern "C" {} by pschuh · Pull Request #25870 · apple/swift · GitHub @jrose proposes that there could be a dummy module where namespaces get put and then this can be found and other namespaces can be imported as extensions.

Because namespaces already have a notion of getCanonicalDecl, this could be the one that is imported as the original namespace that other namespaces are an extension of.

Another option is to import all the namespace's redecls() as one decl. This works for unifying namespaces in a single file into a single swift namespace. However, if you "import module1"; use decl from namespace; import module2; use decl from namespace again. it appears that the namespace imported in module1 does not see the namespace redecl in module2, so it gets imported as the canonical decl without any reference to module2. The lazy decl loading would need to be aware that more decls could show up after the second import.

I think, however, that this all may break down when we have two swift modules that import c++ namespaces and then a third swift module that imports both of those. How would there be only one namespace-enum in that situation? Does it even matter that there is one namespace-enum in that case? Should namespace be private to the swift modules that imports them?

1 Like

Since the namespaces go into the mangling without the Clang module attached, I think we have a good chance of getting away with "one Swift 'namespace enum' per namespace per module". That'd probably be another DenseMap to keep around on the ClangImporter, but I think it would work.

That would be like using getCanonicalDecl(), but partitioning it by the imported clang module?

Sorta. You could pick a different "canonical-ish" decl for the namespace in each module, but I think we could also get away with using the same canonical Clang decl for multiple Swift decls. (We already do that for things that have been renamed, but usually only one of them is the "real" one, and the others are either typealiases or marked unavailable.)

1 Like