https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120571
Bug ID: 120571 Summary: emit DWARF type declarations for incomplete types in headers Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: debug Assignee: unassigned at gcc dot gnu.org Reporter: woodard at redhat dot com Target Milestone: --- Consider: impl.h: struct Point; int dist(struct Point p1, struct Point p2); struct Point mid(struct Point p1, struct Point p2); extern struct Point ORIGIN; and v1.c: #include "impl.h" struct Point { int x, y; }; struct Point ORIGIN = (struct Point){0, 0}; int dist(struct Point p1, struct Point p2) { return 0; } struct Point mid(struct Point p1, struct Point p2) { return ORIGIN; } Currently the DWARF sets the declaration coordinates to the definition rather than the original declaration found in the header file. <1><2e>: Abbrev Number: 4 (DW_TAG_structure_type) <2f> DW_AT_name : (indirect string, offset: 0x79): Point <33> DW_AT_byte_size : 8 <34> DW_AT_decl_file : 1 <35> DW_AT_decl_line : 3 <36> DW_AT_decl_column : 8 We would also like to have gcc emit DWARF fir the incomplete declaration found in the header file which we think would look something like this with the DW_AT_declaration flag set: <1><2e>: Abbrev Number: 4 (DW_TAG_structure_type) <2f> DW_AT_name : (indirect string, offset: 0x79): Point <34> DW_AT_decl_file : 2 <35> DW_AT_decl_line : 1 <36> DW_AT_decl_column : 12 <XX> DW_AT_declaration : 1 Of course this would not include the data members because they would not have been defined yet. I think at some point long ago GCC did emit these but it was removed as a response to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54508 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55059 However, we have a good use case where the information would be necessary: We would like to be able to do something like: $ abidiff --header-file1 test/include/public-api.h /usr/lib64/libproject.so test/lib/libproject.so When the user specifies a header file with --header-file1 then the types, variables and functions which are not explicitly declared in the specified header files are suppressed by default because they are implementation details. While only the types, varibles and functions originally declared in a public header are considered for ABI analysis. Currently, this cannot be done because the DWARF only points to the definition of the type not the original incomplete declaration of the type. So there is no way to identify from the existing DWARF if the file was originally declared in the header file. The problem is, the DWARF currently only points to the definition which is in the C files, it doesn't enumerate the incomplete declarations in the header files. If we had both the location of the incomplete declaration in the header and the definition in the C file then ABI analysis tools such as libabigail could automatically tell which functions, varibles and types are part of the library's public API simply by virtue of the header it is in. This would greatly simplify the process of verifying that the ABI of libraries are not changing over time. The current workaround is very cumbersome, a bespoke libabigail suppression file must be created and maintained for each library which is part of our collection of software. The mainual effort required to do this makes that workaround unfeasible at a large scale. To minimize the volume of additional DWARF being generated It is perfectly acceptable to have this behavior only happen when requested with something like: -gincomplete-types or have it rolled up when there extra debug information is generated with an option like -g3. This should also help minimize the impact on other tools which might have trouble dealing with the DWARF having both an incomplete type for the declaration marked with DW_AT_declaration and a full type definition. Tools which only need the full type definition can be taught to ignore functions, variables, and types which include DW_AT_declaration and to assist them in finding the full type definition DW_AT_sibling can be emitted in the incomplete declaration to point them from the incomplete type to the full type definition.