llvm is missing support for DW_OP_implicit_value operation.
DW_OP_implicit_value op is indispensable for cases such as
optimized out long double variables.
For intro refer: DWARFv5 Spec Pg: 40 2.6.1.1.4 Implicit Location Descriptions
Consider the following example:
int main() { long double ld = 3.14; printf("dummy\n"); ld *= ld; return 0; }
when compiled with tunk clang as
clang test.c -g -O1 produces following location description
of variable ld:
DW_AT_location (0x00000000: [0x0000000000201691, 0x000000000020169b): DW_OP_constu 0xc8f5c28f5c28f800, DW_OP_stack_value, DW_OP_piece 0x8, DW_OP_constu 0x4000, DW_OP_stack_value, DW_OP_bit_piece 0x10 0x40, DW_OP_stack_value) DW_AT_name ("ld")
Here one may notice that this representation is incorrect(DWARF4
stack could only hold integers(and only up to the size of address)).
Here the variable size itself is 128 bit.
GDB and LLDB confirms this:
(gdb) p ld $1 = <invalid float value> (lldb) frame variable ld (long double) ld = <extracting data from value failed>
GCC represents/uses DW_OP_implicit_value in these sort of situations.
Based on the discussion with Jakub Jelinek regarding GCC's motivation
for using this, I concluded that DW_OP_implicit_value is most appropriate
in this case.
Link: https://gcc.gnu.org/pipermail/gcc/2020-July/233057.html
GDB seems happy after this patch:(LLDB doesn't have support
for DW_OP_implicit_value)
(gdb) p ld p ld $1 = 3.14000000000000012434
This restriction seems overly strict and also partially wrong.
First off, the condition should be sunk into DwarfExpression. That's were we do the low-level DWARF expression encoding. Maybe we should add a DwarfExpression::addFPConstant(APFloat) function?
An then in the new function, since we cannot represent anything > 64 bit without DW_OP_implicit_value, we should error out if it's not supported, and not emit a broken constant like we did before.