So we ran into a problem where we had anonymous structs in modules. They have no name, so we had no way to say "module A, please give me a struct named... nothing in the namespace 'foo'". Obviously this doesn't work, so we always try to make sure a typedef doesn't come from a module first, by asking us to get the typedef from the DWO file:
type_sp = ParseTypeFromDWO(die, log); If this fails, it just means we have the typedef in hand. If I compile your example I end up with: 0x0000000b: TAG_compile_unit [1] * AT_producer( "Apple LLVM version 8.0.0 (clang-800.0.5.3)" ) AT_language( DW_LANG_C99 ) AT_name( "main.c" ) AT_stmt_list( 0x00000000 ) AT_comp_dir( "/tmp" ) AT_low_pc( 0x0000000100000f60 ) AT_high_pc( 0x0000000100000fb0 ) 0x0000002e: TAG_subprogram [2] * AT_low_pc( 0x0000000100000f60 ) AT_high_pc( 0x0000000100000f85 ) AT_frame_base( rbp ) AT_name( "myfunc" ) AT_decl_file( "/private/tmp/main.c" ) AT_decl_line( 6 ) AT_prototyped( 0x01 ) AT_external( 0x01 ) 0x00000049: TAG_formal_parameter [3] AT_location( fbreg -8 ) AT_name( "s" ) AT_decl_file( "/private/tmp/main.c" ) AT_decl_line( 6 ) AT_type( {0x0000008c} ( my_untagged_struct* ) ) 0x00000057: NULL 0x00000058: TAG_subprogram [4] * AT_low_pc( 0x0000000100000f90 ) AT_high_pc( 0x0000000100000fb0 ) AT_frame_base( rbp ) AT_name( "main" ) AT_decl_file( "/private/tmp/main.c" ) AT_decl_line( 12 ) AT_type( {0x00000085} ( int ) ) AT_external( 0x01 ) 0x00000076: TAG_variable [5] AT_location( fbreg -16 ) AT_name( "s" ) AT_decl_file( "/private/tmp/main.c" ) AT_decl_line( 14 ) AT_type( {0x00000091} ( my_untagged_struct ) ) 0x00000084: NULL 0x00000085: TAG_base_type [6] AT_name( "int" ) AT_encoding( DW_ATE_signed ) AT_byte_size( 0x04 ) 0x0000008c: TAG_pointer_type [7] AT_type( {0x00000091} ( my_untagged_struct ) ) 0x00000091: TAG_typedef [8] AT_type( {0x0000009c} ( struct ) ) AT_name( "my_untagged_struct" ) AT_decl_file( "/private/tmp/main.c" ) AT_decl_line( 4 ) 0x0000009c: TAG_structure_type [9] * AT_byte_size( 0x08 ) AT_decl_file( "/private/tmp/main.c" ) AT_decl_line( 1 ) 0x000000a0: TAG_member [10] AT_name( "i" ) AT_type( {0x00000085} ( int ) ) AT_decl_file( "/private/tmp/main.c" ) AT_decl_line( 2 ) AT_data_member_location( +0 ) 0x000000ae: TAG_member [10] AT_name( "f" ) AT_type( {0x000000bd} ( float ) ) AT_decl_file( "/private/tmp/main.c" ) AT_decl_line( 3 ) AT_data_member_location( +4 ) 0x000000bc: NULL 0x000000bd: TAG_base_type [6] AT_name( "float" ) AT_encoding( DW_ATE_float ) AT_byte_size( 0x04 ) 0x000000c4: NULL Note that the typedef is at 0x00000091, and it is a typedef to 0x0000009c. Also note that the DWARF DIE at 0x0000009c is a complete definition as it has children describing its members and 0x0000009c doesn't have a DW_AT_declaration(1) attribute. Is this how your DWARF looks for your stuff? The DWARF you had looked like: 0x0000005c: DW_TAG_typedef [6] DW_AT_name( "my_untagged_struct" ) DW_AT_decl_file("/home/luke/main.cpp") DW_AT_decl_line(4) DW_AT_type({0x0000002d}) What did the type at 0x0000002d look like? Similar to 0x0000009c in my DWARF I presume? The DWARFASTParserClang class is responsible for making up a clang type in the clang::ASTContext for this typedef. What will happen in the code where the flow falls through is the we will make a lldb_private::Type that says "I am a typedef to type whose user ID is 0x0000002d (in your example)". A NULL pointer should not be returned from the DWARFASTParserClang::ParseTypeFromDWARF() function. If it is, please step through and figure out why. I compiled your example and did the following: % lldb a.out (lldb) b main (lldb) r Process 89808 launched: '/private/tmp/a.out' (x86_64) Process 89808 stopped * thread #1: tid = 0xf7473, 0x0000000100000fa3 a.out main + 19, stop reason = breakpoint 1.1, queue = com.apple.main-thread frame #0: 0x0000000100000fa3 a.out main + 19 at main.c:15 12 int main() 13 { 14 my_untagged_struct s; -> 15 myfunc(&s); 16 return 0; 17 } (lldb) p myfunc(&s) (lldb) So I was able to call this function. Are you not able to call it? Likewise if I step into this function I can see the variable: (lldb) s (lldb) fr var s (my_untagged_struct *) s = 0x00007fff5fbff8d0 (lldb) fr var *s (my_untagged_struct) *s = (i = 0, f = 3.1400001) So to sum up: when we parse the DW_TAG_typedef in DWARFASTParserClang::ParseTypeFromDWARF(), we should return a valid TypeSP that contains a valid pointer. If that isn't happening, that is a bug. Feel free to send me the example binary and I can figure things out if you have any trouble. I wrote all of this code so I am quite familiar with it. Greg Clayton > On Mar 9, 2016, at 3:54 PM, luke Drummond via lldb-dev > <lldb-dev@lists.llvm.org> wrote: > > 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}) > > _______________________________________________ > lldb-dev mailing list > lldb-dev@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev _______________________________________________ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev