Branch data Line data Source code
1 : : /* Bundles of location information used when printing diagnostics.
2 : : Copyright (C) 2015-2025 Free Software Foundation, Inc.
3 : :
4 : : This program is free software; you can redistribute it and/or modify it
5 : : under the terms of the GNU General Public License as published by the
6 : : Free Software Foundation; either version 3, or (at your option) any
7 : : later version.
8 : :
9 : : This program is distributed in the hope that it will be useful,
10 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : : GNU General Public License for more details.
13 : :
14 : : You should have received a copy of the GNU General Public License
15 : : along with this program; see the file COPYING3. If not see
16 : : <http://www.gnu.org/licenses/>.
17 : :
18 : : In other words, you are welcome to use, share and improve this program.
19 : : You are forbidden to forbid anyone else to use, share and improve
20 : : what you give them. Help stamp out software-hoarding! */
21 : :
22 : : #ifndef LIBCPP_RICH_LOCATION_H
23 : : #define LIBCPP_RICH_LOCATION_H
24 : :
25 : : #include "label-text.h"
26 : :
27 : : class range_label;
28 : : class label_effects;
29 : :
30 : : /* A hint to diagnostic_show_locus on how to print a source range within a
31 : : rich_location.
32 : :
33 : : Typically this is SHOW_RANGE_WITH_CARET for the 0th range, and
34 : : SHOW_RANGE_WITHOUT_CARET for subsequent ranges,
35 : : but the Fortran frontend uses SHOW_RANGE_WITH_CARET repeatedly for
36 : : printing things like:
37 : :
38 : : x = x + y
39 : : 1 2
40 : : Error: Shapes for operands at (1) and (2) are not conformable
41 : :
42 : : where "1" and "2" are notionally carets. */
43 : :
44 : : enum range_display_kind
45 : : {
46 : : /* Show the pertinent source line(s), the caret, and underline(s). */
47 : : SHOW_RANGE_WITH_CARET,
48 : :
49 : : /* Show the pertinent source line(s) and underline(s), but don't
50 : : show the caret (just an underline). */
51 : : SHOW_RANGE_WITHOUT_CARET,
52 : :
53 : : /* Just show the source lines; don't show the range itself.
54 : : This is for use when displaying some line-insertion fix-it hints (for
55 : : showing the user context on the change, for when it doesn't make sense
56 : : to highlight the first column on the next line). */
57 : : SHOW_LINES_WITHOUT_RANGE
58 : : };
59 : :
60 : : /* A location within a rich_location: a caret&range, with
61 : : the caret potentially flagged for display, and an optional
62 : : label. */
63 : :
64 : : struct location_range
65 : : {
66 : : location_t m_loc;
67 : :
68 : : enum range_display_kind m_range_display_kind;
69 : :
70 : : /* If non-NULL, the label for this range. */
71 : : const range_label *m_label;
72 : :
73 : : /* If non-null, the name of the color to use for this range. */
74 : : const char *m_highlight_color;
75 : : };
76 : :
77 : : /* A partially-embedded vec for use within rich_location for storing
78 : : ranges and fix-it hints.
79 : :
80 : : Elements [0..NUM_EMBEDDED) are allocated within m_embed, after
81 : : that they are within the dynamically-allocated m_extra.
82 : :
83 : : This allows for static allocation in the common case, whilst
84 : : supporting the rarer case of an arbitrary number of elements.
85 : :
86 : : Dynamic allocation is not performed unless it's needed. */
87 : :
88 : : template <typename T, int NUM_EMBEDDED>
89 : : class semi_embedded_vec
90 : : {
91 : : public:
92 : : semi_embedded_vec ();
93 : : ~semi_embedded_vec ();
94 : : semi_embedded_vec (const semi_embedded_vec &other);
95 : :
96 : 1523691 : unsigned int count () const { return m_num; }
97 : : T& operator[] (int idx);
98 : : const T& operator[] (int idx) const;
99 : :
100 : : void push (const T&);
101 : : void truncate (int len);
102 : :
103 : : private:
104 : : int m_num;
105 : : T m_embedded[NUM_EMBEDDED];
106 : : int m_alloc;
107 : : T *m_extra;
108 : : };
109 : :
110 : : /* Constructor for semi_embedded_vec. In particular, no dynamic allocation
111 : : is done. */
112 : :
113 : : template <typename T, int NUM_EMBEDDED>
114 : : semi_embedded_vec<T, NUM_EMBEDDED>::semi_embedded_vec ()
115 : : : m_num (0), m_alloc (0), m_extra (NULL)
116 : : {
117 : : }
118 : :
119 : : /* Copy constructor for semi_embedded_vec. */
120 : :
121 : : template <typename T, int NUM_EMBEDDED>
122 : : semi_embedded_vec<T, NUM_EMBEDDED>::semi_embedded_vec (const semi_embedded_vec &other)
123 : : : m_num (0),
124 : : m_alloc (other.m_alloc),
125 : : m_extra (nullptr)
126 : : {
127 : : if (other.m_extra)
128 : : m_extra = XNEWVEC (T, m_alloc);
129 : :
130 : : for (int i = 0; i < other.m_num; i++)
131 : : push (other[i]);
132 : : }
133 : :
134 : : /* semi_embedded_vec's dtor. Release any dynamically-allocated memory. */
135 : :
136 : : template <typename T, int NUM_EMBEDDED>
137 : : semi_embedded_vec<T, NUM_EMBEDDED>::~semi_embedded_vec ()
138 : : {
139 : : XDELETEVEC (m_extra);
140 : : }
141 : :
142 : : /* Look up element IDX, mutably. */
143 : :
144 : : template <typename T, int NUM_EMBEDDED>
145 : : T&
146 : : semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx)
147 : : {
148 : : linemap_assert (idx < m_num);
149 : : if (idx < NUM_EMBEDDED)
150 : : return m_embedded[idx];
151 : : else
152 : : {
153 : : linemap_assert (m_extra != NULL);
154 : : return m_extra[idx - NUM_EMBEDDED];
155 : : }
156 : : }
157 : :
158 : : /* Look up element IDX (const). */
159 : :
160 : : template <typename T, int NUM_EMBEDDED>
161 : : const T&
162 : 19304 : semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx) const
163 : : {
164 : 19304 : linemap_assert (idx < m_num);
165 : 19304 : if (idx < NUM_EMBEDDED)
166 : 13643 : return m_embedded[idx];
167 : : else
168 : : {
169 : 5661 : linemap_assert (m_extra != NULL);
170 : 5661 : return m_extra[idx - NUM_EMBEDDED];
171 : : }
172 : : }
173 : :
174 : : /* Append VALUE to the end of the semi_embedded_vec. */
175 : :
176 : : template <typename T, int NUM_EMBEDDED>
177 : : void
178 : : semi_embedded_vec<T, NUM_EMBEDDED>::push (const T& value)
179 : : {
180 : : int idx = m_num++;
181 : : if (idx < NUM_EMBEDDED)
182 : : m_embedded[idx] = value;
183 : : else
184 : : {
185 : : /* Offset "idx" to be an index within m_extra. */
186 : : idx -= NUM_EMBEDDED;
187 : : if (NULL == m_extra)
188 : : {
189 : : linemap_assert (m_alloc == 0);
190 : : m_alloc = 16;
191 : : m_extra = XNEWVEC (T, m_alloc);
192 : : }
193 : : else if (idx >= m_alloc)
194 : : {
195 : : linemap_assert (m_alloc > 0);
196 : : m_alloc *= 2;
197 : : m_extra = XRESIZEVEC (T, m_extra, m_alloc);
198 : : }
199 : : linemap_assert (m_extra);
200 : : linemap_assert (idx < m_alloc);
201 : : m_extra[idx] = value;
202 : : }
203 : : }
204 : :
205 : : /* Truncate to length LEN. No deallocation is performed. */
206 : :
207 : : template <typename T, int NUM_EMBEDDED>
208 : : void
209 : : semi_embedded_vec<T, NUM_EMBEDDED>::truncate (int len)
210 : : {
211 : : linemap_assert (len <= m_num);
212 : : m_num = len;
213 : : }
214 : :
215 : : class fixit_hint;
216 : : class diagnostic_path;
217 : :
218 : : /* A "rich" source code location, for use when printing diagnostics.
219 : : A rich_location has one or more carets&ranges, where the carets
220 : : are optional. These are referred to as "ranges" from here.
221 : : Typically the zeroth range has a caret; other ranges sometimes
222 : : have carets.
223 : :
224 : : The "primary" location of a rich_location is the caret of range 0,
225 : : used for determining the line/column when printing diagnostic
226 : : text, such as:
227 : :
228 : : some-file.c:3:1: error: ...etc...
229 : :
230 : : Additional ranges may be added to help the user identify other
231 : : pertinent clauses in a diagnostic.
232 : :
233 : : Ranges can (optionally) be given labels via class range_label.
234 : :
235 : : rich_location instances are intended to be allocated on the stack
236 : : when generating diagnostics, and to be short-lived.
237 : :
238 : : Examples of rich locations
239 : : --------------------------
240 : :
241 : : Example A
242 : : *********
243 : : int i = "foo";
244 : : ^
245 : : This "rich" location is simply a single range (range 0), with
246 : : caret = start = finish at the given point.
247 : :
248 : : Example B
249 : : *********
250 : : a = (foo && bar)
251 : : ~~~~~^~~~~~~
252 : : This rich location has a single range (range 0), with the caret
253 : : at the first "&", and the start/finish at the parentheses.
254 : : Compare with example C below.
255 : :
256 : : Example C
257 : : *********
258 : : a = (foo && bar)
259 : : ~~~ ^~ ~~~
260 : : This rich location has three ranges:
261 : : - Range 0 has its caret and start location at the first "&" and
262 : : end at the second "&.
263 : : - Range 1 has its start and finish at the "f" and "o" of "foo";
264 : : the caret is not flagged for display, but is perhaps at the "f"
265 : : of "foo".
266 : : - Similarly, range 2 has its start and finish at the "b" and "r" of
267 : : "bar"; the caret is not flagged for display, but is perhaps at the
268 : : "b" of "bar".
269 : : Compare with example B above.
270 : :
271 : : Example D (Fortran frontend)
272 : : ****************************
273 : : x = x + y
274 : : 1 2
275 : : This rich location has range 0 at "1", and range 1 at "2".
276 : : Both are flagged for caret display. Both ranges have start/finish
277 : : equal to their caret point. The frontend overrides the diagnostic
278 : : context's default caret character for these ranges.
279 : :
280 : : Example E (range labels)
281 : : ************************
282 : : printf ("arg0: %i arg1: %s arg2: %i",
283 : : ^~
284 : : |
285 : : const char *
286 : : 100, 101, 102);
287 : : ~~~
288 : : |
289 : : int
290 : : This rich location has two ranges:
291 : : - range 0 is at the "%s" with start = caret = "%" and finish at
292 : : the "s". It has a range_label ("const char *").
293 : : - range 1 has start/finish covering the "101" and is not flagged for
294 : : caret printing. The caret is at the start of "101", where its
295 : : range_label is printed ("int").
296 : :
297 : : Fix-it hints
298 : : ------------
299 : :
300 : : Rich locations can also contain "fix-it hints", giving suggestions
301 : : for the user on how to edit their code to fix a problem. These
302 : : can be expressed as insertions, replacements, and removals of text.
303 : : The edits by default are relative to the zeroth range within the
304 : : rich_location, but optionally they can be expressed relative to
305 : : other locations (using various overloaded methods of the form
306 : : rich_location::add_fixit_*).
307 : :
308 : : For example:
309 : :
310 : : Example F: fix-it hint: insert_before
311 : : *************************************
312 : : ptr = arr[0];
313 : : ^~~~~~
314 : : &
315 : : This rich location has a single range (range 0) covering "arr[0]",
316 : : with the caret at the start. The rich location has a single
317 : : insertion fix-it hint, inserted before range 0, added via
318 : : richloc.add_fixit_insert_before ("&");
319 : :
320 : : Example G: multiple fix-it hints: insert_before and insert_after
321 : : ****************************************************************
322 : : #define FN(ARG0, ARG1, ARG2) fn(ARG0, ARG1, ARG2)
323 : : ^~~~ ^~~~ ^~~~
324 : : ( ) ( ) ( )
325 : : This rich location has three ranges, covering "arg0", "arg1",
326 : : and "arg2", all with caret-printing enabled.
327 : : The rich location has 6 insertion fix-it hints: each arg
328 : : has a pair of insertion fix-it hints, suggesting wrapping
329 : : them with parentheses: one a '(' inserted before,
330 : : the other a ')' inserted after, added via
331 : : richloc.add_fixit_insert_before (LOC, "(");
332 : : and
333 : : richloc.add_fixit_insert_after (LOC, ")");
334 : :
335 : : Example H: fix-it hint: removal
336 : : *******************************
337 : : struct s {int i};;
338 : : ^
339 : : -
340 : : This rich location has a single range at the stray trailing
341 : : semicolon, along with a single removal fix-it hint, covering
342 : : the same range, added via:
343 : : richloc.add_fixit_remove ();
344 : :
345 : : Example I: fix-it hint: replace
346 : : *******************************
347 : : c = s.colour;
348 : : ^~~~~~
349 : : color
350 : : This rich location has a single range (range 0) covering "colour",
351 : : and a single "replace" fix-it hint, covering the same range,
352 : : added via
353 : : richloc.add_fixit_replace ("color");
354 : :
355 : : Example J: fix-it hint: line insertion
356 : : **************************************
357 : :
358 : : 3 | #include <stddef.h>
359 : : + |+#include <stdio.h>
360 : : 4 | int the_next_line;
361 : :
362 : : This rich location has a single range at line 4 column 1, marked
363 : : with SHOW_LINES_WITHOUT_RANGE (to avoid printing a meaningless caret
364 : : on the "i" of int). It has a insertion fix-it hint of the string
365 : : "#include <stdio.h>\n".
366 : :
367 : : Adding a fix-it hint can fail: for example, attempts to insert content
368 : : at the transition between two line maps may fail due to there being no
369 : : location_t value to express the new location.
370 : :
371 : : Attempts to add a fix-it hint within a macro expansion will fail.
372 : :
373 : : There is only limited support for newline characters in fix-it hints:
374 : : only hints with newlines which insert an entire new line are permitted,
375 : : inserting at the start of a line, and finishing with a newline
376 : : (with no interior newline characters). Other attempts to add
377 : : fix-it hints containing newline characters will fail.
378 : : Similarly, attempts to delete or replace a range *affecting* multiple
379 : : lines will fail.
380 : :
381 : : The rich_location API handles these failures gracefully, so that
382 : : diagnostics can attempt to add fix-it hints without each needing
383 : : extensive checking.
384 : :
385 : : Fix-it hints within a rich_location are "atomic": if any hints can't
386 : : be applied, none of them will be (tracked by the m_seen_impossible_fixit
387 : : flag), and no fix-its hints will be displayed for that rich_location.
388 : : This implies that diagnostic messages need to be worded in such a way
389 : : that they make sense whether or not the fix-it hints are displayed,
390 : : or that richloc.seen_impossible_fixit_p () should be checked before
391 : : issuing the diagnostics. */
392 : :
393 : : class rich_location
394 : : {
395 : : public:
396 : : /* Constructors. */
397 : :
398 : : /* Constructing from a location. */
399 : : rich_location (line_maps *set, location_t loc,
400 : : const range_label *label = nullptr,
401 : : const char *label_highlight_color = nullptr);
402 : :
403 : : /* Destructor. */
404 : : ~rich_location ();
405 : :
406 : : rich_location (const rich_location &);
407 : : rich_location (rich_location &&) = delete;
408 : : rich_location &operator= (const rich_location &) = delete;
409 : : rich_location &operator= (rich_location &&) = delete;
410 : :
411 : : /* Accessors. */
412 : 93924681 : location_t get_loc () const { return get_loc (0); }
413 : : location_t get_loc (unsigned int idx) const;
414 : :
415 : : void set_highlight_color (const char *highlight_color);
416 : :
417 : : void
418 : : add_range (location_t loc,
419 : : enum range_display_kind range_display_kind
420 : : = SHOW_RANGE_WITHOUT_CARET,
421 : : const range_label *label = nullptr,
422 : : const char *highlight_color = nullptr);
423 : :
424 : : void
425 : : set_range (unsigned int idx, location_t loc,
426 : : enum range_display_kind range_display_kind,
427 : : const char *highlight_color = nullptr);
428 : :
429 : 1399154 : unsigned int get_num_locations () const { return m_ranges.count (); }
430 : :
431 : : const location_range *get_range (unsigned int idx) const;
432 : : location_range *get_range (unsigned int idx);
433 : :
434 : : expanded_location get_expanded_location (unsigned int idx) const;
435 : :
436 : : void
437 : : override_column (int column);
438 : :
439 : : /* Fix-it hints. */
440 : :
441 : : /* Methods for adding insertion fix-it hints. */
442 : :
443 : : /* Suggest inserting NEW_CONTENT immediately before the primary
444 : : range's start. */
445 : : void
446 : : add_fixit_insert_before (const char *new_content);
447 : :
448 : : /* Suggest inserting NEW_CONTENT immediately before the start of WHERE. */
449 : : void
450 : : add_fixit_insert_before (location_t where,
451 : : const char *new_content);
452 : :
453 : : /* Suggest inserting NEW_CONTENT immediately after the end of the primary
454 : : range. */
455 : : void
456 : : add_fixit_insert_after (const char *new_content);
457 : :
458 : : /* Suggest inserting NEW_CONTENT immediately after the end of WHERE. */
459 : : void
460 : : add_fixit_insert_after (location_t where,
461 : : const char *new_content);
462 : :
463 : : /* Methods for adding removal fix-it hints. */
464 : :
465 : : /* Suggest removing the content covered by range 0. */
466 : : void
467 : : add_fixit_remove ();
468 : :
469 : : /* Suggest removing the content covered between the start and finish
470 : : of WHERE. */
471 : : void
472 : : add_fixit_remove (location_t where);
473 : :
474 : : /* Suggest removing the content covered by SRC_RANGE. */
475 : : void
476 : : add_fixit_remove (source_range src_range);
477 : :
478 : : /* Methods for adding "replace" fix-it hints. */
479 : :
480 : : /* Suggest replacing the content covered by range 0 with NEW_CONTENT. */
481 : : void
482 : : add_fixit_replace (const char *new_content);
483 : :
484 : : /* Suggest replacing the content between the start and finish of
485 : : WHERE with NEW_CONTENT. */
486 : : void
487 : : add_fixit_replace (location_t where,
488 : : const char *new_content);
489 : :
490 : : /* Suggest replacing the content covered by SRC_RANGE with
491 : : NEW_CONTENT. */
492 : : void
493 : : add_fixit_replace (source_range src_range,
494 : : const char *new_content);
495 : :
496 : 124537 : unsigned int get_num_fixit_hints () const { return m_fixit_hints.count (); }
497 : 19304 : fixit_hint *get_fixit_hint (int idx) const { return m_fixit_hints[idx]; }
498 : : fixit_hint *get_last_fixit_hint () const;
499 : 13725 : bool seen_impossible_fixit_p () const { return m_seen_impossible_fixit; }
500 : :
501 : : /* Set this if the fix-it hints are not suitable to be
502 : : automatically applied.
503 : :
504 : : For example, if you are suggesting more than one
505 : : mutually exclusive solution to a problem, then
506 : : it doesn't make sense to apply all of the solutions;
507 : : manual intervention is required.
508 : :
509 : : If set, then the fix-it hints in the rich_location will
510 : : be printed, but will not be added to generated patches,
511 : : or affect the modified version of the file. */
512 : 140 : void fixits_cannot_be_auto_applied ()
513 : : {
514 : 140 : m_fixits_cannot_be_auto_applied = true;
515 : : }
516 : :
517 : 60 : bool fixits_can_be_auto_applied_p () const
518 : : {
519 : 60 : return !m_fixits_cannot_be_auto_applied;
520 : : }
521 : :
522 : : /* An optional path through the code. */
523 : 330198 : const diagnostic_path *get_path () const { return m_path; }
524 : 3953 : void set_path (const diagnostic_path *path) { m_path = path; }
525 : :
526 : : /* A flag for hinting that the diagnostic involves character encoding
527 : : issues, and thus that it will be helpful to the user if we show some
528 : : representation of how the characters in the pertinent source lines
529 : : are encoded.
530 : : The default is false (i.e. do not escape).
531 : : When set to true, non-ASCII bytes in the pertinent source lines will
532 : : be escaped in a manner controlled by the user-supplied option
533 : : -fdiagnostics-escape-format=, so that the user can better understand
534 : : what's going on with the encoding in their source file. */
535 : 99312 : bool escape_on_output_p () const { return m_escape_on_output; }
536 : 468 : void set_escape_on_output (bool flag) { m_escape_on_output = flag; }
537 : :
538 : 48845 : const line_maps *get_line_table () const { return m_line_table; }
539 : :
540 : 1027 : int get_column_override () const { return m_column_override; }
541 : :
542 : : private:
543 : : bool reject_impossible_fixit (location_t where);
544 : : void stop_supporting_fixits ();
545 : : void maybe_add_fixit (location_t start,
546 : : location_t next_loc,
547 : : const char *new_content);
548 : :
549 : : public:
550 : : static const int STATICALLY_ALLOCATED_RANGES = 3;
551 : :
552 : : protected:
553 : : line_maps * const m_line_table;
554 : : semi_embedded_vec <location_range, STATICALLY_ALLOCATED_RANGES> m_ranges;
555 : :
556 : : int m_column_override;
557 : :
558 : : mutable bool m_have_expanded_location;
559 : : bool m_seen_impossible_fixit;
560 : : bool m_fixits_cannot_be_auto_applied;
561 : : bool m_escape_on_output;
562 : :
563 : : mutable expanded_location m_expanded_location;
564 : :
565 : : /* The class manages the memory pointed to by the elements of
566 : : the m_fixit_hints vector. */
567 : : static const int MAX_STATIC_FIXIT_HINTS = 2;
568 : : semi_embedded_vec <fixit_hint *, MAX_STATIC_FIXIT_HINTS> m_fixit_hints;
569 : :
570 : : const diagnostic_path *m_path;
571 : : };
572 : :
573 : : /* Abstract base class for labelling a range within a rich_location
574 : : (e.g. for labelling expressions with their type).
575 : :
576 : : Generating the text could require non-trivial work, so this work
577 : : is delayed (via the "get_text" virtual function) until the diagnostic
578 : : printing code "knows" it needs it, thus avoiding doing it e.g. for
579 : : warnings that are filtered by command-line flags. This virtual
580 : : function also isolates libcpp and the diagnostics subsystem from
581 : : the front-end and middle-end-specific code for generating the text
582 : : for the labels.
583 : :
584 : : Like the rich_location instances they annotate, range_label instances
585 : : are intended to be allocated on the stack when generating diagnostics,
586 : : and to be short-lived. */
587 : :
588 : 10559 : class range_label
589 : : {
590 : : public:
591 : 9180 : virtual ~range_label () {}
592 : :
593 : : /* Get localized text for the label.
594 : : The RANGE_IDX is provided, allowing for range_label instances to be
595 : : shared by multiple ranges if need be (the "flyweight" design pattern). */
596 : : virtual label_text get_text (unsigned range_idx) const = 0;
597 : :
598 : : /* Get any special effects for the label (e.g. links to other labels). */
599 : 8574 : virtual const label_effects *get_effects (unsigned /*range_idx*/) const
600 : : {
601 : 8574 : return nullptr;
602 : : }
603 : : };
604 : :
605 : : /* A fix-it hint: a suggested insertion, replacement, or deletion of text.
606 : : We handle these three types of edit with one class, by representing
607 : : them as replacement of a half-open range:
608 : : [start, next_loc)
609 : : Insertions have start == next_loc: "replace" the empty string at the
610 : : start location with the new string.
611 : : Deletions are replacement with the empty string.
612 : :
613 : : There is only limited support for newline characters in fix-it hints
614 : : as noted above in the comment for class rich_location.
615 : : A fixit_hint instance can have at most one newline character; if
616 : : present, the newline character must be the final character of
617 : : the content (preventing e.g. fix-its that split a pre-existing line). */
618 : :
619 : : class fixit_hint
620 : : {
621 : : public:
622 : : fixit_hint (location_t start,
623 : : location_t next_loc,
624 : : const char *new_content);
625 : : fixit_hint (const fixit_hint &other);
626 : : fixit_hint (fixit_hint &&other) = delete;
627 : : ~fixit_hint () { free (m_bytes); }
628 : : fixit_hint &operator= (const fixit_hint &) = delete;
629 : : fixit_hint &operator= (fixit_hint &&) = delete;
630 : :
631 : : bool affects_line_p (const line_maps *set,
632 : : const char *file,
633 : : int line) const;
634 : 75742 : location_t get_start_loc () const { return m_start; }
635 : 59942 : location_t get_next_loc () const { return m_next_loc; }
636 : : bool maybe_append (location_t start,
637 : : location_t next_loc,
638 : : const char *new_content);
639 : :
640 : 12628 : const char *get_string () const { return m_bytes; }
641 : 39257 : size_t get_length () const { return m_len; }
642 : :
643 : 27683 : bool insertion_p () const { return m_start == m_next_loc; }
644 : :
645 : : bool ends_with_newline_p () const;
646 : :
647 : : private:
648 : : /* We don't use source_range here since, unlike most places,
649 : : this is a half-open/half-closed range:
650 : : [start, next_loc)
651 : : so that we can support insertion via start == next_loc. */
652 : : location_t m_start;
653 : : location_t m_next_loc;
654 : : char *m_bytes;
655 : : size_t m_len;
656 : : };
657 : :
658 : : #endif /* !LIBCPP_RICH_LOCATION_H */
|