Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang][DebugInfo] Emit global variable definitions for static data members with constant initializers #70551

Closed

Conversation

Michael137
Copy link
Member

When an LLDB user asks for the value of a static data member, LLDB starts by
searching the Names accelerator table for the corresponding variable definition
DIE. For static data members with out-of-class definitions that works fine,
because those get represented as global variables with a location and making them
eligible to be added to the Names table. However, in-class definitions won’t get
indexed because we usually don't emit global variables for them. So in DWARF
we end up with a single DW_TAG_member that usually holds the constant initializer.
But we don't get a corresponding CU-level DW_TAG_variable like we do for
out-of-class definitions.

To make it more convenient for debuggers to get to the value of inline static data members,
this patch makes sure we emit definitions for static variables with constant initializers
the same way we do for other static variables. This also aligns Clang closer to GCC, which
produces CU-level definitions for inline statics and also emits these into .debug_pubnames.

The implementation keeps track of newly created static data members. Then in
CGDebugInfo::finalize, we emit a global DW_TAG_variable with a DW_AT_const_value for
any of those declarations that didn't end up with a definition in the DeclCache.

The newly emitted DW_TAG_variable will look as follows:

0x0000007b:   DW_TAG_structure_type
                DW_AT_calling_convention        (DW_CC_pass_by_value)
                DW_AT_name      ("Foo")
                ...

0x0000008d:     DW_TAG_member
                  DW_AT_name    ("i")
                  DW_AT_type    (0x00000062 "const int")
                  DW_AT_external        (true)
                  DW_AT_declaration     (true)
                  DW_AT_const_value     (4)

Newly added
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

0x0000009a:   DW_TAG_variable
                DW_AT_specification     (0x0000008d "i")
                DW_AT_const_value       (4)
                DW_AT_linkage_name      ("_ZN2t2IiE1iIfEE")

This patch factors out the code to create a DIExpression from
an APValue into a separate helper function.

This will be useful in a follow-up patch where we re-use this
logic elsewhere.
…embers with constant initializers

When an LLDB user asks for the value of a static data member, LLDB starts by
searching the Names accelerator table for the corresponding variable definition
DIE. For static data members with out-of-class definitions that works fine,
because those get represented as global variables with a location and making them
eligible to be added to the Names table. However, in-class definitions won’t get
indexed because we usually don't emit global variables for them. So in DWARF
we end up with a single `DW_TAG_member` that usually holds the constant initializer.
But we don't get a corresponding CU-level `DW_TAG_variable` like we do for
out-of-class definitions.

To make it more convenient for debuggers to get to the value of inline static data members,
this patch makes sure we emit definitions for static variables with constant initializers
the same way we do for other static variables. This also aligns Clang closer to GCC, which
produces CU-level definitions for inline statics and also emits these into `.debug_pubnames`.

The implementation keeps track of newly created static data members. Then in
`CGDebugInfo::finalize`, we emit a global `DW_TAG_variable` with a `DW_AT_const_value` for
any of those declarations that didn't end up with a definition in the `DeclCache`.

The newly emitted `DW_TAG_variable` will look as follows:
```
0x0000007b:   DW_TAG_structure_type
                DW_AT_calling_convention        (DW_CC_pass_by_value)
                DW_AT_name      ("Foo")
                ...

0x0000008d:     DW_TAG_member
                  DW_AT_name    ("i")
                  DW_AT_type    (0x00000062 "const int")
                  DW_AT_external        (true)
                  DW_AT_declaration     (true)
                  DW_AT_const_value     (4)

Newly added
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

0x0000009a:   DW_TAG_variable
                DW_AT_specification     (0x0000008d "i")
                DW_AT_const_value       (4)
                DW_AT_linkage_name      ("_ZN2t2IiE1iIfEE")
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant