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

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


On Tue, 23 Oct 2018 at 17:29, Adrian Prantl via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> On Oct 23, 2018, at 5:10 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> 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.
>
>
> Thanks for the pointer! That interface sounds promising; I will try to
> expose it as a
>
>    virtual ASTSourceDescriptor getOwningModuleFile(Decl *);
>
> in ExternalASTSource and see if that gets me further.
>

A more general name might make sense at the ExternalASTSource level (eg,
lldb might want to specify that its declarations come from a certain .dwo
file), but that generally sounds reasonable to me.


> -- adrian
>
>
>
>> 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
>>
>
> _______________________________________________
> 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/0a7268a6/attachment.html>


More information about the cfe-dev mailing list