Re: [RFC/PATCH] Fix-it hints

2014-09-27 Thread Manuel López-Ibáñez
On 25 September 2014 11:34, Dodji Seketeli  wrote:
>> When the caret line is disabled with -fno-diagnostics-show-caret, the
>> fix-it hint is printed as:
>>
>> gcc/testsuite/g++.dg/template/crash83.C:5:21: error: an explicit
>> specialization must be preceded by 'template <>'
>> gcc/testsuite/g++.dg/template/crash83.C:5:21: fixit: template<>
>>
>> The latter form may allow an IDE (such as emacs) to automatically
>> apply the fix.
>
> Nice.  Is the "fixit:" prefix used by other compilers too?  Or are there
> variations from compiler to compiler?

Clang seems to do:

fix-it:"t.cpp":{7:25-7:29}:"Gamma"

http://clang.llvm.org/docs/UsersManual.html#cmdoption-fdiagnostics-parseable-fixits

where the location is a half-open range (insertions are marked as
{7:25-7:25}). However, this is not the standard GNU format for ranges,
and last time I tried to update that (to support multiple ranges) RMS
was not in favour of adding the Clang flavour. Quoting the filename
also does not seem to be what GNU mandates. No idea why they use {}
around the location range and not sure if they support just 7:25,
which seems nicer.

Also, I don't know who are the consumers of Clang's format that GCC
will be interested in supporting.

No idea about other compilers that support fix-it hints.

Comments?


>
>> Currently, fix-it hints are limited to insertions at one single
>> location, whereas Clang allows insertions, deletions, and replacements
>> at arbitrary location ranges.
>
> Do you have example of each of these kinds of fix-it hints? (deletions,
> replacement at location ranges).  I think it'd be nice to have an idea
> of what needs to be done, even if we are not doing it "in extenso" right
> now.

I think in the case of deletions, they just underline the text to be deleted:

typename3.C:3:7: warning: duplicate 'const' declaration specifier
[-Wduplicate-decl-specifier]
const const long long long int x;
  ^~
fix-it:"typename3.C":{3:7-3:13}:""

In the case of replacements, there does not seem to be any visible
difference with an insertion:

typename3.C:4:33: note: change this ',' to a ';' to call 'f'
const const long long long int x,
^
;
fix-it:"typename3.C":{4:33-4:34}:";"

Cheers,

Manuel.


Re: [RFC/PATCH] Fix-it hints

2014-09-25 Thread Dodji Seketeli
Hello Manuel,

Sorry for taking so long to reply to this.

FWIW, I like the direction of this.  I find fix-it hints cool in
general.  So thank you for working on this.

Manuel López-Ibáñez  a écrit:

> This patch implements fix-it hints. See https://gcc.gnu.org/PR62314
>
> When the caret line is active (which is the default), this adds an
> additional source-line indicating how to fix the code:
>
> gcc/testsuite/g++.dg/template/crash83.C:5:21: error: an explicit
> specialization must be preceded by 'template <>'
>  template: > struct B {}; // { dg-error
> "explicit specialization|expected" }
>  ^
>  template<>

It looks like your mail user agent wrapped a line above, making it hard
to read.  I suspect it should have been:

  template > struct B {}; // { dg-error "explicit 
specialization|expected" }
  ^
  template<>

> When the caret line is disabled with -fno-diagnostics-show-caret, the
> fix-it hint is printed as:
>
> gcc/testsuite/g++.dg/template/crash83.C:5:21: error: an explicit
> specialization must be preceded by 'template <>'
> gcc/testsuite/g++.dg/template/crash83.C:5:21: fixit: template<>
>
> The latter form may allow an IDE (such as emacs) to automatically
> apply the fix.

Nice.  Is the "fixit:" prefix used by other compilers too?  Or are there
variations from compiler to compiler?

> Currently, fix-it hints are limited to insertions at one single
> location, whereas Clang allows insertions, deletions, and replacements
> at arbitrary location ranges.

Do you have example of each of these kinds of fix-it hints? (deletions,
replacement at location ranges).  I think it'd be nice to have an idea
of what needs to be done, even if we are not doing it "in extenso" right
now.

> Opinions? Is the proposed interface/implementation acceptable?

Please read my comments below.

> Any other diagnostics that could use a fix-it hint? In principle, we
> should only give them when we are sure that the proposed fix will fix
> the error or silence a warning.  For example, the C++ parser often
> says 'x' expected before 'y' but adding x before y rarely fixes
> anything.

I am thinking that maybe the diagnostic about the missing ";" after a
struct/class declaration might be a candidate for this fix-it hint
feature.

It's emitted by cp_parser_class_specifier_1() at:

if (CLASSTYPE_DECLARED_CLASS (type))
  error_at (loc, "expected %<;%> after class definition");
else if (TREE_CODE (type) == RECORD_TYPE)
  error_at (loc, "expected %<;%> after struct definition");
else if (TREE_CODE (type) == UNION_TYPE)
  error_at (loc, "expected %<;%> after union definition");
else
  gcc_unreachable ();


[...]

> +
> +static int
> +adjust_column (int line_width, int max_width, int column)

Missing comments for this function.

[...]

> +static const char *
> +get_source_line_and_column (location_t loc, int *line_width, int *column)
> +{

Likewise.

[...]


>  /* Print the physical source line corresponding to the location of
> this diagnostic, and a caret indicating the precise column.  */
>  void
>  diagnostic_show_locus (diagnostic_context * context,
>  const diagnostic_info *diagnostic)
>  {

[...]

>context->last_location = diagnostic->location;
> -  s = expand_location_to_spelling_point (diagnostic->location);
> -  line = location_get_source_line (s, &line_width);
> -  if (line == NULL || s.column > line_width)
> +  line = get_source_line_and_column (diagnostic->location,
> +  &line_width, &column);
> +  if (line == NULL)
>  return;
>  
>max_width = context->caret_max_width;
> -  line = adjust_line (line, line_width, max_width, &(s.column));
> +  line = adjust_line (line, line_width, max_width, &column);

Apparently, each time we call get_source_line_and_column, we also call
adjust_line on it.  So maybe we want to have a
get_adjusted_source_line_and_column (or something like that) that does
it all?

[...]

> @@ -325,13 +345,13 @@ diagnostic_show_locus (diagnostic_contex
>pp_newline (context->printer);
>caret_cs = colorize_start (pp_show_color (context->printer), "caret");
>caret_ce = colorize_stop (pp_show_color (context->printer));
>  
>/* pp_printf does not implement %*c.  */
> -  size_t len = s.column + 3 + strlen (caret_cs) + strlen (caret_ce);
> +  size_t len = column + 3 + strlen (caret_cs) + strlen (caret_ce);
>buffer = XALLOCAVEC (char, len);
> -  snprintf (buffer, len, "%s %*c%s", caret_cs, s.column, context->caret_char,
> +  snprintf (buffer, len, "%s %*c%s", caret_cs, column, context->caret_char,
>   caret_ce);

Maybe you should factorize out the printing of a colored line starting
at given a column, rather than copy-pasting this in fixit_hint() later?

[...]

>diagnostic_set_info (&diagnostic, gmsgid, &ap, location, DK_NOTE);
>report_diagnostic (&diagnostic);
>va_end (ap