On 10/23/2015 02:41 PM, David Malcolm wrote:
As in the previous version of this patch
  "Implement tree expression tracking in C FE (v2)"
the patch now captures ranges for all C expressions during parsing within
a new field of c_expr, and for all tree nodes with a location_t, it stores
them in ad-hoc locations for later use.

Hence compound expressions get ranges; see:
   
https://dmalcolm.fedorapeople.org/gcc/2015-09-22/diagnostic-test-expressions-1.html

and for this example:

   int test (int foo)
   {
     return foo * 100;
            ^^^   ^^^
   }

we have access to the ranges of "foo" and "100" during C parsing via
the c_expr, but once we have GENERIC, all we have is a VAR_DECL and an
INTEGER_CST (the former's location is in at the top of the
function, and the latter has no location).

gcc/ChangeLog:
        * Makefile.in (OBJS): Add gcc-rich-location.o.
        * gcc-rich-location.c: New file.
        * gcc-rich-location.h: New file.
        * print-tree.c (print_node): Print any source range information.
        * tree.c (set_source_range): New functions.
        * tree.h (CAN_HAVE_RANGE_P): New.
        (EXPR_LOCATION_RANGE): New.
        (EXPR_HAS_RANGE): New.
        (get_expr_source_range): New inline function.
        (DECL_LOCATION_RANGE): New.
        (set_source_range): New decls.
        (get_decl_source_range): New inline function.

gcc/c-family/ChangeLog:
        * c-common.c (c_fully_fold_internal): Capture existing souce_range,
        and store it on the result.

gcc/c/ChangeLog:
        * c-parser.c (set_c_expr_source_range): New functions.
        (c_token::get_range): New method.
        (c_token::get_finish): New method.
        (c_parser_expr_no_commas): Call set_c_expr_source_range on the ret
        based on the range from the start of the LHS to the end of the
        RHS.
        (c_parser_conditional_expression): Likewise, based on the range
        from the start of the cond.value to the end of exp2.value.
        (c_parser_binary_expression): Call set_c_expr_source_range on
        the stack values for TRUTH_ANDIF_EXPR and TRUTH_ORIF_EXPR.
        (c_parser_cast_expression): Call set_c_expr_source_range on ret
        based on the cast_loc through to the end of the expr.
        (c_parser_unary_expression): Likewise, based on the
        op_loc through to the end of op.
        (c_parser_sizeof_expression) Likewise, based on the start of the
        sizeof token through to either the closing paren or the end of
        expr.
        (c_parser_postfix_expression): Likewise, using the token range,
        or from the open paren through to the close paren for
        parenthesized expressions.
        (c_parser_postfix_expression_after_primary): Likewise, for
        various kinds of expression.
        * c-tree.h (struct c_expr): Add field "src_range".
        (c_expr::get_start): New method.
        (c_expr::get_finish): New method.
        (set_c_expr_source_range): New decls.
        * c-typeck.c (parser_build_unary_op): Call set_c_expr_source_range
        on ret for prefix unary ops.
        (parser_build_binary_op): Likewise, running from the start of
        arg1.value through to the end of arg2.value.

gcc/testsuite/ChangeLog:
        * gcc.dg/plugin/diagnostic-test-expressions-1.c: New file.
        * gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c:
        New file.
        * gcc.dg/plugin/plugin.exp (plugin_test_list): Add
        diagnostic_plugin_test_tree_expression_range.c and
        diagnostic-test-expressions-1.c.

  /* Initialization routine for this file.  */

@@ -6085,6 +6112,9 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr 
*after,
    ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
                                 code, exp_location, rhs.value,
                                 rhs.original_type);
+  set_c_expr_source_range (&ret,
+                          lhs.get_start (),
+                          rhs.get_finish ());
One line if it fits.


@@ -6198,6 +6232,9 @@ c_parser_conditional_expression (c_parser *parser, struct 
c_expr *after,
                           ? t1
                           : NULL);
      }
+  set_c_expr_source_range (&ret,
+                          start,
+                          exp2.get_finish ());
Here too.

@@ -6522,6 +6564,10 @@ c_parser_cast_expression (c_parser *parser, struct 
c_expr *after)
        expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
        }
        ret.value = c_cast_expr (cast_loc, type_name, expr.value);
+      if (ret.value && expr.value)
+       set_c_expr_source_range (&ret,
+                                cast_loc,
+                                expr.get_finish ());
And here?

With the nits fixed, this is OK.

I think that covers this iteration of the rich location work and that you'll continue working with Jason on extending this into the C++ front-end.

jeff

Reply via email to