[PATCH 4b] diagnostic-show-locus.c changes: Insertions

Jeff Law law@redhat.com
Fri Oct 30 04:53:00 GMT 2015


On 10/28/2015 12:09 PM, David Malcolm wrote:
> gcc/ChangeLog:
> 	* diagnostic-show-locus.c (struct point_state): New struct.
> 	(class colorizer): New class.
> 	(class layout_point): New class.
> 	(class layout_range): New class.
> 	(class layout): New class.
> 	(colorizer::colorizer): New ctor.
> 	(colorizer::~colorizer): New dtor.
> 	(layout::layout): New ctor.
> 	(layout::print_line): New method.
> 	(layout::get_state_at_point): New method.
> 	(layout::get_x_bound_for_row): New method.
> 	(show_ruler): New function.
> 	(diagnostic_show_locus): Reimplement in terms of class layout.
> ---
> +};
> +
> +/* A class to inject colorization codes when printing the diagnostic locus.
> +
> +   It has one kind of colorization for each of:
> +     - normal text
> +     - range 0 (the "primary location")
> +     - range 1
> +     - range 2
> +
> +   The class caches the lookup of the color codes for the above.
> +
> +   The class also has responsibility for tracking which of the above is
> +   active, filtering out unnecessary changes.  This allows layout::print_line
> +   to simply request a colorization code for *every* character it prints
> +   through this class, and have the filtering be done for it here.  */
Not asking you to do anything here -- hopefully this isn't a huge burden 
on the diagnostic performance.  Normally I wouldn't even notice except 
that we're inserting colorization on every character.  That kind of 
model can get expensive.  Something to watch out for -- though I doubt 
we do he massive diagnostic spews we used to which is probably the only 
place it'd be noticeable.



> +
> +/* A point within a layout_range; similar to an expanded_location,
> +   but after filtering on file.  */
> +
> +class layout_point
> +{
> + public:
> +  layout_point (const expanded_location &exploc)
> +  : m_line (exploc.line),
> +    m_column (exploc.column) {}
> +
> +  int m_line;
> +  int m_column;
> +};
Is this even deserving of its own class?  If you pulled up 
m_line/m_column you don't need the class, though I guess you need thee 
of each, one for the start, one for the finish & one for the caret, 
which in turn bloats the layout_range's constructor.  So I guess this is OK.






> +/* Given a source line LINE of length LINE_WIDTH, determine the width
> +   without any trailing whitespace.  */
> +
> +static int
> +get_line_width_without_trailing_whitespace (const char *line, int line_width)
> +{
> +  int result = line_width;
> +  while (result > 0)
> +    {
> +      char ch = line[result - 1];
> +      if (ch == ' ' || ch == '\t')
> +	result--;
> +      else
> +	break;
> +    }
> +  gcc_assert (result >= 0);
> +  gcc_assert (result <= line_width);
> +  gcc_assert (result == 0 ||
> +	      (line[result - 1] != ' '
> +	       && line[result -1] != '\t'));
> +  return result;
> +}
If you use an unsigned for the line width, don't all the asserts become 
redundant & unnecessary?  I love the sanity checking and I could see how 
it might be useful it someone were to reimplmenent this function at a 
later date.  So maybe keep.

> +
> +/* Implementation of class layout.  */
> +
> +/* Constructor for class layout.
> +
> +   Filter the ranges from the rich_location to those that we can
> +   sanely print, populating m_layout_ranges.
> +   Determine the range of lines that we will print.
> +   Determine m_x_offset, to ensure that the primary caret
> +   will fit within the max_width provided by the diagnostic_context.  */
> +
> +layout::layout (diagnostic_context * context,
> +		const diagnostic_info *diagnostic)
[ ... ]
> +  if (0)
> +    show_ruler (context, line_width, m_x_offset);
Debugging code?  If it's if (0) you should probably delete it at this point.


> +}
> +
> +/* Print text describing a line of source code.
> +   This typically prints two lines:
> +
> +   (1) the source code itself, potentially colorized at any ranges, and
> +   (2) an annotation line containing any carets/underlines
> +   describing the ranges.  */
> +
> +void
> +layout::print_line (int row)
Consider breaking this into two functions.  One to print the source line 
and another to print caret/underlines.


  +
> +/* Return true if (ROW/COLUMN) is within a range of the layout.
> +   If it returns true, OUT_STATE is written to, with the
> +   range index, and whether we should draw the caret at
> +   (ROW/COLUMN) (as opposed to an underline).  */
> +
> +bool
> +layout::get_state_at_point (/* Inputs.  */
> +			    int row, int column,
> +			    int first_non_ws, int last_non_ws,
> +			    /* Outputs.  */
> +			    point_state *out_state)
> +{
> +  layout_range *range;
> +  int i;
> +  FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
> +    {
> +      if (0)
> +	fprintf (stderr,
> +		 "range ( (%i, %i), (%i, %i))->contains_point (%i, %i): %s\n",
> +		 range->m_start.m_line,
> +		 range->m_start.m_column,
> +		 range->m_finish.m_line,
> +		 range->m_finish.m_column,
> +		 row,
> +		 column,
> +		 range->contains_point (row, column) ? "true" : "false");
More old debugging code that needs to be removed?



> +
> +/* For debugging layout issues in diagnostic_show_locus and friends,
> +   render a ruler giving column numbers (after the 1-column indent).  */
> +
> +static void
> +show_ruler (diagnostic_context *context, int max_width, int x_offset)
Seems like it ought to be DEBUG_FUNCTION or removed.  I believe it's 
only caller is in if (0) code in layout's ctor.


Overall this looks good.  Take the actions you deem appropriate WRT the 
debugging bits, breaking print_line into two functions and the signed vs 
unsigned stuff in get_line_width_without_trailing_whitespace and it's 
good for the trunk.

Jeff





More information about the Gcc-patches mailing list