aarch64 - Set the mode for the unspec in speculation_tracker insn.
[platform/upstream/linaro-gcc.git] / gcc / diagnostic-show-locus.c
1 /* Diagnostic subroutines for printing source-code
2    Copyright (C) 1999-2016 Free Software Foundation, Inc.
3    Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "version.h"
25 #include "demangle.h"
26 #include "intl.h"
27 #include "backtrace.h"
28 #include "diagnostic.h"
29 #include "diagnostic-color.h"
30
31 #ifdef HAVE_TERMIOS_H
32 # include <termios.h>
33 #endif
34
35 #ifdef GWINSZ_IN_SYS_IOCTL
36 # include <sys/ioctl.h>
37 #endif
38
39 /* Classes for rendering source code and diagnostics, within an
40    anonymous namespace.
41    The work is done by "class layout", which embeds and uses
42    "class colorizer" and "class layout_range" to get things done.  */
43
44 namespace {
45
46 /* The state at a given point of the source code, assuming that we're
47    in a range: which range are we in, and whether we should draw a caret at
48    this point.  */
49
50 struct point_state
51 {
52   int range_idx;
53   bool draw_caret_p;
54 };
55
56 /* A class to inject colorization codes when printing the diagnostic locus.
57
58    It has one kind of colorization for each of:
59      - normal text
60      - range 0 (the "primary location")
61      - range 1
62      - range 2
63
64    The class caches the lookup of the color codes for the above.
65
66    The class also has responsibility for tracking which of the above is
67    active, filtering out unnecessary changes.  This allows
68    layout::print_source_line and layout::print_annotation_line
69    to simply request a colorization code for *every* character they print,
70    via this class, and have the filtering be done for them here.  */
71
72 class colorizer
73 {
74  public:
75   colorizer (diagnostic_context *context,
76              const diagnostic_info *diagnostic);
77   ~colorizer ();
78
79   void set_range (int range_idx) { set_state (range_idx); }
80   void set_normal_text () { set_state (STATE_NORMAL_TEXT); }
81   void set_fixit_hint () { set_state (0); }
82
83  private:
84   void set_state (int state);
85   void begin_state (int state);
86   void finish_state (int state);
87
88  private:
89   static const int STATE_NORMAL_TEXT = -1;
90
91   diagnostic_context *m_context;
92   const diagnostic_info *m_diagnostic;
93   int m_current_state;
94   const char *m_caret_cs;
95   const char *m_caret_ce;
96   const char *m_range1_cs;
97   const char *m_range2_cs;
98   const char *m_range_ce;
99 };
100
101 /* A point within a layout_range; similar to an expanded_location,
102    but after filtering on file.  */
103
104 class layout_point
105 {
106  public:
107   layout_point (const expanded_location &exploc)
108   : m_line (exploc.line),
109     m_column (exploc.column) {}
110
111   int m_line;
112   int m_column;
113 };
114
115 /* A class for use by "class layout" below: a filtered location_range.  */
116
117 class layout_range
118 {
119  public:
120   layout_range (const expanded_location *start_exploc,
121                 const expanded_location *finish_exploc,
122                 bool show_caret_p,
123                 const expanded_location *caret_exploc);
124
125   bool contains_point (int row, int column) const;
126
127   layout_point m_start;
128   layout_point m_finish;
129   bool m_show_caret_p;
130   layout_point m_caret;
131 };
132
133 /* A struct for use by layout::print_source_line for telling
134    layout::print_annotation_line the extents of the source line that
135    it printed, so that underlines can be clipped appropriately.  */
136
137 struct line_bounds
138 {
139   int m_first_non_ws;
140   int m_last_non_ws;
141 };
142
143 /* A range of contiguous source lines within a layout (e.g. "lines 5-10"
144    or "line 23").  During the layout ctor, layout::calculate_line_spans
145    splits the pertinent source lines into a list of disjoint line_span
146    instances (e.g. lines 5-10, lines 15-20, line 23).  */
147
148 struct line_span
149 {
150   line_span (linenum_type first_line, linenum_type last_line)
151     : m_first_line (first_line), m_last_line (last_line)
152   {
153     gcc_assert (first_line <= last_line);
154   }
155   linenum_type get_first_line () const { return m_first_line; }
156   linenum_type get_last_line () const { return m_last_line; }
157
158   bool contains_line_p (linenum_type line) const
159   {
160     return line >= m_first_line && line <= m_last_line;
161   }
162
163   static int comparator (const void *p1, const void *p2)
164   {
165     const line_span *ls1 = (const line_span *)p1;
166     const line_span *ls2 = (const line_span *)p2;
167     int first_line_diff = (int)ls1->m_first_line - (int)ls2->m_first_line;
168     if (first_line_diff)
169       return first_line_diff;
170     return (int)ls1->m_last_line - (int)ls2->m_last_line;
171   }
172
173   linenum_type m_first_line;
174   linenum_type m_last_line;
175 };
176
177 /* A class to control the overall layout when printing a diagnostic.
178
179    The layout is determined within the constructor.
180    It is then printed by repeatedly calling the "print_source_line",
181    "print_annotation_line" and "print_any_fixits" methods.
182
183    We assume we have disjoint ranges.  */
184
185 class layout
186 {
187  public:
188   layout (diagnostic_context *context,
189           const diagnostic_info *diagnostic);
190
191   int get_num_line_spans () const { return m_line_spans.length (); }
192   const line_span *get_line_span (int idx) const { return &m_line_spans[idx]; }
193
194   bool print_heading_for_line_span_index_p (int line_span_idx) const;
195
196   expanded_location get_expanded_location (const line_span *) const;
197
198   bool print_source_line (int row, line_bounds *lbounds_out);
199   void print_annotation_line (int row, const line_bounds lbounds);
200   void print_any_fixits (int row, const rich_location *richloc);
201
202  private:
203   void calculate_line_spans ();
204
205   void print_newline ();
206
207   bool
208   get_state_at_point (/* Inputs.  */
209                       int row, int column,
210                       int first_non_ws, int last_non_ws,
211                       /* Outputs.  */
212                       point_state *out_state);
213
214   int
215   get_x_bound_for_row (int row, int caret_column,
216                        int last_non_ws);
217
218   void
219   move_to_column (int *column, int dest_column);
220
221  private:
222   diagnostic_context *m_context;
223   pretty_printer *m_pp;
224   diagnostic_t m_diagnostic_kind;
225   expanded_location m_exploc;
226   colorizer m_colorizer;
227   bool m_colorize_source_p;
228   auto_vec <layout_range> m_layout_ranges;
229   auto_vec <line_span> m_line_spans;
230   int m_x_offset;
231 };
232
233 /* Implementation of "class colorizer".  */
234
235 /* The constructor for "colorizer".  Lookup and store color codes for the
236    different kinds of things we might need to print.  */
237
238 colorizer::colorizer (diagnostic_context *context,
239                       const diagnostic_info *diagnostic) :
240   m_context (context),
241   m_diagnostic (diagnostic),
242   m_current_state (STATE_NORMAL_TEXT)
243 {
244   m_caret_ce = colorize_stop (pp_show_color (context->printer));
245   m_range1_cs = colorize_start (pp_show_color (context->printer), "range1");
246   m_range2_cs = colorize_start (pp_show_color (context->printer), "range2");
247   m_range_ce = colorize_stop (pp_show_color (context->printer));
248 }
249
250 /* The destructor for "colorize".  If colorization is on, print a code to
251    turn it off.  */
252
253 colorizer::~colorizer ()
254 {
255   finish_state (m_current_state);
256 }
257
258 /* Update state, printing color codes if necessary if there's a state
259    change.  */
260
261 void
262 colorizer::set_state (int new_state)
263 {
264   if (m_current_state != new_state)
265     {
266       finish_state (m_current_state);
267       m_current_state = new_state;
268       begin_state (new_state);
269     }
270 }
271
272 /* Turn on any colorization for STATE.  */
273
274 void
275 colorizer::begin_state (int state)
276 {
277   switch (state)
278     {
279     case STATE_NORMAL_TEXT:
280       break;
281
282     case 0:
283       /* Make range 0 be the same color as the "kind" text
284          (error vs warning vs note).  */
285       pp_string
286         (m_context->printer,
287          colorize_start (pp_show_color (m_context->printer),
288                          diagnostic_get_color_for_kind (m_diagnostic->kind)));
289       break;
290
291     case 1:
292       pp_string (m_context->printer, m_range1_cs);
293       break;
294
295     case 2:
296       pp_string (m_context->printer, m_range2_cs);
297       break;
298
299     default:
300       /* We don't expect more than 3 ranges per diagnostic.  */
301       gcc_unreachable ();
302       break;
303     }
304 }
305
306 /* Turn off any colorization for STATE.  */
307
308 void
309 colorizer::finish_state (int state)
310 {
311   switch (state)
312     {
313     case STATE_NORMAL_TEXT:
314       break;
315
316     case 0:
317       pp_string (m_context->printer, m_caret_ce);
318       break;
319
320     default:
321       /* Within a range.  */
322       gcc_assert (state > 0);
323       pp_string (m_context->printer, m_range_ce);
324       break;
325     }
326 }
327
328 /* Implementation of class layout_range.  */
329
330 /* The constructor for class layout_range.
331    Initialize various layout_point fields from expanded_location
332    equivalents; we've already filtered on file.  */
333
334 layout_range::layout_range (const expanded_location *start_exploc,
335                             const expanded_location *finish_exploc,
336                             bool show_caret_p,
337                             const expanded_location *caret_exploc)
338 : m_start (*start_exploc),
339   m_finish (*finish_exploc),
340   m_show_caret_p (show_caret_p),
341   m_caret (*caret_exploc)
342 {
343 }
344
345 /* Is (column, row) within the given range?
346    We've already filtered on the file.
347
348    Ranges are closed (both limits are within the range).
349
350    Example A: a single-line range:
351      start:  (col=22, line=2)
352      finish: (col=38, line=2)
353
354   |00000011111111112222222222333333333344444444444
355   |34567890123456789012345678901234567890123456789
356 --+-----------------------------------------------
357 01|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
358 02|bbbbbbbbbbbbbbbbbbbSwwwwwwwwwwwwwwwFaaaaaaaaaaa
359 03|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
360
361    Example B: a multiline range with
362      start:  (col=14, line=3)
363      finish: (col=08, line=5)
364
365   |00000011111111112222222222333333333344444444444
366   |34567890123456789012345678901234567890123456789
367 --+-----------------------------------------------
368 01|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
369 02|bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
370 03|bbbbbbbbbbbSwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
371 04|wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
372 05|wwwwwFaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
373 06|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
374 --+-----------------------------------------------
375
376    Legend:
377    - 'b' indicates a point *before* the range
378    - 'S' indicates the start of the range
379    - 'w' indicates a point within the range
380    - 'F' indicates the finish of the range (which is
381          within it).
382    - 'a' indicates a subsequent point *after* the range.  */
383
384 bool
385 layout_range::contains_point (int row, int column) const
386 {
387   gcc_assert (m_start.m_line <= m_finish.m_line);
388   /* ...but the equivalent isn't true for the columns;
389      consider example B in the comment above.  */
390
391   if (row < m_start.m_line)
392     /* Points before the first line of the range are
393        outside it (corresponding to line 01 in example A
394        and lines 01 and 02 in example B above).  */
395     return false;
396
397   if (row == m_start.m_line)
398     /* On same line as start of range (corresponding
399        to line 02 in example A and line 03 in example B).  */
400     {
401       if (column < m_start.m_column)
402         /* Points on the starting line of the range, but
403            before the column in which it begins.  */
404         return false;
405
406       if (row < m_finish.m_line)
407         /* This is a multiline range; the point
408            is within it (corresponds to line 03 in example B
409            from column 14 onwards) */
410         return true;
411       else
412         {
413           /* This is a single-line range.  */
414           gcc_assert (row == m_finish.m_line);
415           return column <= m_finish.m_column;
416         }
417     }
418
419   /* The point is in a line beyond that containing the
420      start of the range: lines 03 onwards in example A,
421      and lines 04 onwards in example B.  */
422   gcc_assert (row > m_start.m_line);
423
424   if (row > m_finish.m_line)
425     /* The point is beyond the final line of the range
426        (lines 03 onwards in example A, and lines 06 onwards
427        in example B).  */
428     return false;
429
430   if (row < m_finish.m_line)
431     {
432       /* The point is in a line that's fully within a multiline
433          range (e.g. line 04 in example B).  */
434       gcc_assert (m_start.m_line < m_finish.m_line);
435       return true;
436     }
437
438   gcc_assert (row ==  m_finish.m_line);
439
440   return column <= m_finish.m_column;
441 }
442
443 /* Given a source line LINE of length LINE_WIDTH, determine the width
444    without any trailing whitespace.  */
445
446 static int
447 get_line_width_without_trailing_whitespace (const char *line, int line_width)
448 {
449   int result = line_width;
450   while (result > 0)
451     {
452       char ch = line[result - 1];
453       if (ch == ' ' || ch == '\t')
454         result--;
455       else
456         break;
457     }
458   gcc_assert (result >= 0);
459   gcc_assert (result <= line_width);
460   gcc_assert (result == 0 ||
461               (line[result - 1] != ' '
462                && line[result -1] != '\t'));
463   return result;
464 }
465
466 /* Helper function for layout's ctor, for sanitizing locations relative
467    to the primary location within a diagnostic.
468
469    Compare LOC_A and LOC_B to see if it makes sense to print underlines
470    connecting their expanded locations.  Doing so is only guaranteed to
471    make sense if the locations share the same macro expansion "history"
472    i.e. they can be traced through the same macro expansions, eventually
473    reaching an ordinary map.
474
475    This may be too strong a condition, but it effectively sanitizes
476    PR c++/70105, which has an example of printing an expression where the
477    final location of the expression is in a different macro, which
478    erroneously was leading to hundreds of lines of irrelevant source
479    being printed.  */
480
481 static bool
482 compatible_locations_p (location_t loc_a, location_t loc_b)
483 {
484   if (IS_ADHOC_LOC (loc_a))
485     loc_a = get_location_from_adhoc_loc (line_table, loc_a);
486   if (IS_ADHOC_LOC (loc_b))
487     loc_b = get_location_from_adhoc_loc (line_table, loc_b);
488
489   /* If either location is one of the special locations outside of a
490      linemap, they are only compatible if they are equal.  */
491   if (loc_a < RESERVED_LOCATION_COUNT
492       || loc_b < RESERVED_LOCATION_COUNT)
493     return loc_a == loc_b;
494
495   const line_map *map_a = linemap_lookup (line_table, loc_a);
496   linemap_assert (map_a);
497
498   const line_map *map_b = linemap_lookup (line_table, loc_b);
499   linemap_assert (map_b);
500
501   /* Are they within the same map?  */
502   if (map_a == map_b)
503     {
504       /* Are both within the same macro expansion?  */
505       if (linemap_macro_expansion_map_p (map_a))
506         {
507           /* Expand each location towards the spelling location, and
508              recurse.  */
509           const line_map_macro *macro_map = linemap_check_macro (map_a);
510           source_location loc_a_toward_spelling
511             = linemap_macro_map_loc_unwind_toward_spelling (line_table,
512                                                             macro_map,
513                                                             loc_a);
514           source_location loc_b_toward_spelling
515             = linemap_macro_map_loc_unwind_toward_spelling (line_table,
516                                                             macro_map,
517                                                             loc_b);
518           return compatible_locations_p (loc_a_toward_spelling,
519                                          loc_b_toward_spelling);
520         }
521
522       /* Otherwise they are within the same ordinary map.  */
523       return true;
524     }
525   else
526     {
527       /* Within different maps.  */
528
529       /* If either is within a macro expansion, they are incompatible.  */
530       if (linemap_macro_expansion_map_p (map_a)
531           || linemap_macro_expansion_map_p (map_b))
532         return false;
533
534       /* Within two different ordinary maps; they are compatible iff they
535          are in the same file.  */
536       const line_map_ordinary *ord_map_a = linemap_check_ordinary (map_a);
537       const line_map_ordinary *ord_map_b = linemap_check_ordinary (map_b);
538       return ord_map_a->to_file == ord_map_b->to_file;
539     }
540 }
541
542 /* Implementation of class layout.  */
543
544 /* Constructor for class layout.
545
546    Filter the ranges from the rich_location to those that we can
547    sanely print, populating m_layout_ranges.
548    Determine the range of lines that we will print, splitting them
549    up into an ordered list of disjoint spans of contiguous line numbers.
550    Determine m_x_offset, to ensure that the primary caret
551    will fit within the max_width provided by the diagnostic_context.  */
552
553 layout::layout (diagnostic_context * context,
554                 const diagnostic_info *diagnostic)
555 : m_context (context),
556   m_pp (context->printer),
557   m_diagnostic_kind (diagnostic->kind),
558   m_exploc (diagnostic->richloc->get_expanded_location (0)),
559   m_colorizer (context, diagnostic),
560   m_colorize_source_p (context->colorize_source_p),
561   m_layout_ranges (rich_location::MAX_RANGES),
562   m_line_spans (1 + rich_location::MAX_RANGES),
563   m_x_offset (0)
564 {
565   rich_location *richloc = diagnostic->richloc;
566   source_location primary_loc = richloc->get_range (0)->m_loc;
567
568   for (unsigned int idx = 0; idx < richloc->get_num_locations (); idx++)
569     {
570       /* This diagnostic printer can only cope with "sufficiently sane" ranges.
571          Ignore any ranges that are awkward to handle.  */
572       const location_range *loc_range = richloc->get_range (idx);
573
574       /* Split the "range" into caret and range information.  */
575       source_range src_range = get_range_from_loc (line_table, loc_range->m_loc);
576
577       /* Expand the various locations.  */
578       expanded_location start
579         = linemap_client_expand_location_to_spelling_point (src_range.m_start);
580       expanded_location finish
581         = linemap_client_expand_location_to_spelling_point (src_range.m_finish);
582       expanded_location caret
583         = linemap_client_expand_location_to_spelling_point (loc_range->m_loc);
584
585       /* If any part of the range isn't in the same file as the primary
586          location of this diagnostic, ignore the range.  */
587       if (start.file != m_exploc.file)
588         continue;
589       if (finish.file != m_exploc.file)
590         continue;
591       if (loc_range->m_show_caret_p)
592         if (caret.file != m_exploc.file)
593           continue;
594
595       /* Sanitize the caret location for non-primary ranges.  */
596       if (m_layout_ranges.length () > 0)
597         if (loc_range->m_show_caret_p)
598           if (!compatible_locations_p (loc_range->m_loc, primary_loc))
599             /* Discard any non-primary ranges that can't be printed
600                sanely relative to the primary location.  */
601             continue;
602
603       /* Everything is now known to be in the correct source file,
604          but it may require further sanitization.  */
605       layout_range ri (&start, &finish, loc_range->m_show_caret_p, &caret);
606
607       /* If we have a range that finishes before it starts (perhaps
608          from something built via macro expansion), printing the
609          range is likely to be nonsensical.  Also, attempting to do so
610          breaks assumptions within the printing code  (PR c/68473).
611          Similarly, don't attempt to print ranges if one or both ends
612          of the range aren't sane to print relative to the
613          primary location (PR c++/70105).  */
614       if (start.line > finish.line
615           || !compatible_locations_p (src_range.m_start, primary_loc)
616           || !compatible_locations_p (src_range.m_finish, primary_loc))
617         {
618           /* Is this the primary location?  */
619           if (m_layout_ranges.length () == 0)
620             {
621               /* We want to print the caret for the primary location, but
622                  we must sanitize away m_start and m_finish.  */
623               ri.m_start = ri.m_caret;
624               ri.m_finish = ri.m_caret;
625             }
626           else
627             /* This is a non-primary range; ignore it.  */
628             continue;
629         }
630
631       /* Passed all the tests; add the range to m_layout_ranges so that
632          it will be printed.  */
633       m_layout_ranges.safe_push (ri);
634     }
635
636   /* Populate m_line_spans.  */
637   calculate_line_spans ();
638
639   /* Adjust m_x_offset.
640      Center the primary caret to fit in max_width; all columns
641      will be adjusted accordingly.  */
642   int max_width = m_context->caret_max_width;
643   int line_width;
644   const char *line = location_get_source_line (m_exploc.file, m_exploc.line,
645                                                &line_width);
646   if (line && m_exploc.column <= line_width)
647     {
648       int right_margin = CARET_LINE_MARGIN;
649       int column = m_exploc.column;
650       right_margin = MIN (line_width - column, right_margin);
651       right_margin = max_width - right_margin;
652       if (line_width >= max_width && column > right_margin)
653         m_x_offset = column - right_margin;
654       gcc_assert (m_x_offset >= 0);
655     }
656 }
657
658 /* Return true iff we should print a heading when starting the
659    line span with the given index.  */
660
661 bool
662 layout::print_heading_for_line_span_index_p (int line_span_idx) const
663 {
664   /* We print a heading for every change of line span, hence for every
665      line span after the initial one.  */
666   if (line_span_idx > 0)
667     return true;
668
669   /* We also do it for the initial span if the primary location of the
670      diagnostic is in a different span.  */
671   if (m_exploc.line > (int)get_line_span (0)->m_last_line)
672     return true;
673
674   return false;
675 }
676
677 /* Get an expanded_location for the first location of interest within
678    the given line_span.
679    Used when printing a heading to indicate a new line span.  */
680
681 expanded_location
682 layout::get_expanded_location (const line_span *line_span) const
683 {
684   /* Whenever possible, use the caret location.  */
685   if (line_span->contains_line_p (m_exploc.line))
686     return m_exploc;
687
688   /* Otherwise, use the start of the first range that's present
689      within the line_span.  */
690   for (unsigned int i = 0; i < m_layout_ranges.length (); i++)
691     {
692       const layout_range *lr = &m_layout_ranges[i];
693       if (line_span->contains_line_p (lr->m_start.m_line))
694         {
695           expanded_location exploc = m_exploc;
696           exploc.line = lr->m_start.m_line;
697           exploc.column = lr->m_start.m_column;
698           return exploc;
699         }
700     }
701
702   /* It should not be possible to have a line span that didn't
703      contain any of the layout_range instances.  */
704   gcc_unreachable ();
705   return m_exploc;
706 }
707
708 /* We want to print the pertinent source code at a diagnostic.  The
709    rich_location can contain multiple locations.  This will have been
710    filtered into m_exploc (the caret for the primary location) and
711    m_layout_ranges, for those ranges within the same source file.
712
713    We will print a subset of the lines within the source file in question,
714    as a collection of "spans" of lines.
715
716    This function populates m_line_spans with an ordered, disjoint list of
717    the line spans of interest.
718
719    For example, if the primary caret location is on line 7, with ranges
720    covering lines 5-6 and lines 9-12:
721
722      004
723      005                   |RANGE 0
724      006                   |RANGE 0
725      007  |PRIMARY CARET
726      008
727      009                                |RANGE 1
728      010                                |RANGE 1
729      011                                |RANGE 1
730      012                                |RANGE 1
731      013
732
733    then we want two spans: lines 5-7 and lines 9-12.  */
734
735 void
736 layout::calculate_line_spans ()
737 {
738   /* This should only be called once, by the ctor.  */
739   gcc_assert (m_line_spans.length () == 0);
740
741   /* Populate tmp_spans with individual spans, for each of
742      m_exploc, and for m_layout_ranges.  */
743   auto_vec<line_span> tmp_spans (1 + rich_location::MAX_RANGES);
744   tmp_spans.safe_push (line_span (m_exploc.line, m_exploc.line));
745   for (unsigned int i = 0; i < m_layout_ranges.length (); i++)
746     {
747       const layout_range *lr = &m_layout_ranges[i];
748       gcc_assert (lr->m_start.m_line <= lr->m_finish.m_line);
749       tmp_spans.safe_push (line_span (lr->m_start.m_line,
750                                       lr->m_finish.m_line));
751     }
752
753   /* Sort them.  */
754   tmp_spans.qsort(line_span::comparator);
755
756   /* Now iterate through tmp_spans, copying into m_line_spans, and
757      combining where possible.  */
758   gcc_assert (tmp_spans.length () > 0);
759   m_line_spans.safe_push (tmp_spans[0]);
760   for (unsigned int i = 1; i < tmp_spans.length (); i++)
761     {
762       line_span *current = &m_line_spans[m_line_spans.length () - 1];
763       const line_span *next = &tmp_spans[i];
764       gcc_assert (next->m_first_line >= current->m_first_line);
765       if (next->m_first_line <= current->m_last_line + 1)
766         {
767           /* We can merge them. */
768           if (next->m_last_line > current->m_last_line)
769             current->m_last_line = next->m_last_line;
770         }
771       else
772         {
773           /* No merger possible.  */
774           m_line_spans.safe_push (*next);
775         }
776     }
777
778   /* Verify the result, in m_line_spans.  */
779   gcc_assert (m_line_spans.length () > 0);
780   for (unsigned int i = 1; i < m_line_spans.length (); i++)
781     {
782       const line_span *prev = &m_line_spans[i - 1];
783       const line_span *next = &m_line_spans[i];
784       /* The individual spans must be sane.  */
785       gcc_assert (prev->m_first_line <= prev->m_last_line);
786       gcc_assert (next->m_first_line <= next->m_last_line);
787       /* The spans must be ordered.  */
788       gcc_assert (prev->m_first_line < next->m_first_line);
789       /* There must be a gap of at least one line between separate spans.  */
790       gcc_assert ((prev->m_last_line + 1) < next->m_first_line);
791     }
792 }
793
794 /* Attempt to print line ROW of source code, potentially colorized at any
795    ranges.
796    Return true if the line was printed, populating *LBOUNDS_OUT.
797    Return false if the source line could not be read, leaving *LBOUNDS_OUT
798    untouched.  */
799
800 bool
801 layout::print_source_line (int row, line_bounds *lbounds_out)
802 {
803   int line_width;
804   const char *line = location_get_source_line (m_exploc.file, row,
805                                                &line_width);
806   if (!line)
807     return false;
808
809   m_colorizer.set_normal_text ();
810
811   /* We will stop printing the source line at any trailing
812      whitespace.  */
813   line_width = get_line_width_without_trailing_whitespace (line,
814                                                            line_width);
815   line += m_x_offset;
816
817   pp_space (m_pp);
818   int first_non_ws = INT_MAX;
819   int last_non_ws = 0;
820   int column;
821   for (column = 1 + m_x_offset; column <= line_width; column++)
822     {
823       /* Assuming colorization is enabled for the caret and underline
824          characters, we may also colorize the associated characters
825          within the source line.
826
827          For frontends that generate range information, we color the
828          associated characters in the source line the same as the
829          carets and underlines in the annotation line, to make it easier
830          for the reader to see the pertinent code.
831
832          For frontends that only generate carets, we don't colorize the
833          characters above them, since this would look strange (e.g.
834          colorizing just the first character in a token).  */
835       if (m_colorize_source_p)
836         {
837           bool in_range_p;
838           point_state state;
839           in_range_p = get_state_at_point (row, column,
840                                            0, INT_MAX,
841                                            &state);
842           if (in_range_p)
843             m_colorizer.set_range (state.range_idx);
844           else
845             m_colorizer.set_normal_text ();
846         }
847       char c = *line == '\t' ? ' ' : *line;
848       if (c == '\0')
849         c = ' ';
850       if (c != ' ')
851         {
852           last_non_ws = column;
853           if (first_non_ws == INT_MAX)
854             first_non_ws = column;
855         }
856       pp_character (m_pp, c);
857       line++;
858     }
859   print_newline ();
860
861   lbounds_out->m_first_non_ws = first_non_ws;
862   lbounds_out->m_last_non_ws = last_non_ws;
863   return true;
864 }
865
866 /* Print a line consisting of the caret/underlines for the given
867    source line.  */
868
869 void
870 layout::print_annotation_line (int row, const line_bounds lbounds)
871 {
872   int x_bound = get_x_bound_for_row (row, m_exploc.column,
873                                      lbounds.m_last_non_ws);
874
875   pp_space (m_pp);
876   for (int column = 1 + m_x_offset; column < x_bound; column++)
877     {
878       bool in_range_p;
879       point_state state;
880       in_range_p = get_state_at_point (row, column,
881                                        lbounds.m_first_non_ws,
882                                        lbounds.m_last_non_ws,
883                                        &state);
884       if (in_range_p)
885         {
886           /* Within a range.  Draw either the caret or an underline.  */
887           m_colorizer.set_range (state.range_idx);
888           if (state.draw_caret_p)
889             /* Draw the caret.  */
890             pp_character (m_pp, m_context->caret_chars[state.range_idx]);
891           else
892             pp_character (m_pp, '~');
893         }
894       else
895         {
896           /* Not in a range.  */
897           m_colorizer.set_normal_text ();
898           pp_character (m_pp, ' ');
899         }
900     }
901   print_newline ();
902 }
903
904 /* If there are any fixit hints on source line ROW within RICHLOC, print them.
905    They are printed in order, attempting to combine them onto lines, but
906    starting new lines if necessary.  */
907
908 void
909 layout::print_any_fixits (int row, const rich_location *richloc)
910 {
911   int column = 0;
912   for (unsigned int i = 0; i < richloc->get_num_fixit_hints (); i++)
913     {
914       fixit_hint *hint = richloc->get_fixit_hint (i);
915       if (hint->affects_line_p (m_exploc.file, row))
916         {
917           /* For now we assume each fixit hint can only touch one line.  */
918           switch (hint->get_kind ())
919             {
920             case fixit_hint::INSERT:
921               {
922                 fixit_insert *insert = static_cast <fixit_insert *> (hint);
923                 /* This assumes the insertion just affects one line.  */
924                 int start_column
925                   = LOCATION_COLUMN (insert->get_location ());
926                 move_to_column (&column, start_column);
927                 m_colorizer.set_fixit_hint ();
928                 pp_string (m_pp, insert->get_string ());
929                 m_colorizer.set_normal_text ();
930                 column += insert->get_length ();
931               }
932               break;
933
934             case fixit_hint::REMOVE:
935               {
936                 fixit_remove *remove = static_cast <fixit_remove *> (hint);
937                 /* This assumes the removal just affects one line.  */
938                 source_range src_range = remove->get_range ();
939                 int start_column = LOCATION_COLUMN (src_range.m_start);
940                 int finish_column = LOCATION_COLUMN (src_range.m_finish);
941                 move_to_column (&column, start_column);
942                 for (int column = start_column; column <= finish_column; column++)
943                   {
944                     m_colorizer.set_fixit_hint ();
945                     pp_character (m_pp, '-');
946                     m_colorizer.set_normal_text ();
947                   }
948               }
949               break;
950
951             case fixit_hint::REPLACE:
952               {
953                 fixit_replace *replace = static_cast <fixit_replace *> (hint);
954                 int start_column
955                   = LOCATION_COLUMN (replace->get_range ().m_start);
956                 move_to_column (&column, start_column);
957                 m_colorizer.set_fixit_hint ();
958                 pp_string (m_pp, replace->get_string ());
959                 m_colorizer.set_normal_text ();
960                 column += replace->get_length ();
961               }
962               break;
963
964             default:
965               gcc_unreachable ();
966             }
967         }
968     }
969
970   /* Add a trailing newline, if necessary.  */
971   move_to_column (&column, 0);
972 }
973
974 /* Disable any colorization and emit a newline.  */
975
976 void
977 layout::print_newline ()
978 {
979   m_colorizer.set_normal_text ();
980   pp_newline (m_pp);
981 }
982
983 /* Return true if (ROW/COLUMN) is within a range of the layout.
984    If it returns true, OUT_STATE is written to, with the
985    range index, and whether we should draw the caret at
986    (ROW/COLUMN) (as opposed to an underline).  */
987
988 bool
989 layout::get_state_at_point (/* Inputs.  */
990                             int row, int column,
991                             int first_non_ws, int last_non_ws,
992                             /* Outputs.  */
993                             point_state *out_state)
994 {
995   layout_range *range;
996   int i;
997   FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
998     {
999       if (range->contains_point (row, column))
1000         {
1001           out_state->range_idx = i;
1002
1003           /* Are we at the range's caret?  is it visible? */
1004           out_state->draw_caret_p = false;
1005           if (range->m_show_caret_p
1006               && row == range->m_caret.m_line
1007               && column == range->m_caret.m_column)
1008             out_state->draw_caret_p = true;
1009
1010           /* Within a multiline range, don't display any underline
1011              in any leading or trailing whitespace on a line.
1012              We do display carets, however.  */
1013           if (!out_state->draw_caret_p)
1014             if (column < first_non_ws || column > last_non_ws)
1015               return false;
1016
1017           /* We are within a range.  */
1018           return true;
1019         }
1020     }
1021
1022   return false;
1023 }
1024
1025 /* Helper function for use by layout::print_line when printing the
1026    annotation line under the source line.
1027    Get the column beyond the rightmost one that could contain a caret or
1028    range marker, given that we stop rendering at trailing whitespace.
1029    ROW is the source line within the given file.
1030    CARET_COLUMN is the column of range 0's caret.
1031    LAST_NON_WS_COLUMN is the last column containing a non-whitespace
1032    character of source (as determined when printing the source line).  */
1033
1034 int
1035 layout::get_x_bound_for_row (int row, int caret_column,
1036                              int last_non_ws_column)
1037 {
1038   int result = caret_column + 1;
1039
1040   layout_range *range;
1041   int i;
1042   FOR_EACH_VEC_ELT (m_layout_ranges, i, range)
1043     {
1044       if (row >= range->m_start.m_line)
1045         {
1046           if (range->m_finish.m_line == row)
1047             {
1048               /* On the final line within a range; ensure that
1049                  we render up to the end of the range.  */
1050               if (result <= range->m_finish.m_column)
1051                 result = range->m_finish.m_column + 1;
1052             }
1053           else if (row < range->m_finish.m_line)
1054             {
1055               /* Within a multiline range; ensure that we render up to the
1056                  last non-whitespace column.  */
1057               if (result <= last_non_ws_column)
1058                 result = last_non_ws_column + 1;
1059             }
1060         }
1061     }
1062
1063   return result;
1064 }
1065
1066 /* Given *COLUMN as an x-coordinate, print spaces to position
1067    successive output at DEST_COLUMN, printing a newline if necessary,
1068    and updating *COLUMN.  */
1069
1070 void
1071 layout::move_to_column (int *column, int dest_column)
1072 {
1073   /* Start a new line if we need to.  */
1074   if (*column > dest_column)
1075     {
1076       print_newline ();
1077       *column = 0;
1078     }
1079
1080   while (*column < dest_column)
1081     {
1082       pp_space (m_pp);
1083       (*column)++;
1084     }
1085 }
1086
1087 } /* End of anonymous namespace.  */
1088
1089 /* Print the physical source code corresponding to the location of
1090    this diagnostic, with additional annotations.  */
1091
1092 void
1093 diagnostic_show_locus (diagnostic_context * context,
1094                        const diagnostic_info *diagnostic)
1095 {
1096   pp_newline (context->printer);
1097
1098   if (!context->show_caret
1099       || diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION
1100       || diagnostic_location (diagnostic, 0) == context->last_location)
1101     return;
1102
1103   context->last_location = diagnostic_location (diagnostic, 0);
1104
1105   const char *saved_prefix = pp_get_prefix (context->printer);
1106   pp_set_prefix (context->printer, NULL);
1107
1108   layout layout (context, diagnostic);
1109   for (int line_span_idx = 0; line_span_idx < layout.get_num_line_spans ();
1110        line_span_idx++)
1111     {
1112       const line_span *line_span = layout.get_line_span (line_span_idx);
1113       if (layout.print_heading_for_line_span_index_p (line_span_idx))
1114         {
1115           expanded_location exploc = layout.get_expanded_location (line_span);
1116           context->start_span (context, exploc);
1117         }
1118       int last_line = line_span->get_last_line ();
1119       for (int row = line_span->get_first_line (); row <= last_line; row++)
1120         {
1121           /* Print the source line, followed by an annotation line
1122              consisting of any caret/underlines, then any fixits.
1123              If the source line can't be read, print nothing.  */
1124           line_bounds lbounds;
1125           if (layout.print_source_line (row, &lbounds))
1126             {
1127               layout.print_annotation_line (row, lbounds);
1128               layout.print_any_fixits (row, diagnostic->richloc);
1129             }
1130         }
1131     }
1132
1133   pp_set_prefix (context->printer, saved_prefix);
1134 }