[cfe-dev] local submodule visibility, namespaces and Decl::getOwningModule()

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Tue Oct 23 17:10:33 PDT 2018

On Mon, 15 Oct 2018 at 10:13, Adrian Prantl via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> 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.

Sort of. In practice, what's happening is this:

When we create a declaration, we inherit its owning module from its lexical
parent by default. And we ensure that the lexical parent of the TU
declaration corresponds to the module we're currently "in". When a
declaration is injected into a lexical declaration context from a different
module, such as happens when adding a template specialization to an
imported template, that default behavior will pick up the current module at
global scope, but will pick up the owning module of the enclosing namespace
declaration at namespace scope, which will be the owning module of
whichever declaration of the template we picked. Now, this usually doesn't
matter, because a template specialization doesn't really *have* a
meaningful notion of "owning module". For visibility purposes, the
specialization should be visible wherever the corresponding template is
visible, and for linkage purposes, it should be considered owned by the
same module as the template pattern. So in some sense the bug is in the
global-scope case: we should always treat the specialization as being owned
by module A.

I think there's a chance that you're asking the wrong question -- perhaps
you should be trying to determine whether the declaration in question is
imported from a module *file*, not what its semantic owning module is. (As
an example, suppose we're tracking module ownership but not using PCM
files. If we textually enter a modular header of some other module, I think
you want to *not* treat declarations in that header as being owned by a
module for the purpose of -gmodules, because there is no reason to think
there's separate debug information for that header.) You can figure that
out by calling Decl::isFromASTFile(), and if you want to know *which* AST
file the declaration comes from (because you know that some AST files have
debug information and some don't), you can use
ASTReader::getOwningModuleFile to find out.

> 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.
> thanks,
> Adrian
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20181023/a70542d5/attachment.html>

More information about the cfe-dev mailing list