[lldb-dev] DWARFASTParserClang and DW_TAG_typedef for anonymous structs

luke Drummond via lldb-dev lldb-dev at lists.llvm.org
Wed Mar 9 15:54:41 PST 2016


Hi All

I'm hoping that someone might be able to give me some direction
regarding `Type` resolution from DWARF informationfor functions taking
anonymous structs hidden behind a typedef

e.g.

```
typedef struct {
    int i;
    float f;
} my_untagged_struct;

void __attribute__((noinline)) myfunc(my_untagged_struct *s)
{
    s->i = 0;
    s->f = 3.14f;
}

int main()
{
    my_untagged_struct s;
    myfunc(&s);
    return 0;
}

```

I [recently reported a
bug](https://llvm.org/bugs/show_bug.cgi?id=26790) relating to the
clang expression evaluator no longer being able to resolve calls to
functions with arguments to typedefed anonymous structs, after a cleanup
to the expression parsing code.
I was perfectly wrong in my assumptions about the cause of the bug, and
after some more digging, I think I've tracked it down to a section of
code in `DWARFASTParserClang::ParseTypeFromDWARF`.


(DWARFASTParserClang::ParseTypeFromDwarf:254)
```
switch (tag)
{
    case DW_TAG_typedef:
        // Try to parse a typedef from the DWO file first as modules
        // can contain typedef'ed structures that have no names like:
        //
        //  typedef struct { int a; } Foo;
        //
        // In this case we will have a structure with no name and a
        // typedef named "Foo" that points to this unnamed structure.
        // The name in the typedef is the only identifier for the
struct, // so always try to get typedefs from DWO files if possible.
        //
        // The type_sp returned will be empty if the typedef doesn't
exist // in a DWO file, so it is cheap to call this function just to
check. //
        // If we don't do this we end up creating a TypeSP that says
this // is a typedef to type 0x123 (the DW_AT_type value would be 0x123
        // in the DW_TAG_typedef), and this is the unnamed structure
type. // We will have a hard time tracking down an unnammed structure
        // type in the module DWO file, so we make sure we don't get
into // this situation by always resolving typedefs from the DWO file.
        type_sp = ParseTypeFromDWO(die, log);
        if (type_sp)
            return type_sp;
    LLVM_FALLTHROUGH
```

In my case, the type information for the typedef is included within the
main executable's DWARF rather than an external .dwo file (snippet from
the DWARF included the end of this message), and therefore the `case`
for `DW_TAG_typedef` falls through as `ParseTypeFromDWO` returns a NULL
value.


As this is code I'm not familiar with, I'd appreciate if any one on the
list was able to give some guidance as to the best way to resolve this
issue, so that `ClangExpressionDeclMap::FindExternalVisibleDecls` can
correctly resolve calls to functions taking typedef names to anonymous
structs. I'm happy to take a whack at implementing this feature, but
I'm a bit stuck as to how to resolve this type given the current DIE
object.

Any help or guidance on where to start with this would be really
helpful.

All the best

Luke




--------
This is a snippet from the output of llvm-dwarfdump on the above code
example.

`g++ -g main.cpp && llvm-dwarfdump a.out | grep DW_TAG_typedef -A 35`
--------

0x0000005c:   DW_TAG_typedef [6]  
                DW_AT_name [DW_FORM_strp]
( .debug_str[0x00000069] = "my_untagged_struct") DW_AT_decl_file
[DW_FORM_data1]	("/home/luke/main.cpp") DW_AT_decl_line
[DW_FORM_data1]	(4) DW_AT_type [DW_FORM_ref4]	(cu +
0x002d => {0x0000002d})

0x00000067:   DW_TAG_subprogram [7] *
                DW_AT_external [DW_FORM_flag_present]	(true)
                DW_AT_name [DW_FORM_strp]
( .debug_str[0x00000006] = "myfunc") DW_AT_decl_file
[DW_FORM_data1]	("/home/luke/main.cpp") DW_AT_decl_line
[DW_FORM_data1]	(6) DW_AT_linkage_name [DW_FORM_strp]
( .debug_str[0x0000005d] = "_Z6myfuncP18my_untagged_struct")
DW_AT_low_pc [DW_FORM_addr]	(0x0000000000400566) DW_AT_high_pc
[DW_FORM_data8]	(0x0000000000000026) DW_AT_frame_base
[DW_FORM_exprloc]	(<0x1> 9c ) DW_AT_Unknown_2117
[DW_FORM_flag_present]	(true) DW_AT_sibling
[DW_FORM_ref4]	(cu + 0x0095 => {0x00000095})

0x00000088:     DW_TAG_formal_parameter [8]  
                  DW_AT_name [DW_FORM_string]	("s")
                  DW_AT_decl_file [DW_FORM_data1]
("/home/luke/main.cpp") DW_AT_decl_line [DW_FORM_data1]	(6)
                  DW_AT_type [DW_FORM_ref4]	(cu + 0x0095 =>
{0x00000095}) DW_AT_location [DW_FORM_exprloc]	(<0x2> 91 68 )

0x00000094:     NULL

0x00000095:   DW_TAG_pointer_type [9]  
                DW_AT_byte_size [DW_FORM_data1]	(0x08)
                DW_AT_type [DW_FORM_ref4]	(cu + 0x005c =>
{0x0000005c})



More information about the lldb-dev mailing list