I'm trying to fix a bug in the -gmodules debug info that appears when debugging Clang with local submodule visibility enabled. In my reduced testcase, I have a module A, defining a template "AlignedCharArray<unsigned, unsigned>", and two templates "SmallVector" and "Optional" that use it. In module B, I'm instantiating an Optional that instantiates an AlignedCharArray<4, 16>. In module C, I'm instantiating a SmallVector that also instantiates an AlignedCharArray<4, 16>.
The -gmodules debug info format saves space by forward-declaring types that are defined in an already-imported module and specify which module they came from. To point to the module of the definition CGDebugInfo::getParentModuleOrNull(const Decl *D) uses Decl::getOwningModule(). This mechanism works as expected, but only if the TemplateDecl is not inside a namespace.
When compiling the attached testcase with -U WITH_NAMESPACE, the owning module for the ClassTemplateSpecializationDecl (of AlignedCharArray<4, 16>) in module B is C. (B imports C, so the C specialization is instantiated first).
When compiling the attached testcase with -D WITH_NAMESPACE, the owning module for the ClassTemplateSpecializationDecl (of AlignedCharArray<4, 16>) in module B is A. (A is where the TemplateDecl that is being specialized comes from).
I'm sure that this discrepancy must be because a namespace can be spread out over many modules. I can "fix" my issue by always emitting full debug info definitions for template specializations inside of namespaces. But I'm also really curious whether the behavior I'm experiencing is indicative of a general bug/shortcoming of the LSV implementation that we might be interested in fixing. The owning module of each declaration is set to the owning module of its DeclContext and namespaces seem to interfere with this mechanism.
testcase.diff (3.89 KB)