This is an archive of the discontinued LLVM Phabricator instance.

CodeView - add static data members to global variable debug info.
ClosedPublic

Authored by akhuang on May 20 2019, 5:20 PM.

Diff Detail

Repository
rL LLVM

Event Timeline

akhuang created this revision.May 20 2019, 5:20 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptMay 20 2019, 5:20 PM
rnk added a comment.May 21 2019, 1:20 PM

This needs a clang-side test to show that clang generates the expected IR for static data members.

akhuang marked an inline comment as done.May 21 2019, 3:49 PM
akhuang added a subscriber: dblaikie.
akhuang added inline comments.
clang/lib/CodeGen/CGDebugInfo.cpp
4385 ↗(On Diff #200378)

@dblaikie I'm using the global scope here because if the class type is used as the scope it runs into the assert message Context of a global variable should not be a type with identifier. Is there a reason for the assert?

dblaikie added inline comments.May 22 2019, 3:16 PM
clang/lib/CodeGen/CGDebugInfo.cpp
4385 ↗(On Diff #200378)

I think it's generally how LLVM handles definitions for the most part - putting them at the global scope.

Though I'm confused by this patch - it has a source change in clang, but a test in LLVM. Generally there should be testing to cover where the source change is, I think?

akhuang updated this revision to Diff 201004.May 23 2019, 10:00 AM

Add llvm IR test.

akhuang marked an inline comment as done.May 23 2019, 10:09 AM
akhuang added inline comments.
clang/lib/CodeGen/CGDebugInfo.cpp
4385 ↗(On Diff #200378)

yep, there should be a test for this - added now.

akhuang marked an inline comment as done.May 24 2019, 3:29 PM
akhuang added inline comments.
clang/lib/CodeGen/CGDebugInfo.cpp
4385 ↗(On Diff #200378)

So for the global scope, it seems like elsewhere, when creating the debug info for a static data member global variable, the scope is set to be the global scope. But it would be helpful for codeview debug info if the scope remained as the class type, partially so we can use the class type information in the variable name that we emit.

Does it seem reasonable to remove the assert for global variable scope so that the scope can be the class here?

rnk added inline comments.
clang/lib/CodeGen/CGDebugInfo.cpp
4385 ↗(On Diff #200378)

I think the assertion in question is this one here in DIBuilder:
https://github.com/llvm/llvm-project/blob/master/llvm/lib/IR/DIBuilder.cpp#L634

It looks like @manmanren added this in 2014:
https://github.com/llvm/llvm-project/commit/bfd2b829d912ecd89f73ae32d4c683856dd677a3

@dblaikie do you know if this check is still necessary? It seems like the DWARF clang generages today corresponds to C++ written this way:

struct Foo { static const int Test2; };
const int Foo::Test2 = 4;

When oftentimes the source looks more like this:

struct Foo { static const int Test2 = 4; };

I saw a conversation between you and @probinson fixing clang irgen to avoid this assert sometime back, so I figured you might be a good point of reference.

Is this the change we were discussing the other week semi-related to preserved enums? It sounded to me like the conclusion was somewhat to go ahead without adding all these things to the constant list and see how it goes? Is this case different from the enum case in some way?

clang/lib/CodeGen/CGDebugInfo.cpp
4385 ↗(On Diff #200378)

My expectation is that this characterization is probably a pragmatic one of "it's what GCC does/we're not sure if GDB could cope with it otherwise" (we don't always adhere strictly to what GCC does - for instance GCC always puts function definitions at the CU scope, and if the function was defined in a namespace it puts a declaration in the namespace and references that from the global scoped definition - Clang goes the other way and puts the definition in the namespace scope (even if the function was declared there but defined from outside the namespace))

If that's the case (worth testing) then arguably the frontend should emit the more accurate metadata and the DWARF backend could fudge this - or like some of the other stuff we do we could emit different metadata in the frontend depending on the DWARF v CodeView split.

On further experimentation, I'm somewhat confused what this change is about. In ToT, this code:

struct foo {
  static const int bar = 3;
};
int f() {
  return foo::bar;
}

Becomes DWARF that has a DICompositeType with elements pointing to a DIDerivedType:DW_TAG_member with the extraData of i32 3.

And that becomes this DWARF:

TAG_structure_type
  AT_name "foo"
  TAG_member
    AT_name "foo"
    declaration true
    const_value 3

which seems accurate to me - this isn't a variable definition, it's a declaration with a value.

akhuang updated this revision to Diff 202027.May 29 2019, 12:57 PM

Append class name to static data member debug info name.

rnk accepted this revision.May 29 2019, 2:38 PM

lgtm!

This revision is now accepted and ready to land.May 29 2019, 2:38 PM
This revision was automatically updated to reflect the committed changes.