This is an archive of the discontinued LLVM Phabricator instance.

Top-level anonymous namespaces are missing import DW_TAG_imported_module and nested anonymous namespaces are not
ClosedPublic

Authored by kromanova on Sep 3 2015, 6:46 PM.

Details

Summary

I had a review opened for anonymous namespaces bug in llvm-commits (see http://reviews.llvm.org/D7895). It was opened in llvm-commits is because the first patch that I submitted was in the backend. However it seems that the frontend patch will be more appropriate in this case. David Blaikie advised to get cfe developers opinion, specifically Richard Smith's.
Rather than just adding cfe-dev to the reviewers list, I thought it will be better to open a brand new review.

There was quite a long discussion in llvm-commits list about this bug and several re-implementations of a fix, so it gets confusing after a while.
I will write a short summary of what was discussed in http://reviews.llvm.org/D7895

Problem #1:

DW_TAG_imported_module is missing from the compile unit's root scope. Without this tag, anonymous namespace is not imported into the root scope by PS4 debugger.

Consider the following testcase. Lack of DW_TAG_imported_module prevents our debugger from displaying the value of ‘a’.

#include <stdio.h>

namespace
{

int a = 5;

}

int main()
{

printf("%d\n", a);

return 0;

}

Problem #2:

Another (more general) problem is that while the clang compiler doesn't generate DW_TAG_imported_module for the top-level anonymous namespace, it generates this tag for nested anonymous namespaces. So, we have an asymmetrical situation.

namespace
{

namespace {
  int a1 = 5;
}
int a2 = 7;

}
int *b1 = &a1;
int *b2 = &a2;

DWARF:
<1><54>: Abbrev Number: 5 (DW_TAG_namespace)

<55>   DW_AT_decl_file   : 1
<56>   DW_AT_decl_line   : 2

<2><57>: Abbrev Number: 5 (DW_TAG_namespace)

<58>   DW_AT_decl_file   : 1
<59>   DW_AT_decl_line   : 3

....
<2><8d>: Abbrev Number: 7 (DW_TAG_imported_module)

<8e>   DW_AT_import      : <0x57>   [Abbrev Number: 5 (DW_TAG_namespace)]

Note that DW_TAG_import is not generated for the top-level anonymous namespace.

There was a long discussion if we want to generate explicit imports marked by DW_AT_artificial attribute for anonymous namespaces in Clang or not. Both GCC and ICC compilers generate explicit imports in this case. However, it's an arguable gray area between the compiler and the debugger. The final decision was *not* to generate DW_TAG_imported_module for all the platforms except PS4. On PS4 we definitely want it, since our debugger doesn't import the anonymous namespace automatically.

There were several different patches for this fix. For this review, I'm providing the latest FE patch only. It takes care of both problem #1 and problem #2.
See http://reviews.llvm.org/D7895 for more details/earlier patches.

Richard, could you please give your opinion on how that problem needs to get taken care of in the FE. I don't mind re-writing patch based on your comments, if necessary.
Thank you!

Diff Detail

Repository
rL LLVM

Event Timeline

kromanova updated this revision to Diff 34007.Sep 3 2015, 6:46 PM
kromanova retitled this revision from to Top-level anonymous namespaces are missing import DW_TAG_imported_module and nested anonymous namespaces are not .
kromanova updated this object.
kromanova added a subscriber: cfe-commits.
rsmith edited edge metadata.Sep 4 2015, 12:00 PM

I think this is fundamentally the right approach. Anonymous namespaces do inject a using directive, and we should not forget to pass it to the AST consumer.

lib/CodeGen/CGDebugInfo.cpp
3263–3264 ↗(On Diff #34007)

I think we should do this unconditionally, to better match the source language semantics, but I'm curious what David, Eric, and other folks on the DWARF side think.

lib/Parse/ParseDeclCXX.cpp
204 ↗(On Diff #34007)

This comment doesn't add anything and doesn't use the right name for either variable. Just remove it?

235 ↗(On Diff #34007)

Use nullptr, not NULL.

241 ↗(On Diff #34007)

Add an assert here:

assert(!ImplicitUsingDirectiveDecl && "nested namespace definition cannot define anonymous namespace");
lib/Sema/SemaDeclCXX.cpp
7189 ↗(On Diff #34007)

No space after &.

probinson added inline comments.Sep 8 2015, 3:08 PM
lib/CodeGen/CGDebugInfo.cpp
3263–3264 ↗(On Diff #34007)

David (in previous discussions and review comments) has said he thinks it is unnecessary as the debugger already must know so much about C++ to get various things right, it might as well know that it has to implicitly import the anonymous namespace contents. One example debugger UI allows the user to type source-like syntax, and requires the debugger to apply (for example) C++ parameter-type matching rules to distinguish between overloaded functions. Compared to this, implicit imports are child's play.

I believe Eric agrees with David; I don't remember whether Adrian said anything in the previous iterations of this patch.

I believe the explicit (although artificial) import is a good thing, because it matches the source language semantics. I find an important distinction between "which declarations are available in this scope" and "how does the user disambiguate declarations in this scope." As a counterpart to the above debugger UI example, I postulate a GUI drop-down list of symbols available in-scope; this UI needs to know nothing about language semantics and automatic imports, if the DWARF provides the correct explicit import. This suggests to me that the DWARF should provide it.

There's also the piddly detail that debuggers are not the only consumers of DWARF information, and presenting the DWARF in a more source-language-neutral way (i.e., with the explicit artificial import) could be beneficial for those other consumers, who might not necessarily want to learn language-specific scoping rules.

No debugger will be thrown for a loop if it sees the explicit import; however for some debuggers it would be redundant (because they implicitly import the anonymous namespace already). There is a pretty trivial space savings if it's omitted.

Katya has mentioned the GCC and ICC precedent; in fairness I will say GCC didn't used to emit this, and GDB tolerated that.

Note that the DWARF standard does not tell us what to do; it merely tells us how to emit the import, if we want to emit one. Whether we want to emit one is up to us.

rsmith added inline comments.Sep 8 2015, 3:51 PM
lib/CodeGen/CGDebugInfo.cpp
3263–3264 ↗(On Diff #34007)

I've chatted to David about this offline, and he said largely similar things. It seems that different DWARF consumers will want and expect different things here, so (sadly) we should do different things depending on who we think will be consuming the DWARF.

I'm fine keeping this conditional, but I don't think IR generation should be making this decision based on the triple, so I'd prefer it was phrased in a different way: add a CodeGenOpt for whether to emit imports for anonymous namespaces, and enable it for PS4 targets from the frontend.

probinson added inline comments.Sep 8 2015, 5:18 PM
lib/CodeGen/CGDebugInfo.cpp
3263–3264 ↗(On Diff #34007)

I think including the explicit import is not actively harmful to any consumer, or to object-file size; but if somebody insists on not having it, okay.

Assuming Katya is willing to invent the CodeGenOpt, I should add that not too far down on my to-do list is plumbing the LLVM "debugger tuning" idea up through Clang. We can make the tuning (rather than the triple) set the CodeGenOpt when the time comes.

probinson edited edge metadata.Sep 9 2015, 10:42 AM
probinson added a subscriber: probinson.

This seems pretty fine-grained for a CodeGenOpt (not that I've looked there, perhaps there are examples of similarly fine grained things already there?)- I'm curious to understand the preference towards that rather than perhaps the more general "Debugger tuning" sort of thing Paul's implemented/could be pushed up here.

On the LLVM side, debugger tuning is basically a way to package up settings for a variety of rather specific flags. Then the individual flags control their respective fine-grained behaviors. This approach was very clearly favored during the whole "what is tuning" design discussion.

So, having an "emit explicit import" flag follows that same design decision and makes rather more sense than peppering IRGen with tuning or triple checks. Whether the flag goes in CodeGenOpt or somewhere else is a separate question. There are other debug-related flags in there, but if they want to be factored out into their own DebugInfoOpt that's probably a separate topic/patch.
--paulr

From: David Blaikie [mailto:dblaikie@gmail.com]
Sent: Tuesday, September 08, 2015 7:36 PM
To: reviews+D12624+public+25876849b7c59a9f@reviews.llvm.org; Richard Smith
Cc: Romanova, Katya; Eric Christopher; Robinson, Paul; Adrian Prantl; cfe-commits
Subject: Re: [PATCH] D12624: Top-level anonymous namespaces are missing import DW_TAG_imported_module and nested anonymous namespaces are not

kromanova updated this revision to Diff 42364.Dec 9 2015, 5:40 PM
kromanova updated this object.
kromanova edited edge metadata.
kromanova set the repository for this revision to rL LLVM.

I have made all the changes that Richard suggested. Sorry for the delay, got distracted by other tasks.
Anything else I need to change?

rsmith accepted this revision.Dec 9 2015, 6:27 PM
rsmith edited edge metadata.

This looks good to me.

Once we have this in place we can think about factoring the debug-specific flags out of CodeGenOpts into some kind of DebugInfoOpts, to be configured by whatever debugger tuning mechanism we end up with.

This revision is now accepted and ready to land.Dec 9 2015, 6:27 PM

Once we have this in place we can think about factoring the debug-specific flags out of CodeGenOpts into some kind of DebugInfoOpts, to be configured by whatever debugger tuning mechanism we end up with.

Good idea!
Thank you for such prompt review.
Katya.

This revision was automatically updated to reflect the committed changes.