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

Reply via email to