On Thu, Mar 09, 2017 at 10:24:43AM +0100, Jakub Jelinek wrote: > Hi! > > Similarly to https://gcc.gnu.org/ml/gcc-patches/2009-09/msg01161.html > the C FE gets wrong the location of DW_TAG_enumeral_type if there is a > forward declaration. If we e.g. have a variable that is first declared > extern and then defined, we emit DW_TAG_variable with the location of the > first declaration and then another DW_TAG_variable with DW_AT_specification > pointing to the previous one for the definition, with locus of the > definition. That is not what we do for enums, there is just one DIE, so we > should use the more descriptive from the locations, which is the definition. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > 2017-03-09 Jakub Jelinek <ja...@redhat.com> > > PR c/79969 > * c-decl.c (start_enum): Adjust DECL_SOURCE_LOCATION of > TYPE_STUB_DECL.
How about doing this in finish_enum, similarly to finish_struct? You'd need to pass a location from the parser, but that's easy: diff --git gcc/c/c-decl.c gcc/c/c-decl.c index 645304a..5df41dd 100644 --- gcc/c/c-decl.c +++ gcc/c/c-decl.c @@ -8246,7 +8246,7 @@ start_enum (location_t loc, struct c_enum_contents *the_enum, tree name) Returns ENUMTYPE. */ tree -finish_enum (tree enumtype, tree values, tree attributes) +finish_enum (location_t loc, tree enumtype, tree values, tree attributes) { tree pair, tem; tree minnode = 0, maxnode = 0; @@ -8382,6 +8382,11 @@ finish_enum (tree enumtype, tree values, tree attributes) TYPE_LANG_SPECIFIC (tem) = TYPE_LANG_SPECIFIC (enumtype); } + /* Update type location to the one of the definition, instead of e.g. + a forward declaration. */ + if (TYPE_STUB_DECL (enumtype)) + DECL_SOURCE_LOCATION (TYPE_STUB_DECL (enumtype)) = loc; + /* Finish debugging output for this type. */ rest_of_type_compilation (enumtype, toplevel); diff --git gcc/c/c-parser.c gcc/c/c-parser.c index 8330e65..2d9c0d3 100644 --- gcc/c/c-parser.c +++ gcc/c/c-parser.c @@ -2779,7 +2779,7 @@ c_parser_enum_specifier (c_parser *parser) } } postfix_attrs = c_parser_attributes (parser); - ret.spec = finish_enum (type, nreverse (values), + ret.spec = finish_enum (enum_loc, type, nreverse (values), chainon (attrs, postfix_attrs)); ret.kind = ctsk_tagdef; ret.expr = NULL_TREE; diff --git gcc/c/c-tree.h gcc/c/c-tree.h index 13e40e6..3800256 100644 --- gcc/c/c-tree.h +++ gcc/c/c-tree.h @@ -534,7 +534,7 @@ extern void c_release_switch_bindings (struct c_spot_bindings *); extern bool c_check_switch_jump_warnings (struct c_spot_bindings *, location_t, location_t); extern void finish_decl (tree, location_t, tree, tree, tree); -extern tree finish_enum (tree, tree, tree); +extern tree finish_enum (location_t, tree, tree, tree); extern void finish_function (void); extern tree finish_struct (location_t, tree, tree, tree, struct c_struct_parse_info *); Marek