163d1a8abSmrg /* Map (unsigned int) keys to (source file, line, column) triples.
2*ec02198aSmrg Copyright (C) 2001-2020 Free Software Foundation, Inc.
363d1a8abSmrg
463d1a8abSmrg This program is free software; you can redistribute it and/or modify it
563d1a8abSmrg under the terms of the GNU General Public License as published by the
663d1a8abSmrg Free Software Foundation; either version 3, or (at your option) any
763d1a8abSmrg later version.
863d1a8abSmrg
963d1a8abSmrg This program is distributed in the hope that it will be useful,
1063d1a8abSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of
1163d1a8abSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1263d1a8abSmrg GNU General Public License for more details.
1363d1a8abSmrg
1463d1a8abSmrg You should have received a copy of the GNU General Public License
1563d1a8abSmrg along with this program; see the file COPYING3. If not see
1663d1a8abSmrg <http://www.gnu.org/licenses/>.
1763d1a8abSmrg
1863d1a8abSmrg In other words, you are welcome to use, share and improve this program.
1963d1a8abSmrg You are forbidden to forbid anyone else to use, share and improve
2063d1a8abSmrg what you give them. Help stamp out software-hoarding! */
2163d1a8abSmrg
2263d1a8abSmrg #ifndef LIBCPP_LINE_MAP_H
2363d1a8abSmrg #define LIBCPP_LINE_MAP_H
2463d1a8abSmrg
2563d1a8abSmrg #ifndef GTY
2663d1a8abSmrg #define GTY(x) /* nothing */
2763d1a8abSmrg #endif
2863d1a8abSmrg
29c7a68eb7Smrg /* Both gcc and emacs number source *lines* starting at 1, but
30c7a68eb7Smrg they have differing conventions for *columns*.
31c7a68eb7Smrg
32c7a68eb7Smrg GCC uses a 1-based convention for source columns,
33c7a68eb7Smrg whereas Emacs's M-x column-number-mode uses a 0-based convention.
34c7a68eb7Smrg
35c7a68eb7Smrg For example, an error in the initial, left-hand
36c7a68eb7Smrg column of source line 3 is reported by GCC as:
37c7a68eb7Smrg
38c7a68eb7Smrg some-file.c:3:1: error: ...etc...
39c7a68eb7Smrg
40c7a68eb7Smrg On navigating to the location of that error in Emacs
41c7a68eb7Smrg (e.g. via "next-error"),
42c7a68eb7Smrg the locus is reported in the Mode Line
43c7a68eb7Smrg (assuming M-x column-number-mode) as:
44c7a68eb7Smrg
45c7a68eb7Smrg some-file.c 10% (3, 0)
46c7a68eb7Smrg
47c7a68eb7Smrg i.e. "3:1:" in GCC corresponds to "(3, 0)" in Emacs. */
48c7a68eb7Smrg
49c7a68eb7Smrg /* The type of line numbers. */
50c7a68eb7Smrg typedef unsigned int linenum_type;
51c7a68eb7Smrg
520fc04c29Smrg /* A type for doing arithmetic on line numbers. */
530fc04c29Smrg typedef long long linenum_arith_t;
540fc04c29Smrg
55c7a68eb7Smrg /* A function for for use by qsort for comparing line numbers. */
56c7a68eb7Smrg
compare(linenum_type lhs,linenum_type rhs)57c7a68eb7Smrg inline int compare (linenum_type lhs, linenum_type rhs)
58c7a68eb7Smrg {
590fc04c29Smrg /* Avoid truncation issues by using linenum_arith_t for the comparison,
60c7a68eb7Smrg and only consider the sign of the result. */
610fc04c29Smrg linenum_arith_t diff = (linenum_arith_t)lhs - (linenum_arith_t)rhs;
62c7a68eb7Smrg if (diff)
63c7a68eb7Smrg return diff > 0 ? 1 : -1;
64c7a68eb7Smrg return 0;
65c7a68eb7Smrg }
66c7a68eb7Smrg
670fc04c29Smrg /* Reason for creating a new line map with linemap_add. */
6863d1a8abSmrg enum lc_reason
6963d1a8abSmrg {
700fc04c29Smrg LC_ENTER = 0, /* Begin #include. */
710fc04c29Smrg LC_LEAVE, /* Return to including file. */
720fc04c29Smrg LC_RENAME, /* Other reason for name change. */
730fc04c29Smrg LC_RENAME_VERBATIM, /* Likewise, but "" != stdin. */
740fc04c29Smrg LC_ENTER_MACRO, /* Begin macro expansion. */
7563d1a8abSmrg /* FIXME: add support for stringize and paste. */
760fc04c29Smrg LC_HWM /* High Water Mark. */
7763d1a8abSmrg };
7863d1a8abSmrg
790fc04c29Smrg /* The typedef "location_t" is a key within the location database,
8063d1a8abSmrg identifying a source location or macro expansion, along with range
8163d1a8abSmrg information, and (optionally) a pointer for use by gcc.
8263d1a8abSmrg
8363d1a8abSmrg This key only has meaning in relation to a line_maps instance. Within
8463d1a8abSmrg gcc there is a single line_maps instance: "line_table", declared in
8563d1a8abSmrg gcc/input.h and defined in gcc/input.c.
8663d1a8abSmrg
8763d1a8abSmrg The values of the keys are intended to be internal to libcpp,
8863d1a8abSmrg but for ease-of-understanding the implementation, they are currently
8963d1a8abSmrg assigned as follows:
9063d1a8abSmrg
9163d1a8abSmrg Actual | Value | Meaning
9263d1a8abSmrg -----------+-------------------------------+-------------------------------
9363d1a8abSmrg 0x00000000 | UNKNOWN_LOCATION (gcc/input.h)| Unknown/invalid location.
9463d1a8abSmrg -----------+-------------------------------+-------------------------------
9563d1a8abSmrg 0x00000001 | BUILTINS_LOCATION | The location for declarations
9663d1a8abSmrg | (gcc/input.h) | in "<built-in>"
9763d1a8abSmrg -----------+-------------------------------+-------------------------------
9863d1a8abSmrg 0x00000002 | RESERVED_LOCATION_COUNT | The first location to be
9963d1a8abSmrg | (also | handed out, and the
10063d1a8abSmrg | ordmap[0]->start_location) | first line in ordmap 0
10163d1a8abSmrg -----------+-------------------------------+-------------------------------
10263d1a8abSmrg | ordmap[1]->start_location | First line in ordmap 1
10363d1a8abSmrg | ordmap[1]->start_location+32 | First column in that line
10463d1a8abSmrg | (assuming range_bits == 5) |
10563d1a8abSmrg | ordmap[1]->start_location+64 | 2nd column in that line
10663d1a8abSmrg | ordmap[1]->start_location+4096| Second line in ordmap 1
10763d1a8abSmrg | (assuming column_bits == 12)
10863d1a8abSmrg |
10963d1a8abSmrg | Subsequent lines are offset by (1 << column_bits),
11063d1a8abSmrg | e.g. 4096 for 12 bits, with a column value of 0 representing
11163d1a8abSmrg | "the whole line".
11263d1a8abSmrg |
11363d1a8abSmrg | Within a line, the low "range_bits" (typically 5) are used for
11463d1a8abSmrg | storing short ranges, so that there's an offset of
11563d1a8abSmrg | (1 << range_bits) between individual columns within a line,
11663d1a8abSmrg | typically 32.
11763d1a8abSmrg | The low range_bits store the offset of the end point from the
11863d1a8abSmrg | start point, and the start point is found by masking away
11963d1a8abSmrg | the range bits.
12063d1a8abSmrg |
12163d1a8abSmrg | For example:
12263d1a8abSmrg | ordmap[1]->start_location+64 "2nd column in that line"
12363d1a8abSmrg | above means a caret at that location, with a range
12463d1a8abSmrg | starting and finishing at the same place (the range bits
12563d1a8abSmrg | are 0), a range of length 1.
12663d1a8abSmrg |
12763d1a8abSmrg | By contrast:
12863d1a8abSmrg | ordmap[1]->start_location+68
12963d1a8abSmrg | has range bits 0x4, meaning a caret with a range starting at
13063d1a8abSmrg | that location, but with endpoint 4 columns further on: a range
13163d1a8abSmrg | of length 5.
13263d1a8abSmrg |
13363d1a8abSmrg | Ranges that have caret != start, or have an endpoint too
13463d1a8abSmrg | far away to fit in range_bits are instead stored as ad-hoc
13563d1a8abSmrg | locations. Hence for range_bits == 5 we can compactly store
13663d1a8abSmrg | tokens of length <= 32 without needing to use the ad-hoc
13763d1a8abSmrg | table.
13863d1a8abSmrg |
13963d1a8abSmrg | This packing scheme means we effectively have
14063d1a8abSmrg | (column_bits - range_bits)
14163d1a8abSmrg | of bits for the columns, typically (12 - 5) = 7, for 128
14263d1a8abSmrg | columns; longer line widths are accomodated by starting a
14363d1a8abSmrg | new ordmap with a higher column_bits.
14463d1a8abSmrg |
14563d1a8abSmrg | ordmap[2]->start_location-1 | Final location in ordmap 1
14663d1a8abSmrg -----------+-------------------------------+-------------------------------
14763d1a8abSmrg | ordmap[2]->start_location | First line in ordmap 2
14863d1a8abSmrg | ordmap[3]->start_location-1 | Final location in ordmap 2
14963d1a8abSmrg -----------+-------------------------------+-------------------------------
15063d1a8abSmrg | | (etc)
15163d1a8abSmrg -----------+-------------------------------+-------------------------------
15263d1a8abSmrg | ordmap[n-1]->start_location | First line in final ord map
15363d1a8abSmrg | | (etc)
15463d1a8abSmrg | set->highest_location - 1 | Final location in that ordmap
15563d1a8abSmrg -----------+-------------------------------+-------------------------------
15663d1a8abSmrg | set->highest_location | Location of the where the next
15763d1a8abSmrg | | ordinary linemap would start
15863d1a8abSmrg -----------+-------------------------------+-------------------------------
15963d1a8abSmrg | |
16063d1a8abSmrg | VVVVVVVVVVVVVVVVVVVVVVVVVVV
16163d1a8abSmrg | Ordinary maps grow this way
16263d1a8abSmrg |
16363d1a8abSmrg | (unallocated integers)
16463d1a8abSmrg |
16563d1a8abSmrg 0x60000000 | LINE_MAP_MAX_LOCATION_WITH_COLS
16663d1a8abSmrg | Beyond this point, ordinary linemaps have 0 bits per column:
16763d1a8abSmrg | each increment of the value corresponds to a new source line.
16863d1a8abSmrg |
1690fc04c29Smrg 0x70000000 | LINE_MAP_MAX_LOCATION
17063d1a8abSmrg | Beyond the point, we give up on ordinary maps; attempts to
17163d1a8abSmrg | create locations in them lead to UNKNOWN_LOCATION (0).
17263d1a8abSmrg |
17363d1a8abSmrg | (unallocated integers)
17463d1a8abSmrg |
17563d1a8abSmrg | Macro maps grow this way
17663d1a8abSmrg | ^^^^^^^^^^^^^^^^^^^^^^^^
17763d1a8abSmrg | |
17863d1a8abSmrg -----------+-------------------------------+-------------------------------
17963d1a8abSmrg | LINEMAPS_MACRO_LOWEST_LOCATION| Locations within macro maps
18063d1a8abSmrg | macromap[m-1]->start_location | Start of last macro map
18163d1a8abSmrg | |
18263d1a8abSmrg -----------+-------------------------------+-------------------------------
18363d1a8abSmrg | macromap[m-2]->start_location | Start of penultimate macro map
18463d1a8abSmrg -----------+-------------------------------+-------------------------------
18563d1a8abSmrg | macromap[1]->start_location | Start of macro map 1
18663d1a8abSmrg -----------+-------------------------------+-------------------------------
18763d1a8abSmrg | macromap[0]->start_location | Start of macro map 0
1880fc04c29Smrg 0x7fffffff | MAX_LOCATION_T | Also used as a mask for
18963d1a8abSmrg | | accessing the ad-hoc data table
19063d1a8abSmrg -----------+-------------------------------+-------------------------------
19163d1a8abSmrg 0x80000000 | Start of ad-hoc values; the lower 31 bits are used as an index
19263d1a8abSmrg ... | into the line_table->location_adhoc_data_map.data array.
19363d1a8abSmrg 0xffffffff | UINT_MAX |
19463d1a8abSmrg -----------+-------------------------------+-------------------------------
19563d1a8abSmrg
19663d1a8abSmrg Examples of location encoding.
19763d1a8abSmrg
19863d1a8abSmrg Packed ranges
19963d1a8abSmrg =============
20063d1a8abSmrg
20163d1a8abSmrg Consider encoding the location of a token "foo", seen underlined here
20263d1a8abSmrg on line 523, within an ordinary line_map that starts at line 500:
20363d1a8abSmrg
20463d1a8abSmrg 11111111112
20563d1a8abSmrg 12345678901234567890
20663d1a8abSmrg 522
20763d1a8abSmrg 523 return foo + bar;
20863d1a8abSmrg ^~~
20963d1a8abSmrg 524
21063d1a8abSmrg
21163d1a8abSmrg The location's caret and start are both at line 523, column 11; the
21263d1a8abSmrg location's finish is on the same line, at column 13 (an offset of 2
21363d1a8abSmrg columns, for length 3).
21463d1a8abSmrg
21563d1a8abSmrg Line 523 is offset 23 from the starting line of the ordinary line_map.
21663d1a8abSmrg
21763d1a8abSmrg caret == start, and the offset of the finish fits within 5 bits, so
21863d1a8abSmrg this can be stored as a packed range.
21963d1a8abSmrg
22063d1a8abSmrg This is encoded as:
22163d1a8abSmrg ordmap->start
22263d1a8abSmrg + (line_offset << ordmap->m_column_and_range_bits)
22363d1a8abSmrg + (column << ordmap->m_range_bits)
22463d1a8abSmrg + (range_offset);
22563d1a8abSmrg i.e. (for line offset 23, column 11, range offset 2):
22663d1a8abSmrg ordmap->start
22763d1a8abSmrg + (23 << 12)
22863d1a8abSmrg + (11 << 5)
22963d1a8abSmrg + 2;
23063d1a8abSmrg i.e.:
23163d1a8abSmrg ordmap->start + 0x17162
23263d1a8abSmrg assuming that the line_map uses the default of 7 bits for columns and
23363d1a8abSmrg 5 bits for packed range (giving 12 bits for m_column_and_range_bits).
23463d1a8abSmrg
23563d1a8abSmrg
23663d1a8abSmrg "Pure" locations
23763d1a8abSmrg ================
23863d1a8abSmrg
23963d1a8abSmrg These are a special case of the above, where
24063d1a8abSmrg caret == start == finish
24163d1a8abSmrg They are stored as packed ranges with offset == 0.
24263d1a8abSmrg For example, the location of the "f" of "foo" could be stored
24363d1a8abSmrg as above, but with range offset 0, giving:
24463d1a8abSmrg ordmap->start
24563d1a8abSmrg + (23 << 12)
24663d1a8abSmrg + (11 << 5)
24763d1a8abSmrg + 0;
24863d1a8abSmrg i.e.:
24963d1a8abSmrg ordmap->start + 0x17160
25063d1a8abSmrg
25163d1a8abSmrg
25263d1a8abSmrg Unoptimized ranges
25363d1a8abSmrg ==================
25463d1a8abSmrg
25563d1a8abSmrg Consider encoding the location of the binary expression
25663d1a8abSmrg below:
25763d1a8abSmrg
25863d1a8abSmrg 11111111112
25963d1a8abSmrg 12345678901234567890
26063d1a8abSmrg 522
26163d1a8abSmrg 523 return foo + bar;
26263d1a8abSmrg ~~~~^~~~~
26363d1a8abSmrg 524
26463d1a8abSmrg
26563d1a8abSmrg The location's caret is at the "+", line 523 column 15, but starts
26663d1a8abSmrg earlier, at the "f" of "foo" at column 11. The finish is at the "r"
26763d1a8abSmrg of "bar" at column 19.
26863d1a8abSmrg
26963d1a8abSmrg This can't be stored as a packed range since start != caret.
27063d1a8abSmrg Hence it is stored as an ad-hoc location e.g. 0x80000003.
27163d1a8abSmrg
27263d1a8abSmrg Stripping off the top bit gives us an index into the ad-hoc
27363d1a8abSmrg lookaside table:
27463d1a8abSmrg
27563d1a8abSmrg line_table->location_adhoc_data_map.data[0x3]
27663d1a8abSmrg
27763d1a8abSmrg from which the caret, start and finish can be looked up,
27863d1a8abSmrg encoded as "pure" locations:
27963d1a8abSmrg
28063d1a8abSmrg start == ordmap->start + (23 << 12) + (11 << 5)
28163d1a8abSmrg == ordmap->start + 0x17160 (as above; the "f" of "foo")
28263d1a8abSmrg
28363d1a8abSmrg caret == ordmap->start + (23 << 12) + (15 << 5)
28463d1a8abSmrg == ordmap->start + 0x171e0
28563d1a8abSmrg
28663d1a8abSmrg finish == ordmap->start + (23 << 12) + (19 << 5)
28763d1a8abSmrg == ordmap->start + 0x17260
28863d1a8abSmrg
2890fc04c29Smrg To further see how location_t works in practice, see the
29063d1a8abSmrg worked example in libcpp/location-example.txt. */
2910fc04c29Smrg typedef unsigned int location_t;
29263d1a8abSmrg
293c7a68eb7Smrg /* Do not track column numbers higher than this one. As a result, the
294c7a68eb7Smrg range of column_bits is [12, 18] (or 0 if column numbers are
295c7a68eb7Smrg disabled). */
296c7a68eb7Smrg const unsigned int LINE_MAP_MAX_COLUMN_NUMBER = (1U << 12);
297c7a68eb7Smrg
29863d1a8abSmrg /* Do not pack ranges if locations get higher than this.
29963d1a8abSmrg If you change this, update:
30063d1a8abSmrg gcc.dg/plugin/location-overflow-test-*.c. */
3010fc04c29Smrg const location_t LINE_MAP_MAX_LOCATION_WITH_PACKED_RANGES = 0x50000000;
30263d1a8abSmrg
30363d1a8abSmrg /* Do not track column numbers if locations get higher than this.
30463d1a8abSmrg If you change this, update:
30563d1a8abSmrg gcc.dg/plugin/location-overflow-test-*.c. */
3060fc04c29Smrg const location_t LINE_MAP_MAX_LOCATION_WITH_COLS = 0x60000000;
3070fc04c29Smrg
3080fc04c29Smrg /* Highest possible source location encoded within an ordinary map. */
3090fc04c29Smrg const location_t LINE_MAP_MAX_LOCATION = 0x70000000;
31063d1a8abSmrg
31163d1a8abSmrg /* A range of source locations.
31263d1a8abSmrg
31363d1a8abSmrg Ranges are closed:
31463d1a8abSmrg m_start is the first location within the range,
31563d1a8abSmrg m_finish is the last location within the range.
31663d1a8abSmrg
31763d1a8abSmrg We may need a more compact way to store these, but for now,
31863d1a8abSmrg let's do it the simple way, as a pair. */
31963d1a8abSmrg struct GTY(()) source_range
32063d1a8abSmrg {
3210fc04c29Smrg location_t m_start;
3220fc04c29Smrg location_t m_finish;
32363d1a8abSmrg
32463d1a8abSmrg /* We avoid using constructors, since various structs that
32563d1a8abSmrg don't yet have constructors will embed instances of
32663d1a8abSmrg source_range. */
32763d1a8abSmrg
3280fc04c29Smrg /* Make a source_range from a location_t. */
from_locationsource_range3290fc04c29Smrg static source_range from_location (location_t loc)
33063d1a8abSmrg {
33163d1a8abSmrg source_range result;
33263d1a8abSmrg result.m_start = loc;
33363d1a8abSmrg result.m_finish = loc;
33463d1a8abSmrg return result;
33563d1a8abSmrg }
33663d1a8abSmrg
3370fc04c29Smrg /* Make a source_range from a pair of location_t. */
from_locationssource_range3380fc04c29Smrg static source_range from_locations (location_t start,
3390fc04c29Smrg location_t finish)
34063d1a8abSmrg {
34163d1a8abSmrg source_range result;
34263d1a8abSmrg result.m_start = start;
34363d1a8abSmrg result.m_finish = finish;
34463d1a8abSmrg return result;
34563d1a8abSmrg }
34663d1a8abSmrg };
34763d1a8abSmrg
34863d1a8abSmrg /* Memory allocation function typedef. Works like xrealloc. */
34963d1a8abSmrg typedef void *(*line_map_realloc) (void *, size_t);
35063d1a8abSmrg
35163d1a8abSmrg /* Memory allocator function that returns the actual allocated size,
35263d1a8abSmrg for a given requested allocation. */
35363d1a8abSmrg typedef size_t (*line_map_round_alloc_size_func) (size_t);
35463d1a8abSmrg
35563d1a8abSmrg /* A line_map encodes a sequence of locations.
35663d1a8abSmrg There are two kinds of maps. Ordinary maps and macro expansion
35763d1a8abSmrg maps, a.k.a macro maps.
35863d1a8abSmrg
35963d1a8abSmrg A macro map encodes source locations of tokens that are part of a
36063d1a8abSmrg macro replacement-list, at a macro expansion point. E.g, in:
36163d1a8abSmrg
36263d1a8abSmrg #define PLUS(A,B) A + B
36363d1a8abSmrg
36463d1a8abSmrg No macro map is going to be created there, because we are not at a
36563d1a8abSmrg macro expansion point. We are at a macro /definition/ point. So the
36663d1a8abSmrg locations of the tokens of the macro replacement-list (i.e, A + B)
36763d1a8abSmrg will be locations in an ordinary map, not a macro map.
36863d1a8abSmrg
36963d1a8abSmrg On the other hand, if we later do:
37063d1a8abSmrg
37163d1a8abSmrg int a = PLUS (1,2);
37263d1a8abSmrg
37363d1a8abSmrg The invocation of PLUS here is a macro expansion. So we are at a
37463d1a8abSmrg macro expansion point. The preprocessor expands PLUS (1,2) and
37563d1a8abSmrg replaces it with the tokens of its replacement-list: 1 + 2. A macro
37663d1a8abSmrg map is going to be created to hold (or rather to map, haha ...) the
37763d1a8abSmrg locations of the tokens 1, + and 2. The macro map also records the
37863d1a8abSmrg location of the expansion point of PLUS. That location is mapped in
37963d1a8abSmrg the map that is active right before the location of the invocation
38063d1a8abSmrg of PLUS. */
38163d1a8abSmrg
3820fc04c29Smrg /* This contains GTY mark-up to support precompiled headers.
3830fc04c29Smrg line_map is an abstract class, only derived objects exist. */
3840fc04c29Smrg struct GTY((tag ("0"), desc ("MAP_ORDINARY_P (&%h) ? 1 : 2"))) line_map {
3850fc04c29Smrg location_t start_location;
3860fc04c29Smrg
3870fc04c29Smrg /* Size and alignment is (usually) 4 bytes. */
38863d1a8abSmrg };
38963d1a8abSmrg
39063d1a8abSmrg /* An ordinary line map encodes physical source locations. Those
39163d1a8abSmrg physical source locations are called "spelling locations".
39263d1a8abSmrg
39363d1a8abSmrg Physical source file TO_FILE at line TO_LINE at column 0 is represented
39463d1a8abSmrg by the logical START_LOCATION. TO_LINE+L at column C is represented by
39563d1a8abSmrg START_LOCATION+(L*(1<<m_column_and_range_bits))+(C*1<<m_range_bits), as
39663d1a8abSmrg long as C<(1<<effective range bits), and the result_location is less than
39763d1a8abSmrg the next line_map's start_location.
39863d1a8abSmrg (The top line is line 1 and the leftmost column is column 1; line/column 0
39963d1a8abSmrg means "entire file/line" or "unknown line/column" or "not applicable".)
40063d1a8abSmrg
4010fc04c29Smrg The highest possible source location is MAX_LOCATION_T. */
40263d1a8abSmrg struct GTY((tag ("1"))) line_map_ordinary : public line_map {
4030fc04c29Smrg /* Base class is 4 bytes. */
40463d1a8abSmrg
4050fc04c29Smrg /* 4 bytes of integers, each 1 byte for easy extraction/insertion. */
4060fc04c29Smrg
4070fc04c29Smrg /* The reason for creation of this line map. */
4080fc04c29Smrg ENUM_BITFIELD (lc_reason) reason : 8;
40963d1a8abSmrg
41063d1a8abSmrg /* SYSP is one for a system header, two for a C system header file
41163d1a8abSmrg that therefore needs to be extern "C" protected in C++, and zero
41263d1a8abSmrg otherwise. This field isn't really needed now that it's in
41363d1a8abSmrg cpp_buffer. */
41463d1a8abSmrg unsigned char sysp;
41563d1a8abSmrg
4160fc04c29Smrg /* Number of the low-order location_t bits used for column numbers
41763d1a8abSmrg and ranges. */
41863d1a8abSmrg unsigned int m_column_and_range_bits : 8;
41963d1a8abSmrg
42063d1a8abSmrg /* Number of the low-order "column" bits used for storing short ranges
42163d1a8abSmrg inline, rather than in the ad-hoc table.
42263d1a8abSmrg MSB LSB
42363d1a8abSmrg 31 0
42463d1a8abSmrg +-------------------------+-------------------------------------------+
42563d1a8abSmrg | |<---map->column_and_range_bits (e.g. 12)-->|
42663d1a8abSmrg +-------------------------+-----------------------+-------------------+
42763d1a8abSmrg | | column_and_range_bits | map->range_bits |
42863d1a8abSmrg | | - range_bits | |
42963d1a8abSmrg +-------------------------+-----------------------+-------------------+
43063d1a8abSmrg | row bits | effective column bits | short range bits |
43163d1a8abSmrg | | (e.g. 7) | (e.g. 5) |
43263d1a8abSmrg +-------------------------+-----------------------+-------------------+ */
43363d1a8abSmrg unsigned int m_range_bits : 8;
4340fc04c29Smrg
4350fc04c29Smrg /* Pointer alignment boundary on both 32 and 64-bit systems. */
4360fc04c29Smrg
4370fc04c29Smrg const char *to_file;
4380fc04c29Smrg linenum_type to_line;
4390fc04c29Smrg
4400fc04c29Smrg /* Location from whence this line map was included. For regular
4410fc04c29Smrg #includes, this location will be the last location of a map. For
4420fc04c29Smrg outermost file, this is 0. */
4430fc04c29Smrg location_t included_from;
4440fc04c29Smrg
4450fc04c29Smrg /* Size is 20 or 24 bytes, no padding */
44663d1a8abSmrg };
44763d1a8abSmrg
44863d1a8abSmrg /* This is the highest possible source location encoded within an
44963d1a8abSmrg ordinary or macro map. */
4500fc04c29Smrg const location_t MAX_LOCATION_T = 0x7FFFFFFF;
45163d1a8abSmrg
45263d1a8abSmrg struct cpp_hashnode;
45363d1a8abSmrg
45463d1a8abSmrg /* A macro line map encodes location of tokens coming from a macro
45563d1a8abSmrg expansion.
45663d1a8abSmrg
45763d1a8abSmrg The offset from START_LOCATION is used to index into
45863d1a8abSmrg MACRO_LOCATIONS; this holds the original location of the token. */
45963d1a8abSmrg struct GTY((tag ("2"))) line_map_macro : public line_map {
4600fc04c29Smrg /* Base is 4 bytes. */
46163d1a8abSmrg
46263d1a8abSmrg /* The number of tokens inside the replacement-list of MACRO. */
46363d1a8abSmrg unsigned int n_tokens;
46463d1a8abSmrg
4650fc04c29Smrg /* Pointer alignment boundary. */
4660fc04c29Smrg
4670fc04c29Smrg /* The cpp macro whose expansion gave birth to this macro map. */
4680fc04c29Smrg struct cpp_hashnode *
4690fc04c29Smrg GTY ((nested_ptr (union tree_node,
4700fc04c29Smrg "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
4710fc04c29Smrg "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL")))
4720fc04c29Smrg macro;
4730fc04c29Smrg
47463d1a8abSmrg /* This array of location is actually an array of pairs of
47563d1a8abSmrg locations. The elements inside it thus look like:
47663d1a8abSmrg
47763d1a8abSmrg x0,y0, x1,y1, x2,y2, ...., xn,yn.
47863d1a8abSmrg
47963d1a8abSmrg where n == n_tokens;
48063d1a8abSmrg
48163d1a8abSmrg Remember that these xI,yI are collected when libcpp is about to
48263d1a8abSmrg expand a given macro.
48363d1a8abSmrg
48463d1a8abSmrg yI is the location in the macro definition, either of the token
48563d1a8abSmrg itself or of a macro parameter that it replaces.
48663d1a8abSmrg
48763d1a8abSmrg Imagine this:
48863d1a8abSmrg
48963d1a8abSmrg #define PLUS(A, B) A + B <--- #1
49063d1a8abSmrg
49163d1a8abSmrg int a = PLUS (1,2); <--- #2
49263d1a8abSmrg
49363d1a8abSmrg There is a macro map for the expansion of PLUS in #2. PLUS is
49463d1a8abSmrg expanded into its expansion-list. The expansion-list is the
49563d1a8abSmrg replacement-list of PLUS where the macro parameters are replaced
49663d1a8abSmrg with their arguments. So the replacement-list of PLUS is made of
49763d1a8abSmrg the tokens:
49863d1a8abSmrg
49963d1a8abSmrg A, +, B
50063d1a8abSmrg
50163d1a8abSmrg and the expansion-list is made of the tokens:
50263d1a8abSmrg
50363d1a8abSmrg 1, +, 2
50463d1a8abSmrg
50563d1a8abSmrg Let's consider the case of token "+". Its y1 [yI for I == 1] is
50663d1a8abSmrg its spelling location in #1.
50763d1a8abSmrg
50863d1a8abSmrg y0 (thus for token "1") is the spelling location of A in #1.
50963d1a8abSmrg
51063d1a8abSmrg And y2 (of token "2") is the spelling location of B in #1.
51163d1a8abSmrg
51263d1a8abSmrg When the token is /not/ an argument for a macro, xI is the same
51363d1a8abSmrg location as yI. Otherwise, xI is the location of the token
51463d1a8abSmrg outside this macro expansion. If this macro was expanded from
51563d1a8abSmrg another macro expansion, xI is a virtual location representing
51663d1a8abSmrg the token in that macro expansion; otherwise, it is the spelling
51763d1a8abSmrg location of the token.
51863d1a8abSmrg
51963d1a8abSmrg Note that a virtual location is a location returned by
52063d1a8abSmrg linemap_add_macro_token. It encodes the relevant locations (x,y
52163d1a8abSmrg pairs) of that token across the macro expansions from which it
52263d1a8abSmrg (the token) might come from.
52363d1a8abSmrg
52463d1a8abSmrg In the example above x1 (for token "+") is going to be the same
52563d1a8abSmrg as y1. x0 is the spelling location for the argument token "1",
52663d1a8abSmrg and x2 is the spelling location for the argument token "2". */
5270fc04c29Smrg location_t * GTY((atomic)) macro_locations;
52863d1a8abSmrg
52963d1a8abSmrg /* This is the location of the expansion point of the current macro
53063d1a8abSmrg map. It's the location of the macro name. That location is held
53163d1a8abSmrg by the map that was current right before the current one. It
53263d1a8abSmrg could have been either a macro or an ordinary map, depending on
53363d1a8abSmrg if we are in a nested expansion context not. */
5340fc04c29Smrg location_t expansion;
5350fc04c29Smrg
5360fc04c29Smrg /* Size is 20 or 32 (4 bytes padding on 64-bit). */
53763d1a8abSmrg };
53863d1a8abSmrg
53963d1a8abSmrg #if CHECKING_P && (GCC_VERSION >= 2007)
54063d1a8abSmrg
54163d1a8abSmrg /* Assertion macro to be used in line-map code. */
54263d1a8abSmrg #define linemap_assert(EXPR) \
54363d1a8abSmrg do { \
54463d1a8abSmrg if (! (EXPR)) \
54563d1a8abSmrg abort (); \
54663d1a8abSmrg } while (0)
54763d1a8abSmrg
54863d1a8abSmrg /* Assert that becomes a conditional expression when checking is disabled at
54963d1a8abSmrg compilation time. Use this for conditions that should not happen but if
55063d1a8abSmrg they happen, it is better to handle them gracefully rather than crash
55163d1a8abSmrg randomly later.
55263d1a8abSmrg Usage:
55363d1a8abSmrg
55463d1a8abSmrg if (linemap_assert_fails(EXPR)) handle_error(); */
55563d1a8abSmrg #define linemap_assert_fails(EXPR) __extension__ \
55663d1a8abSmrg ({linemap_assert (EXPR); false;})
55763d1a8abSmrg
55863d1a8abSmrg #else
55963d1a8abSmrg /* Include EXPR, so that unused variable warnings do not occur. */
56063d1a8abSmrg #define linemap_assert(EXPR) ((void)(0 && (EXPR)))
56163d1a8abSmrg #define linemap_assert_fails(EXPR) (! (EXPR))
56263d1a8abSmrg #endif
56363d1a8abSmrg
564*ec02198aSmrg /* Get whether location LOC is an ordinary location. */
5650fc04c29Smrg
5660fc04c29Smrg inline bool
IS_ORDINARY_LOC(location_t loc)5670fc04c29Smrg IS_ORDINARY_LOC (location_t loc)
5680fc04c29Smrg {
5690fc04c29Smrg return loc < LINE_MAP_MAX_LOCATION;
5700fc04c29Smrg }
5710fc04c29Smrg
572*ec02198aSmrg /* Get whether location LOC is an ad-hoc location. */
573*ec02198aSmrg
5740fc04c29Smrg inline bool
IS_ADHOC_LOC(location_t loc)5750fc04c29Smrg IS_ADHOC_LOC (location_t loc)
5760fc04c29Smrg {
5770fc04c29Smrg return loc > MAX_LOCATION_T;
5780fc04c29Smrg }
5790fc04c29Smrg
5800fc04c29Smrg /* Categorize line map kinds. */
5810fc04c29Smrg
5820fc04c29Smrg inline bool
MAP_ORDINARY_P(const line_map * map)5830fc04c29Smrg MAP_ORDINARY_P (const line_map *map)
5840fc04c29Smrg {
5850fc04c29Smrg return IS_ORDINARY_LOC (map->start_location);
5860fc04c29Smrg }
5870fc04c29Smrg
58863d1a8abSmrg /* Return TRUE if MAP encodes locations coming from a macro
58963d1a8abSmrg replacement-list at macro expansion point. */
59063d1a8abSmrg bool
591*ec02198aSmrg linemap_macro_expansion_map_p (const line_map *);
59263d1a8abSmrg
59363d1a8abSmrg /* Assert that MAP encodes locations of tokens that are not part of
59463d1a8abSmrg the replacement-list of a macro expansion, downcasting from
59563d1a8abSmrg line_map * to line_map_ordinary *. */
59663d1a8abSmrg
59763d1a8abSmrg inline line_map_ordinary *
linemap_check_ordinary(line_map * map)598*ec02198aSmrg linemap_check_ordinary (line_map *map)
59963d1a8abSmrg {
6000fc04c29Smrg linemap_assert (MAP_ORDINARY_P (map));
60163d1a8abSmrg return (line_map_ordinary *)map;
60263d1a8abSmrg }
60363d1a8abSmrg
60463d1a8abSmrg /* Assert that MAP encodes locations of tokens that are not part of
60563d1a8abSmrg the replacement-list of a macro expansion, downcasting from
60663d1a8abSmrg const line_map * to const line_map_ordinary *. */
60763d1a8abSmrg
60863d1a8abSmrg inline const line_map_ordinary *
linemap_check_ordinary(const line_map * map)609*ec02198aSmrg linemap_check_ordinary (const line_map *map)
61063d1a8abSmrg {
6110fc04c29Smrg linemap_assert (MAP_ORDINARY_P (map));
61263d1a8abSmrg return (const line_map_ordinary *)map;
61363d1a8abSmrg }
61463d1a8abSmrg
61563d1a8abSmrg /* Assert that MAP is a macro expansion and downcast to the appropriate
61663d1a8abSmrg subclass. */
61763d1a8abSmrg
linemap_check_macro(line_map * map)61863d1a8abSmrg inline line_map_macro *linemap_check_macro (line_map *map)
61963d1a8abSmrg {
6200fc04c29Smrg linemap_assert (!MAP_ORDINARY_P (map));
62163d1a8abSmrg return (line_map_macro *)map;
62263d1a8abSmrg }
62363d1a8abSmrg
62463d1a8abSmrg /* Assert that MAP is a macro expansion and downcast to the appropriate
62563d1a8abSmrg subclass. */
62663d1a8abSmrg
62763d1a8abSmrg inline const line_map_macro *
linemap_check_macro(const line_map * map)62863d1a8abSmrg linemap_check_macro (const line_map *map)
62963d1a8abSmrg {
6300fc04c29Smrg linemap_assert (!MAP_ORDINARY_P (map));
63163d1a8abSmrg return (const line_map_macro *)map;
63263d1a8abSmrg }
63363d1a8abSmrg
63463d1a8abSmrg /* Read the start location of MAP. */
63563d1a8abSmrg
6360fc04c29Smrg inline location_t
MAP_START_LOCATION(const line_map * map)63763d1a8abSmrg MAP_START_LOCATION (const line_map *map)
63863d1a8abSmrg {
63963d1a8abSmrg return map->start_location;
64063d1a8abSmrg }
64163d1a8abSmrg
64263d1a8abSmrg /* Get the starting line number of ordinary map MAP. */
64363d1a8abSmrg
64463d1a8abSmrg inline linenum_type
ORDINARY_MAP_STARTING_LINE_NUMBER(const line_map_ordinary * ord_map)64563d1a8abSmrg ORDINARY_MAP_STARTING_LINE_NUMBER (const line_map_ordinary *ord_map)
64663d1a8abSmrg {
64763d1a8abSmrg return ord_map->to_line;
64863d1a8abSmrg }
64963d1a8abSmrg
65063d1a8abSmrg /* Return a positive value if map encodes locations from a system
65163d1a8abSmrg header, 0 otherwise. Returns 1 if ordinary map MAP encodes locations
65263d1a8abSmrg in a system header and 2 if it encodes locations in a C system header
65363d1a8abSmrg that therefore needs to be extern "C" protected in C++. */
65463d1a8abSmrg
65563d1a8abSmrg inline unsigned char
ORDINARY_MAP_IN_SYSTEM_HEADER_P(const line_map_ordinary * ord_map)65663d1a8abSmrg ORDINARY_MAP_IN_SYSTEM_HEADER_P (const line_map_ordinary *ord_map)
65763d1a8abSmrg {
65863d1a8abSmrg return ord_map->sysp;
65963d1a8abSmrg }
66063d1a8abSmrg
66163d1a8abSmrg /* Get the filename of ordinary map MAP. */
66263d1a8abSmrg
66363d1a8abSmrg inline const char *
ORDINARY_MAP_FILE_NAME(const line_map_ordinary * ord_map)66463d1a8abSmrg ORDINARY_MAP_FILE_NAME (const line_map_ordinary *ord_map)
66563d1a8abSmrg {
66663d1a8abSmrg return ord_map->to_file;
66763d1a8abSmrg }
66863d1a8abSmrg
66963d1a8abSmrg /* Get the cpp macro whose expansion gave birth to macro map MAP. */
67063d1a8abSmrg
67163d1a8abSmrg inline cpp_hashnode *
MACRO_MAP_MACRO(const line_map_macro * macro_map)67263d1a8abSmrg MACRO_MAP_MACRO (const line_map_macro *macro_map)
67363d1a8abSmrg {
67463d1a8abSmrg return macro_map->macro;
67563d1a8abSmrg }
67663d1a8abSmrg
67763d1a8abSmrg /* Get the number of tokens inside the replacement-list of the macro
67863d1a8abSmrg that led to macro map MAP. */
67963d1a8abSmrg
68063d1a8abSmrg inline unsigned int
MACRO_MAP_NUM_MACRO_TOKENS(const line_map_macro * macro_map)68163d1a8abSmrg MACRO_MAP_NUM_MACRO_TOKENS (const line_map_macro *macro_map)
68263d1a8abSmrg {
68363d1a8abSmrg return macro_map->n_tokens;
68463d1a8abSmrg }
68563d1a8abSmrg
68663d1a8abSmrg /* Get the array of pairs of locations within macro map MAP.
68763d1a8abSmrg See the declaration of line_map_macro for more information. */
68863d1a8abSmrg
6890fc04c29Smrg inline location_t *
MACRO_MAP_LOCATIONS(const line_map_macro * macro_map)69063d1a8abSmrg MACRO_MAP_LOCATIONS (const line_map_macro *macro_map)
69163d1a8abSmrg {
69263d1a8abSmrg return macro_map->macro_locations;
69363d1a8abSmrg }
69463d1a8abSmrg
69563d1a8abSmrg /* Get the location of the expansion point of the macro map MAP. */
69663d1a8abSmrg
6970fc04c29Smrg inline location_t
MACRO_MAP_EXPANSION_POINT_LOCATION(const line_map_macro * macro_map)69863d1a8abSmrg MACRO_MAP_EXPANSION_POINT_LOCATION (const line_map_macro *macro_map)
69963d1a8abSmrg {
70063d1a8abSmrg return macro_map->expansion;
70163d1a8abSmrg }
70263d1a8abSmrg
70363d1a8abSmrg /* The abstraction of a set of location maps. There can be several
70463d1a8abSmrg types of location maps. This abstraction contains the attributes
70563d1a8abSmrg that are independent from the type of the map.
70663d1a8abSmrg
70763d1a8abSmrg Essentially this is just a vector of T_linemap_subclass,
70863d1a8abSmrg which can only ever grow in size. */
70963d1a8abSmrg
71063d1a8abSmrg struct GTY(()) maps_info_ordinary {
71163d1a8abSmrg /* This array contains the "ordinary" line maps, for all
71263d1a8abSmrg events other than macro expansion
71363d1a8abSmrg (e.g. when a new preprocessing unit starts or ends). */
71463d1a8abSmrg line_map_ordinary * GTY ((length ("%h.used"))) maps;
71563d1a8abSmrg
71663d1a8abSmrg /* The total number of allocated maps. */
71763d1a8abSmrg unsigned int allocated;
71863d1a8abSmrg
71963d1a8abSmrg /* The number of elements used in maps. This number is smaller
72063d1a8abSmrg or equal to ALLOCATED. */
72163d1a8abSmrg unsigned int used;
72263d1a8abSmrg
723*ec02198aSmrg mutable unsigned int cache;
72463d1a8abSmrg };
72563d1a8abSmrg
72663d1a8abSmrg struct GTY(()) maps_info_macro {
72763d1a8abSmrg /* This array contains the macro line maps.
72863d1a8abSmrg A macro line map is created whenever a macro expansion occurs. */
72963d1a8abSmrg line_map_macro * GTY ((length ("%h.used"))) maps;
73063d1a8abSmrg
73163d1a8abSmrg /* The total number of allocated maps. */
73263d1a8abSmrg unsigned int allocated;
73363d1a8abSmrg
73463d1a8abSmrg /* The number of elements used in maps. This number is smaller
73563d1a8abSmrg or equal to ALLOCATED. */
73663d1a8abSmrg unsigned int used;
73763d1a8abSmrg
738*ec02198aSmrg mutable unsigned int cache;
73963d1a8abSmrg };
74063d1a8abSmrg
74163d1a8abSmrg /* Data structure to associate a source_range together with an arbitrary
74263d1a8abSmrg data pointer with a source location. */
74363d1a8abSmrg struct GTY(()) location_adhoc_data {
7440fc04c29Smrg location_t locus;
74563d1a8abSmrg source_range src_range;
74663d1a8abSmrg void * GTY((skip)) data;
74763d1a8abSmrg };
74863d1a8abSmrg
74963d1a8abSmrg struct htab;
75063d1a8abSmrg
75163d1a8abSmrg /* The following data structure encodes a location with some adhoc data
75263d1a8abSmrg and maps it to a new unsigned integer (called an adhoc location)
75363d1a8abSmrg that replaces the original location to represent the mapping.
75463d1a8abSmrg
75563d1a8abSmrg The new adhoc_loc uses the highest bit as the enabling bit, i.e. if the
75663d1a8abSmrg highest bit is 1, then the number is adhoc_loc. Otherwise, it serves as
75763d1a8abSmrg the original location. Once identified as the adhoc_loc, the lower 31
75863d1a8abSmrg bits of the integer is used to index the location_adhoc_data array,
75963d1a8abSmrg in which the locus and associated data is stored. */
76063d1a8abSmrg
76163d1a8abSmrg struct GTY(()) location_adhoc_data_map {
76263d1a8abSmrg struct htab * GTY((skip)) htab;
7630fc04c29Smrg location_t curr_loc;
76463d1a8abSmrg unsigned int allocated;
76563d1a8abSmrg struct location_adhoc_data GTY((length ("%h.allocated"))) *data;
76663d1a8abSmrg };
76763d1a8abSmrg
76863d1a8abSmrg /* A set of chronological line_map structures. */
class()769*ec02198aSmrg class GTY(()) line_maps {
770*ec02198aSmrg public:
77163d1a8abSmrg
77263d1a8abSmrg ~line_maps ();
77363d1a8abSmrg
77463d1a8abSmrg maps_info_ordinary info_ordinary;
77563d1a8abSmrg
77663d1a8abSmrg maps_info_macro info_macro;
77763d1a8abSmrg
77863d1a8abSmrg /* Depth of the include stack, including the current file. */
77963d1a8abSmrg unsigned int depth;
78063d1a8abSmrg
78163d1a8abSmrg /* If true, prints an include trace a la -H. */
78263d1a8abSmrg bool trace_includes;
78363d1a8abSmrg
7840fc04c29Smrg /* Highest location_t "given out". */
7850fc04c29Smrg location_t highest_location;
78663d1a8abSmrg
7870fc04c29Smrg /* Start of line of highest location_t "given out". */
7880fc04c29Smrg location_t highest_line;
78963d1a8abSmrg
79063d1a8abSmrg /* The maximum column number we can quickly allocate. Higher numbers
79163d1a8abSmrg may require allocating a new line_map. */
79263d1a8abSmrg unsigned int max_column_hint;
79363d1a8abSmrg
7940fc04c29Smrg /* The allocator to use when resizing 'maps', defaults to xrealloc. */
79563d1a8abSmrg line_map_realloc reallocator;
79663d1a8abSmrg
79763d1a8abSmrg /* The allocators' function used to know the actual size it
79863d1a8abSmrg allocated, for a certain allocation size requested. */
79963d1a8abSmrg line_map_round_alloc_size_func round_alloc_size;
80063d1a8abSmrg
80163d1a8abSmrg struct location_adhoc_data_map location_adhoc_data_map;
80263d1a8abSmrg
80363d1a8abSmrg /* The special location value that is used as spelling location for
80463d1a8abSmrg built-in tokens. */
8050fc04c29Smrg location_t builtin_location;
80663d1a8abSmrg
80763d1a8abSmrg /* True if we've seen a #line or # 44 "file" directive. */
80863d1a8abSmrg bool seen_line_directive;
80963d1a8abSmrg
81063d1a8abSmrg /* The default value of range_bits in ordinary line maps. */
81163d1a8abSmrg unsigned int default_range_bits;
81263d1a8abSmrg
81363d1a8abSmrg unsigned int num_optimized_ranges;
81463d1a8abSmrg unsigned int num_unoptimized_ranges;
81563d1a8abSmrg };
81663d1a8abSmrg
81763d1a8abSmrg /* Returns the number of allocated maps so far. MAP_KIND shall be TRUE
81863d1a8abSmrg if we are interested in macro maps, FALSE otherwise. */
81963d1a8abSmrg inline unsigned int
LINEMAPS_ALLOCATED(const line_maps * set,bool map_kind)82063d1a8abSmrg LINEMAPS_ALLOCATED (const line_maps *set, bool map_kind)
82163d1a8abSmrg {
82263d1a8abSmrg if (map_kind)
82363d1a8abSmrg return set->info_macro.allocated;
82463d1a8abSmrg else
82563d1a8abSmrg return set->info_ordinary.allocated;
82663d1a8abSmrg }
82763d1a8abSmrg
82863d1a8abSmrg /* As above, but by reference (e.g. as an lvalue). */
82963d1a8abSmrg
83063d1a8abSmrg inline unsigned int &
LINEMAPS_ALLOCATED(line_maps * set,bool map_kind)83163d1a8abSmrg LINEMAPS_ALLOCATED (line_maps *set, bool map_kind)
83263d1a8abSmrg {
83363d1a8abSmrg if (map_kind)
83463d1a8abSmrg return set->info_macro.allocated;
83563d1a8abSmrg else
83663d1a8abSmrg return set->info_ordinary.allocated;
83763d1a8abSmrg }
83863d1a8abSmrg
83963d1a8abSmrg /* Returns the number of used maps so far. MAP_KIND shall be TRUE if
84063d1a8abSmrg we are interested in macro maps, FALSE otherwise.*/
84163d1a8abSmrg inline unsigned int
LINEMAPS_USED(const line_maps * set,bool map_kind)84263d1a8abSmrg LINEMAPS_USED (const line_maps *set, bool map_kind)
84363d1a8abSmrg {
84463d1a8abSmrg if (map_kind)
84563d1a8abSmrg return set->info_macro.used;
84663d1a8abSmrg else
84763d1a8abSmrg return set->info_ordinary.used;
84863d1a8abSmrg }
84963d1a8abSmrg
85063d1a8abSmrg /* As above, but by reference (e.g. as an lvalue). */
85163d1a8abSmrg
85263d1a8abSmrg inline unsigned int &
LINEMAPS_USED(line_maps * set,bool map_kind)85363d1a8abSmrg LINEMAPS_USED (line_maps *set, bool map_kind)
85463d1a8abSmrg {
85563d1a8abSmrg if (map_kind)
85663d1a8abSmrg return set->info_macro.used;
85763d1a8abSmrg else
85863d1a8abSmrg return set->info_ordinary.used;
85963d1a8abSmrg }
86063d1a8abSmrg
86163d1a8abSmrg /* Returns the index of the last map that was looked up with
86263d1a8abSmrg linemap_lookup. MAP_KIND shall be TRUE if we are interested in
86363d1a8abSmrg macro maps, FALSE otherwise. */
86463d1a8abSmrg inline unsigned int &
LINEMAPS_CACHE(const line_maps * set,bool map_kind)865*ec02198aSmrg LINEMAPS_CACHE (const line_maps *set, bool map_kind)
86663d1a8abSmrg {
86763d1a8abSmrg if (map_kind)
86863d1a8abSmrg return set->info_macro.cache;
86963d1a8abSmrg else
87063d1a8abSmrg return set->info_ordinary.cache;
87163d1a8abSmrg }
87263d1a8abSmrg
87363d1a8abSmrg /* Return the map at a given index. */
87463d1a8abSmrg inline line_map *
LINEMAPS_MAP_AT(const line_maps * set,bool map_kind,int index)87563d1a8abSmrg LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, int index)
87663d1a8abSmrg {
87763d1a8abSmrg if (map_kind)
87863d1a8abSmrg return &set->info_macro.maps[index];
87963d1a8abSmrg else
88063d1a8abSmrg return &set->info_ordinary.maps[index];
88163d1a8abSmrg }
88263d1a8abSmrg
88363d1a8abSmrg /* Returns the last map used in the line table SET. MAP_KIND
88463d1a8abSmrg shall be TRUE if we are interested in macro maps, FALSE
88563d1a8abSmrg otherwise.*/
88663d1a8abSmrg inline line_map *
LINEMAPS_LAST_MAP(const line_maps * set,bool map_kind)88763d1a8abSmrg LINEMAPS_LAST_MAP (const line_maps *set, bool map_kind)
88863d1a8abSmrg {
88963d1a8abSmrg return LINEMAPS_MAP_AT (set, map_kind,
89063d1a8abSmrg LINEMAPS_USED (set, map_kind) - 1);
89163d1a8abSmrg }
89263d1a8abSmrg
89363d1a8abSmrg /* Returns the last map that was allocated in the line table SET.
89463d1a8abSmrg MAP_KIND shall be TRUE if we are interested in macro maps, FALSE
89563d1a8abSmrg otherwise.*/
89663d1a8abSmrg inline line_map *
LINEMAPS_LAST_ALLOCATED_MAP(const line_maps * set,bool map_kind)89763d1a8abSmrg LINEMAPS_LAST_ALLOCATED_MAP (const line_maps *set, bool map_kind)
89863d1a8abSmrg {
89963d1a8abSmrg return LINEMAPS_MAP_AT (set, map_kind,
90063d1a8abSmrg LINEMAPS_ALLOCATED (set, map_kind) - 1);
90163d1a8abSmrg }
90263d1a8abSmrg
90363d1a8abSmrg /* Returns a pointer to the memory region where ordinary maps are
90463d1a8abSmrg allocated in the line table SET. */
90563d1a8abSmrg inline line_map_ordinary *
LINEMAPS_ORDINARY_MAPS(const line_maps * set)90663d1a8abSmrg LINEMAPS_ORDINARY_MAPS (const line_maps *set)
90763d1a8abSmrg {
90863d1a8abSmrg return set->info_ordinary.maps;
90963d1a8abSmrg }
91063d1a8abSmrg
91163d1a8abSmrg /* Returns the INDEXth ordinary map. */
91263d1a8abSmrg inline line_map_ordinary *
LINEMAPS_ORDINARY_MAP_AT(const line_maps * set,int index)91363d1a8abSmrg LINEMAPS_ORDINARY_MAP_AT (const line_maps *set, int index)
91463d1a8abSmrg {
915*ec02198aSmrg linemap_assert (index >= 0
916*ec02198aSmrg && (unsigned int)index < LINEMAPS_USED (set, false));
917*ec02198aSmrg return (line_map_ordinary *)LINEMAPS_MAP_AT (set, false, index);
91863d1a8abSmrg }
91963d1a8abSmrg
92063d1a8abSmrg /* Return the number of ordinary maps allocated in the line table
92163d1a8abSmrg SET. */
92263d1a8abSmrg inline unsigned int
LINEMAPS_ORDINARY_ALLOCATED(const line_maps * set)92363d1a8abSmrg LINEMAPS_ORDINARY_ALLOCATED (const line_maps *set)
92463d1a8abSmrg {
92563d1a8abSmrg return LINEMAPS_ALLOCATED (set, false);
92663d1a8abSmrg }
92763d1a8abSmrg
92863d1a8abSmrg /* Return the number of ordinary maps used in the line table SET. */
92963d1a8abSmrg inline unsigned int
LINEMAPS_ORDINARY_USED(const line_maps * set)93063d1a8abSmrg LINEMAPS_ORDINARY_USED (const line_maps *set)
93163d1a8abSmrg {
93263d1a8abSmrg return LINEMAPS_USED (set, false);
93363d1a8abSmrg }
93463d1a8abSmrg
93563d1a8abSmrg /* Return the index of the last ordinary map that was looked up with
93663d1a8abSmrg linemap_lookup. */
93763d1a8abSmrg inline unsigned int &
LINEMAPS_ORDINARY_CACHE(const line_maps * set)938*ec02198aSmrg LINEMAPS_ORDINARY_CACHE (const line_maps *set)
93963d1a8abSmrg {
94063d1a8abSmrg return LINEMAPS_CACHE (set, false);
94163d1a8abSmrg }
94263d1a8abSmrg
94363d1a8abSmrg /* Returns a pointer to the last ordinary map used in the line table
94463d1a8abSmrg SET. */
94563d1a8abSmrg inline line_map_ordinary *
LINEMAPS_LAST_ORDINARY_MAP(const line_maps * set)94663d1a8abSmrg LINEMAPS_LAST_ORDINARY_MAP (const line_maps *set)
94763d1a8abSmrg {
94863d1a8abSmrg return (line_map_ordinary *)LINEMAPS_LAST_MAP (set, false);
94963d1a8abSmrg }
95063d1a8abSmrg
95163d1a8abSmrg /* Returns a pointer to the last ordinary map allocated the line table
95263d1a8abSmrg SET. */
95363d1a8abSmrg inline line_map_ordinary *
LINEMAPS_LAST_ALLOCATED_ORDINARY_MAP(const line_maps * set)95463d1a8abSmrg LINEMAPS_LAST_ALLOCATED_ORDINARY_MAP (const line_maps *set)
95563d1a8abSmrg {
95663d1a8abSmrg return (line_map_ordinary *)LINEMAPS_LAST_ALLOCATED_MAP (set, false);
95763d1a8abSmrg }
95863d1a8abSmrg
95963d1a8abSmrg /* Returns a pointer to the beginning of the region where macro maps
96063d1a8abSmrg are allocated. */
96163d1a8abSmrg inline line_map_macro *
LINEMAPS_MACRO_MAPS(const line_maps * set)96263d1a8abSmrg LINEMAPS_MACRO_MAPS (const line_maps *set)
96363d1a8abSmrg {
96463d1a8abSmrg return set->info_macro.maps;
96563d1a8abSmrg }
96663d1a8abSmrg
96763d1a8abSmrg /* Returns the INDEXth macro map. */
96863d1a8abSmrg inline line_map_macro *
LINEMAPS_MACRO_MAP_AT(const line_maps * set,int index)96963d1a8abSmrg LINEMAPS_MACRO_MAP_AT (const line_maps *set, int index)
97063d1a8abSmrg {
971*ec02198aSmrg linemap_assert (index >= 0
972*ec02198aSmrg && (unsigned int)index < LINEMAPS_USED (set, true));
973*ec02198aSmrg return (line_map_macro *)LINEMAPS_MAP_AT (set, true, index);
97463d1a8abSmrg }
97563d1a8abSmrg
97663d1a8abSmrg /* Returns the number of macro maps that were allocated in the line
97763d1a8abSmrg table SET. */
97863d1a8abSmrg inline unsigned int
LINEMAPS_MACRO_ALLOCATED(const line_maps * set)97963d1a8abSmrg LINEMAPS_MACRO_ALLOCATED (const line_maps *set)
98063d1a8abSmrg {
98163d1a8abSmrg return LINEMAPS_ALLOCATED (set, true);
98263d1a8abSmrg }
98363d1a8abSmrg
98463d1a8abSmrg /* Returns the number of macro maps used in the line table SET. */
98563d1a8abSmrg inline unsigned int
LINEMAPS_MACRO_USED(const line_maps * set)98663d1a8abSmrg LINEMAPS_MACRO_USED (const line_maps *set)
98763d1a8abSmrg {
98863d1a8abSmrg return LINEMAPS_USED (set, true);
98963d1a8abSmrg }
99063d1a8abSmrg
991*ec02198aSmrg /* Return the index of the last macro map that was looked up with
99263d1a8abSmrg linemap_lookup. */
99363d1a8abSmrg inline unsigned int &
LINEMAPS_MACRO_CACHE(const line_maps * set)994*ec02198aSmrg LINEMAPS_MACRO_CACHE (const line_maps *set)
99563d1a8abSmrg {
99663d1a8abSmrg return LINEMAPS_CACHE (set, true);
99763d1a8abSmrg }
99863d1a8abSmrg
99963d1a8abSmrg /* Returns the last macro map used in the line table SET. */
100063d1a8abSmrg inline line_map_macro *
LINEMAPS_LAST_MACRO_MAP(const line_maps * set)100163d1a8abSmrg LINEMAPS_LAST_MACRO_MAP (const line_maps *set)
100263d1a8abSmrg {
100363d1a8abSmrg return (line_map_macro *)LINEMAPS_LAST_MAP (set, true);
100463d1a8abSmrg }
100563d1a8abSmrg
100663d1a8abSmrg /* Returns the lowest location [of a token resulting from macro
100763d1a8abSmrg expansion] encoded in this line table. */
10080fc04c29Smrg inline location_t
LINEMAPS_MACRO_LOWEST_LOCATION(const line_maps * set)100963d1a8abSmrg LINEMAPS_MACRO_LOWEST_LOCATION (const line_maps *set)
101063d1a8abSmrg {
101163d1a8abSmrg return LINEMAPS_MACRO_USED (set)
101263d1a8abSmrg ? MAP_START_LOCATION (LINEMAPS_LAST_MACRO_MAP (set))
10130fc04c29Smrg : MAX_LOCATION_T + 1;
101463d1a8abSmrg }
101563d1a8abSmrg
101663d1a8abSmrg /* Returns the last macro map allocated in the line table SET. */
101763d1a8abSmrg inline line_map_macro *
LINEMAPS_LAST_ALLOCATED_MACRO_MAP(const line_maps * set)101863d1a8abSmrg LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set)
101963d1a8abSmrg {
102063d1a8abSmrg return (line_map_macro *)LINEMAPS_LAST_ALLOCATED_MAP (set, true);
102163d1a8abSmrg }
102263d1a8abSmrg
1023*ec02198aSmrg extern location_t get_combined_adhoc_loc (class line_maps *,
10240fc04c29Smrg location_t,
102563d1a8abSmrg source_range,
102663d1a8abSmrg void *);
1027*ec02198aSmrg extern void *get_data_from_adhoc_loc (const line_maps *, location_t);
1028*ec02198aSmrg extern location_t get_location_from_adhoc_loc (const line_maps *,
10290fc04c29Smrg location_t);
103063d1a8abSmrg
10310fc04c29Smrg extern source_range get_range_from_loc (line_maps *set, location_t loc);
103263d1a8abSmrg
103363d1a8abSmrg /* Get whether location LOC is a "pure" location, or
103463d1a8abSmrg whether it is an ad-hoc location, or embeds range information. */
103563d1a8abSmrg
103663d1a8abSmrg bool
10370fc04c29Smrg pure_location_p (line_maps *set, location_t loc);
103863d1a8abSmrg
103963d1a8abSmrg /* Given location LOC within SET, strip away any packed range information
104063d1a8abSmrg or ad-hoc information. */
104163d1a8abSmrg
10420fc04c29Smrg extern location_t get_pure_location (line_maps *set,
10430fc04c29Smrg location_t loc);
104463d1a8abSmrg
104563d1a8abSmrg /* Combine LOC and BLOCK, giving a combined adhoc location. */
104663d1a8abSmrg
10470fc04c29Smrg inline location_t
COMBINE_LOCATION_DATA(class line_maps * set,location_t loc,source_range src_range,void * block)1048*ec02198aSmrg COMBINE_LOCATION_DATA (class line_maps *set,
10490fc04c29Smrg location_t loc,
105063d1a8abSmrg source_range src_range,
105163d1a8abSmrg void *block)
105263d1a8abSmrg {
105363d1a8abSmrg return get_combined_adhoc_loc (set, loc, src_range, block);
105463d1a8abSmrg }
105563d1a8abSmrg
1056*ec02198aSmrg extern void rebuild_location_adhoc_htab (class line_maps *);
105763d1a8abSmrg
105863d1a8abSmrg /* Initialize a line map set. SET is the line map set to initialize
105963d1a8abSmrg and BUILTIN_LOCATION is the special location value to be used as
106063d1a8abSmrg spelling location for built-in tokens. This BUILTIN_LOCATION has
106163d1a8abSmrg to be strictly less than RESERVED_LOCATION_COUNT. */
1062*ec02198aSmrg extern void linemap_init (class line_maps *set,
10630fc04c29Smrg location_t builtin_location);
106463d1a8abSmrg
106563d1a8abSmrg /* Check for and warn about line_maps entered but not exited. */
106663d1a8abSmrg
1067*ec02198aSmrg extern void linemap_check_files_exited (class line_maps *);
106863d1a8abSmrg
10690fc04c29Smrg /* Return a location_t for the start (i.e. column==0) of
107063d1a8abSmrg (physical) line TO_LINE in the current source file (as in the
107163d1a8abSmrg most recent linemap_add). MAX_COLUMN_HINT is the highest column
107263d1a8abSmrg number we expect to use in this line (but it does not change
107363d1a8abSmrg the highest_location). */
107463d1a8abSmrg
10750fc04c29Smrg extern location_t linemap_line_start
1076*ec02198aSmrg (class line_maps *set, linenum_type to_line, unsigned int max_column_hint);
107763d1a8abSmrg
107863d1a8abSmrg /* Add a mapping of logical source line to physical source file and
107963d1a8abSmrg line number. This function creates an "ordinary map", which is a
108063d1a8abSmrg map that records locations of tokens that are not part of macro
108163d1a8abSmrg replacement-lists present at a macro expansion point.
108263d1a8abSmrg
108363d1a8abSmrg The text pointed to by TO_FILE must have a lifetime
108463d1a8abSmrg at least as long as the lifetime of SET. An empty
108563d1a8abSmrg TO_FILE means standard input. If reason is LC_LEAVE, and
108663d1a8abSmrg TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
108763d1a8abSmrg natural values considering the file we are returning to.
108863d1a8abSmrg
108963d1a8abSmrg A call to this function can relocate the previous set of
109063d1a8abSmrg maps, so any stored line_map pointers should not be used. */
1091*ec02198aSmrg extern const line_map *linemap_add
1092*ec02198aSmrg (class line_maps *, enum lc_reason, unsigned int sysp,
109363d1a8abSmrg const char *to_file, linenum_type to_line);
109463d1a8abSmrg
109563d1a8abSmrg /* Given a logical source location, returns the map which the
109663d1a8abSmrg corresponding (source file, line, column) triplet can be deduced
109763d1a8abSmrg from. Since the set is built chronologically, the logical lines are
109863d1a8abSmrg monotonic increasing, and so the list is sorted and we can use a
109963d1a8abSmrg binary search. If no line map have been allocated yet, this
110063d1a8abSmrg function returns NULL. */
1101*ec02198aSmrg extern const line_map *linemap_lookup
1102*ec02198aSmrg (const line_maps *, location_t);
110363d1a8abSmrg
110463d1a8abSmrg /* Returns TRUE if the line table set tracks token locations across
110563d1a8abSmrg macro expansion, FALSE otherwise. */
1106*ec02198aSmrg bool linemap_tracks_macro_expansion_locs_p (class line_maps *);
110763d1a8abSmrg
110863d1a8abSmrg /* Return the name of the macro associated to MACRO_MAP. */
110963d1a8abSmrg const char* linemap_map_get_macro_name (const line_map_macro *);
111063d1a8abSmrg
111163d1a8abSmrg /* Return a positive value if LOCATION is the locus of a token that is
111263d1a8abSmrg located in a system header, O otherwise. It returns 1 if LOCATION
111363d1a8abSmrg is the locus of a token that is located in a system header, and 2
111463d1a8abSmrg if LOCATION is the locus of a token located in a C system header
111563d1a8abSmrg that therefore needs to be extern "C" protected in C++.
111663d1a8abSmrg
111763d1a8abSmrg Note that this function returns 1 if LOCATION belongs to a token
111863d1a8abSmrg that is part of a macro replacement-list defined in a system
111963d1a8abSmrg header, but expanded in a non-system file. */
1120*ec02198aSmrg int linemap_location_in_system_header_p (class line_maps *,
11210fc04c29Smrg location_t);
112263d1a8abSmrg
112363d1a8abSmrg /* Return TRUE if LOCATION is a source code location of a token that is part of
112463d1a8abSmrg a macro expansion, FALSE otherwise. */
1125*ec02198aSmrg bool linemap_location_from_macro_expansion_p (const line_maps *,
11260fc04c29Smrg location_t);
112763d1a8abSmrg
112863d1a8abSmrg /* TRUE if LOCATION is a source code location of a token that is part of the
112963d1a8abSmrg definition of a macro, FALSE otherwise. */
1130*ec02198aSmrg bool linemap_location_from_macro_definition_p (class line_maps *,
11310fc04c29Smrg location_t);
113263d1a8abSmrg
113363d1a8abSmrg /* With the precondition that LOCATION is the locus of a token that is
113463d1a8abSmrg an argument of a function-like macro MACRO_MAP and appears in the
113563d1a8abSmrg expansion of MACRO_MAP, return the locus of that argument in the
113663d1a8abSmrg context of the caller of MACRO_MAP. */
113763d1a8abSmrg
11380fc04c29Smrg extern location_t linemap_macro_map_loc_unwind_toward_spelling
11390fc04c29Smrg (line_maps *set, const line_map_macro *macro_map, location_t location);
114063d1a8abSmrg
11410fc04c29Smrg /* location_t values from 0 to RESERVED_LOCATION_COUNT-1 will
114263d1a8abSmrg be reserved for libcpp user as special values, no token from libcpp
114363d1a8abSmrg will contain any of those locations. */
11440fc04c29Smrg const location_t RESERVED_LOCATION_COUNT = 2;
114563d1a8abSmrg
11460fc04c29Smrg /* Converts a map and a location_t to source line. */
114763d1a8abSmrg inline linenum_type
SOURCE_LINE(const line_map_ordinary * ord_map,location_t loc)11480fc04c29Smrg SOURCE_LINE (const line_map_ordinary *ord_map, location_t loc)
114963d1a8abSmrg {
115063d1a8abSmrg return ((loc - ord_map->start_location)
115163d1a8abSmrg >> ord_map->m_column_and_range_bits) + ord_map->to_line;
115263d1a8abSmrg }
115363d1a8abSmrg
11540fc04c29Smrg /* Convert a map and location_t to source column number. */
115563d1a8abSmrg inline linenum_type
SOURCE_COLUMN(const line_map_ordinary * ord_map,location_t loc)11560fc04c29Smrg SOURCE_COLUMN (const line_map_ordinary *ord_map, location_t loc)
115763d1a8abSmrg {
115863d1a8abSmrg return ((loc - ord_map->start_location)
115963d1a8abSmrg & ((1 << ord_map->m_column_and_range_bits) - 1)) >> ord_map->m_range_bits;
116063d1a8abSmrg }
116163d1a8abSmrg
11620fc04c29Smrg
11630fc04c29Smrg inline location_t
linemap_included_from(const line_map_ordinary * ord_map)11640fc04c29Smrg linemap_included_from (const line_map_ordinary *ord_map)
116563d1a8abSmrg {
11660fc04c29Smrg return ord_map->included_from;
116763d1a8abSmrg }
116863d1a8abSmrg
11690fc04c29Smrg /* The linemap containing the included-from location of MAP. */
11700fc04c29Smrg const line_map_ordinary *linemap_included_from_linemap
11710fc04c29Smrg (line_maps *set, const line_map_ordinary *map);
117263d1a8abSmrg
117363d1a8abSmrg /* True if the map is at the bottom of the include stack. */
117463d1a8abSmrg
117563d1a8abSmrg inline bool
MAIN_FILE_P(const line_map_ordinary * ord_map)117663d1a8abSmrg MAIN_FILE_P (const line_map_ordinary *ord_map)
117763d1a8abSmrg {
11780fc04c29Smrg return ord_map->included_from == 0;
117963d1a8abSmrg }
118063d1a8abSmrg
11810fc04c29Smrg /* Encode and return a location_t from a column number. The
118263d1a8abSmrg source line considered is the last source line used to call
118363d1a8abSmrg linemap_line_start, i.e, the last source line which a location was
118463d1a8abSmrg encoded from. */
11850fc04c29Smrg extern location_t
1186*ec02198aSmrg linemap_position_for_column (class line_maps *, unsigned int);
118763d1a8abSmrg
118863d1a8abSmrg /* Encode and return a source location from a given line and
118963d1a8abSmrg column. */
11900fc04c29Smrg location_t
119163d1a8abSmrg linemap_position_for_line_and_column (line_maps *set,
119263d1a8abSmrg const line_map_ordinary *,
119363d1a8abSmrg linenum_type, unsigned int);
119463d1a8abSmrg
11950fc04c29Smrg /* Encode and return a location_t starting from location LOC and
119663d1a8abSmrg shifting it by OFFSET columns. This function does not support
119763d1a8abSmrg virtual locations. */
11980fc04c29Smrg location_t
1199*ec02198aSmrg linemap_position_for_loc_and_offset (class line_maps *set,
12000fc04c29Smrg location_t loc,
120163d1a8abSmrg unsigned int offset);
120263d1a8abSmrg
120363d1a8abSmrg /* Return the file this map is for. */
120463d1a8abSmrg inline const char *
LINEMAP_FILE(const line_map_ordinary * ord_map)120563d1a8abSmrg LINEMAP_FILE (const line_map_ordinary *ord_map)
120663d1a8abSmrg {
120763d1a8abSmrg return ord_map->to_file;
120863d1a8abSmrg }
120963d1a8abSmrg
121063d1a8abSmrg /* Return the line number this map started encoding location from. */
121163d1a8abSmrg inline linenum_type
LINEMAP_LINE(const line_map_ordinary * ord_map)121263d1a8abSmrg LINEMAP_LINE (const line_map_ordinary *ord_map)
121363d1a8abSmrg {
121463d1a8abSmrg return ord_map->to_line;
121563d1a8abSmrg }
121663d1a8abSmrg
121763d1a8abSmrg /* Return a positive value if map encodes locations from a system
121863d1a8abSmrg header, 0 otherwise. Returns 1 if MAP encodes locations in a
121963d1a8abSmrg system header and 2 if it encodes locations in a C system header
122063d1a8abSmrg that therefore needs to be extern "C" protected in C++. */
122163d1a8abSmrg inline unsigned char
LINEMAP_SYSP(const line_map_ordinary * ord_map)122263d1a8abSmrg LINEMAP_SYSP (const line_map_ordinary *ord_map)
122363d1a8abSmrg {
122463d1a8abSmrg return ord_map->sysp;
122563d1a8abSmrg }
122663d1a8abSmrg
122763d1a8abSmrg /* Return a positive value if PRE denotes the location of a token that
122863d1a8abSmrg comes before the token of POST, 0 if PRE denotes the location of
122963d1a8abSmrg the same token as the token for POST, and a negative value
123063d1a8abSmrg otherwise. */
1231*ec02198aSmrg int linemap_compare_locations (class line_maps *set,
12320fc04c29Smrg location_t pre,
12330fc04c29Smrg location_t post);
123463d1a8abSmrg
123563d1a8abSmrg /* Return TRUE if LOC_A denotes the location a token that comes
123663d1a8abSmrg topogically before the token denoted by location LOC_B, or if they
123763d1a8abSmrg are equal. */
123863d1a8abSmrg inline bool
linemap_location_before_p(class line_maps * set,location_t loc_a,location_t loc_b)1239*ec02198aSmrg linemap_location_before_p (class line_maps *set,
12400fc04c29Smrg location_t loc_a,
12410fc04c29Smrg location_t loc_b)
124263d1a8abSmrg {
124363d1a8abSmrg return linemap_compare_locations (set, loc_a, loc_b) >= 0;
124463d1a8abSmrg }
124563d1a8abSmrg
124663d1a8abSmrg typedef struct
124763d1a8abSmrg {
124863d1a8abSmrg /* The name of the source file involved. */
124963d1a8abSmrg const char *file;
125063d1a8abSmrg
125163d1a8abSmrg /* The line-location in the source file. */
125263d1a8abSmrg int line;
125363d1a8abSmrg
125463d1a8abSmrg int column;
125563d1a8abSmrg
125663d1a8abSmrg void *data;
125763d1a8abSmrg
125863d1a8abSmrg /* In a system header?. */
125963d1a8abSmrg bool sysp;
126063d1a8abSmrg } expanded_location;
126163d1a8abSmrg
12620fc04c29Smrg class range_label;
126363d1a8abSmrg
12640fc04c29Smrg /* A hint to diagnostic_show_locus on how to print a source range within a
12650fc04c29Smrg rich_location.
126663d1a8abSmrg
12670fc04c29Smrg Typically this is SHOW_RANGE_WITH_CARET for the 0th range, and
12680fc04c29Smrg SHOW_RANGE_WITHOUT_CARET for subsequent ranges,
12690fc04c29Smrg but the Fortran frontend uses SHOW_RANGE_WITH_CARET repeatedly for
12700fc04c29Smrg printing things like:
127163d1a8abSmrg
127263d1a8abSmrg x = x + y
127363d1a8abSmrg 1 2
127463d1a8abSmrg Error: Shapes for operands at (1) and (2) are not conformable
127563d1a8abSmrg
127663d1a8abSmrg where "1" and "2" are notionally carets. */
12770fc04c29Smrg
12780fc04c29Smrg enum range_display_kind
12790fc04c29Smrg {
12800fc04c29Smrg /* Show the pertinent source line(s), the caret, and underline(s). */
12810fc04c29Smrg SHOW_RANGE_WITH_CARET,
12820fc04c29Smrg
12830fc04c29Smrg /* Show the pertinent source line(s) and underline(s), but don't
12840fc04c29Smrg show the caret (just an underline). */
12850fc04c29Smrg SHOW_RANGE_WITHOUT_CARET,
12860fc04c29Smrg
12870fc04c29Smrg /* Just show the source lines; don't show the range itself.
12880fc04c29Smrg This is for use when displaying some line-insertion fix-it hints (for
12890fc04c29Smrg showing the user context on the change, for when it doesn't make sense
12900fc04c29Smrg to highlight the first column on the next line). */
12910fc04c29Smrg SHOW_LINES_WITHOUT_RANGE
12920fc04c29Smrg };
12930fc04c29Smrg
12940fc04c29Smrg /* A location within a rich_location: a caret&range, with
12950fc04c29Smrg the caret potentially flagged for display, and an optional
12960fc04c29Smrg label. */
12970fc04c29Smrg
12980fc04c29Smrg struct location_range
12990fc04c29Smrg {
13000fc04c29Smrg location_t m_loc;
13010fc04c29Smrg
13020fc04c29Smrg enum range_display_kind m_range_display_kind;
13030fc04c29Smrg
13040fc04c29Smrg /* If non-NULL, the label for this range. */
13050fc04c29Smrg const range_label *m_label;
130663d1a8abSmrg };
130763d1a8abSmrg
130863d1a8abSmrg /* A partially-embedded vec for use within rich_location for storing
130963d1a8abSmrg ranges and fix-it hints.
131063d1a8abSmrg
131163d1a8abSmrg Elements [0..NUM_EMBEDDED) are allocated within m_embed, after
131263d1a8abSmrg that they are within the dynamically-allocated m_extra.
131363d1a8abSmrg
131463d1a8abSmrg This allows for static allocation in the common case, whilst
131563d1a8abSmrg supporting the rarer case of an arbitrary number of elements.
131663d1a8abSmrg
131763d1a8abSmrg Dynamic allocation is not performed unless it's needed. */
131863d1a8abSmrg
131963d1a8abSmrg template <typename T, int NUM_EMBEDDED>
132063d1a8abSmrg class semi_embedded_vec
132163d1a8abSmrg {
132263d1a8abSmrg public:
132363d1a8abSmrg semi_embedded_vec ();
132463d1a8abSmrg ~semi_embedded_vec ();
132563d1a8abSmrg
count()132663d1a8abSmrg unsigned int count () const { return m_num; }
132763d1a8abSmrg T& operator[] (int idx);
132863d1a8abSmrg const T& operator[] (int idx) const;
132963d1a8abSmrg
133063d1a8abSmrg void push (const T&);
133163d1a8abSmrg void truncate (int len);
133263d1a8abSmrg
133363d1a8abSmrg private:
133463d1a8abSmrg int m_num;
133563d1a8abSmrg T m_embedded[NUM_EMBEDDED];
133663d1a8abSmrg int m_alloc;
133763d1a8abSmrg T *m_extra;
133863d1a8abSmrg };
133963d1a8abSmrg
134063d1a8abSmrg /* Constructor for semi_embedded_vec. In particular, no dynamic allocation
134163d1a8abSmrg is done. */
134263d1a8abSmrg
134363d1a8abSmrg template <typename T, int NUM_EMBEDDED>
semi_embedded_vec()134463d1a8abSmrg semi_embedded_vec<T, NUM_EMBEDDED>::semi_embedded_vec ()
134563d1a8abSmrg : m_num (0), m_alloc (0), m_extra (NULL)
134663d1a8abSmrg {
134763d1a8abSmrg }
134863d1a8abSmrg
134963d1a8abSmrg /* semi_embedded_vec's dtor. Release any dynamically-allocated memory. */
135063d1a8abSmrg
135163d1a8abSmrg template <typename T, int NUM_EMBEDDED>
~semi_embedded_vec()135263d1a8abSmrg semi_embedded_vec<T, NUM_EMBEDDED>::~semi_embedded_vec ()
135363d1a8abSmrg {
135463d1a8abSmrg XDELETEVEC (m_extra);
135563d1a8abSmrg }
135663d1a8abSmrg
135763d1a8abSmrg /* Look up element IDX, mutably. */
135863d1a8abSmrg
135963d1a8abSmrg template <typename T, int NUM_EMBEDDED>
136063d1a8abSmrg T&
136163d1a8abSmrg semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx)
136263d1a8abSmrg {
136363d1a8abSmrg linemap_assert (idx < m_num);
136463d1a8abSmrg if (idx < NUM_EMBEDDED)
136563d1a8abSmrg return m_embedded[idx];
136663d1a8abSmrg else
136763d1a8abSmrg {
136863d1a8abSmrg linemap_assert (m_extra != NULL);
136963d1a8abSmrg return m_extra[idx - NUM_EMBEDDED];
137063d1a8abSmrg }
137163d1a8abSmrg }
137263d1a8abSmrg
137363d1a8abSmrg /* Look up element IDX (const). */
137463d1a8abSmrg
137563d1a8abSmrg template <typename T, int NUM_EMBEDDED>
137663d1a8abSmrg const T&
137763d1a8abSmrg semi_embedded_vec<T, NUM_EMBEDDED>::operator[] (int idx) const
137863d1a8abSmrg {
137963d1a8abSmrg linemap_assert (idx < m_num);
138063d1a8abSmrg if (idx < NUM_EMBEDDED)
138163d1a8abSmrg return m_embedded[idx];
138263d1a8abSmrg else
138363d1a8abSmrg {
138463d1a8abSmrg linemap_assert (m_extra != NULL);
138563d1a8abSmrg return m_extra[idx - NUM_EMBEDDED];
138663d1a8abSmrg }
138763d1a8abSmrg }
138863d1a8abSmrg
138963d1a8abSmrg /* Append VALUE to the end of the semi_embedded_vec. */
139063d1a8abSmrg
139163d1a8abSmrg template <typename T, int NUM_EMBEDDED>
139263d1a8abSmrg void
push(const T & value)139363d1a8abSmrg semi_embedded_vec<T, NUM_EMBEDDED>::push (const T& value)
139463d1a8abSmrg {
139563d1a8abSmrg int idx = m_num++;
139663d1a8abSmrg if (idx < NUM_EMBEDDED)
139763d1a8abSmrg m_embedded[idx] = value;
139863d1a8abSmrg else
139963d1a8abSmrg {
140063d1a8abSmrg /* Offset "idx" to be an index within m_extra. */
140163d1a8abSmrg idx -= NUM_EMBEDDED;
140263d1a8abSmrg if (NULL == m_extra)
140363d1a8abSmrg {
140463d1a8abSmrg linemap_assert (m_alloc == 0);
140563d1a8abSmrg m_alloc = 16;
140663d1a8abSmrg m_extra = XNEWVEC (T, m_alloc);
140763d1a8abSmrg }
140863d1a8abSmrg else if (idx >= m_alloc)
140963d1a8abSmrg {
141063d1a8abSmrg linemap_assert (m_alloc > 0);
141163d1a8abSmrg m_alloc *= 2;
141263d1a8abSmrg m_extra = XRESIZEVEC (T, m_extra, m_alloc);
141363d1a8abSmrg }
141463d1a8abSmrg linemap_assert (m_extra);
141563d1a8abSmrg linemap_assert (idx < m_alloc);
141663d1a8abSmrg m_extra[idx] = value;
141763d1a8abSmrg }
141863d1a8abSmrg }
141963d1a8abSmrg
142063d1a8abSmrg /* Truncate to length LEN. No deallocation is performed. */
142163d1a8abSmrg
142263d1a8abSmrg template <typename T, int NUM_EMBEDDED>
142363d1a8abSmrg void
truncate(int len)142463d1a8abSmrg semi_embedded_vec<T, NUM_EMBEDDED>::truncate (int len)
142563d1a8abSmrg {
142663d1a8abSmrg linemap_assert (len <= m_num);
142763d1a8abSmrg m_num = len;
142863d1a8abSmrg }
142963d1a8abSmrg
143063d1a8abSmrg class fixit_hint;
1431*ec02198aSmrg class diagnostic_path;
143263d1a8abSmrg
143363d1a8abSmrg /* A "rich" source code location, for use when printing diagnostics.
143463d1a8abSmrg A rich_location has one or more carets&ranges, where the carets
143563d1a8abSmrg are optional. These are referred to as "ranges" from here.
143663d1a8abSmrg Typically the zeroth range has a caret; other ranges sometimes
143763d1a8abSmrg have carets.
143863d1a8abSmrg
143963d1a8abSmrg The "primary" location of a rich_location is the caret of range 0,
144063d1a8abSmrg used for determining the line/column when printing diagnostic
144163d1a8abSmrg text, such as:
144263d1a8abSmrg
144363d1a8abSmrg some-file.c:3:1: error: ...etc...
144463d1a8abSmrg
144563d1a8abSmrg Additional ranges may be added to help the user identify other
144663d1a8abSmrg pertinent clauses in a diagnostic.
144763d1a8abSmrg
14480fc04c29Smrg Ranges can (optionally) be given labels via class range_label.
14490fc04c29Smrg
145063d1a8abSmrg rich_location instances are intended to be allocated on the stack
145163d1a8abSmrg when generating diagnostics, and to be short-lived.
145263d1a8abSmrg
145363d1a8abSmrg Examples of rich locations
145463d1a8abSmrg --------------------------
145563d1a8abSmrg
145663d1a8abSmrg Example A
145763d1a8abSmrg *********
145863d1a8abSmrg int i = "foo";
145963d1a8abSmrg ^
146063d1a8abSmrg This "rich" location is simply a single range (range 0), with
146163d1a8abSmrg caret = start = finish at the given point.
146263d1a8abSmrg
146363d1a8abSmrg Example B
146463d1a8abSmrg *********
146563d1a8abSmrg a = (foo && bar)
146663d1a8abSmrg ~~~~~^~~~~~~
146763d1a8abSmrg This rich location has a single range (range 0), with the caret
146863d1a8abSmrg at the first "&", and the start/finish at the parentheses.
146963d1a8abSmrg Compare with example C below.
147063d1a8abSmrg
147163d1a8abSmrg Example C
147263d1a8abSmrg *********
147363d1a8abSmrg a = (foo && bar)
147463d1a8abSmrg ~~~ ^~ ~~~
147563d1a8abSmrg This rich location has three ranges:
147663d1a8abSmrg - Range 0 has its caret and start location at the first "&" and
147763d1a8abSmrg end at the second "&.
147863d1a8abSmrg - Range 1 has its start and finish at the "f" and "o" of "foo";
147963d1a8abSmrg the caret is not flagged for display, but is perhaps at the "f"
148063d1a8abSmrg of "foo".
148163d1a8abSmrg - Similarly, range 2 has its start and finish at the "b" and "r" of
148263d1a8abSmrg "bar"; the caret is not flagged for display, but is perhaps at the
148363d1a8abSmrg "b" of "bar".
148463d1a8abSmrg Compare with example B above.
148563d1a8abSmrg
148663d1a8abSmrg Example D (Fortran frontend)
148763d1a8abSmrg ****************************
148863d1a8abSmrg x = x + y
148963d1a8abSmrg 1 2
149063d1a8abSmrg This rich location has range 0 at "1", and range 1 at "2".
149163d1a8abSmrg Both are flagged for caret display. Both ranges have start/finish
149263d1a8abSmrg equal to their caret point. The frontend overrides the diagnostic
149363d1a8abSmrg context's default caret character for these ranges.
149463d1a8abSmrg
14950fc04c29Smrg Example E (range labels)
14960fc04c29Smrg ************************
149763d1a8abSmrg printf ("arg0: %i arg1: %s arg2: %i",
149863d1a8abSmrg ^~
14990fc04c29Smrg |
15000fc04c29Smrg const char *
150163d1a8abSmrg 100, 101, 102);
150263d1a8abSmrg ~~~
15030fc04c29Smrg |
15040fc04c29Smrg int
150563d1a8abSmrg This rich location has two ranges:
150663d1a8abSmrg - range 0 is at the "%s" with start = caret = "%" and finish at
15070fc04c29Smrg the "s". It has a range_label ("const char *").
150863d1a8abSmrg - range 1 has start/finish covering the "101" and is not flagged for
15090fc04c29Smrg caret printing. The caret is at the start of "101", where its
15100fc04c29Smrg range_label is printed ("int").
151163d1a8abSmrg
151263d1a8abSmrg Fix-it hints
151363d1a8abSmrg ------------
151463d1a8abSmrg
151563d1a8abSmrg Rich locations can also contain "fix-it hints", giving suggestions
151663d1a8abSmrg for the user on how to edit their code to fix a problem. These
151763d1a8abSmrg can be expressed as insertions, replacements, and removals of text.
151863d1a8abSmrg The edits by default are relative to the zeroth range within the
151963d1a8abSmrg rich_location, but optionally they can be expressed relative to
152063d1a8abSmrg other locations (using various overloaded methods of the form
152163d1a8abSmrg rich_location::add_fixit_*).
152263d1a8abSmrg
152363d1a8abSmrg For example:
152463d1a8abSmrg
152563d1a8abSmrg Example F: fix-it hint: insert_before
152663d1a8abSmrg *************************************
152763d1a8abSmrg ptr = arr[0];
152863d1a8abSmrg ^~~~~~
152963d1a8abSmrg &
153063d1a8abSmrg This rich location has a single range (range 0) covering "arr[0]",
153163d1a8abSmrg with the caret at the start. The rich location has a single
153263d1a8abSmrg insertion fix-it hint, inserted before range 0, added via
153363d1a8abSmrg richloc.add_fixit_insert_before ("&");
153463d1a8abSmrg
153563d1a8abSmrg Example G: multiple fix-it hints: insert_before and insert_after
153663d1a8abSmrg ****************************************************************
153763d1a8abSmrg #define FN(ARG0, ARG1, ARG2) fn(ARG0, ARG1, ARG2)
153863d1a8abSmrg ^~~~ ^~~~ ^~~~
153963d1a8abSmrg ( ) ( ) ( )
154063d1a8abSmrg This rich location has three ranges, covering "arg0", "arg1",
154163d1a8abSmrg and "arg2", all with caret-printing enabled.
154263d1a8abSmrg The rich location has 6 insertion fix-it hints: each arg
154363d1a8abSmrg has a pair of insertion fix-it hints, suggesting wrapping
154463d1a8abSmrg them with parentheses: one a '(' inserted before,
154563d1a8abSmrg the other a ')' inserted after, added via
154663d1a8abSmrg richloc.add_fixit_insert_before (LOC, "(");
154763d1a8abSmrg and
154863d1a8abSmrg richloc.add_fixit_insert_after (LOC, ")");
154963d1a8abSmrg
155063d1a8abSmrg Example H: fix-it hint: removal
155163d1a8abSmrg *******************************
155263d1a8abSmrg struct s {int i};;
155363d1a8abSmrg ^
155463d1a8abSmrg -
155563d1a8abSmrg This rich location has a single range at the stray trailing
155663d1a8abSmrg semicolon, along with a single removal fix-it hint, covering
155763d1a8abSmrg the same range, added via:
155863d1a8abSmrg richloc.add_fixit_remove ();
155963d1a8abSmrg
156063d1a8abSmrg Example I: fix-it hint: replace
156163d1a8abSmrg *******************************
156263d1a8abSmrg c = s.colour;
156363d1a8abSmrg ^~~~~~
156463d1a8abSmrg color
156563d1a8abSmrg This rich location has a single range (range 0) covering "colour",
156663d1a8abSmrg and a single "replace" fix-it hint, covering the same range,
156763d1a8abSmrg added via
156863d1a8abSmrg richloc.add_fixit_replace ("color");
156963d1a8abSmrg
15700fc04c29Smrg Example J: fix-it hint: line insertion
15710fc04c29Smrg **************************************
15720fc04c29Smrg
15730fc04c29Smrg 3 | #include <stddef.h>
15740fc04c29Smrg + |+#include <stdio.h>
15750fc04c29Smrg 4 | int the_next_line;
15760fc04c29Smrg
15770fc04c29Smrg This rich location has a single range at line 4 column 1, marked
15780fc04c29Smrg with SHOW_LINES_WITHOUT_RANGE (to avoid printing a meaningless caret
15790fc04c29Smrg on the "i" of int). It has a insertion fix-it hint of the string
15800fc04c29Smrg "#include <stdio.h>\n".
15810fc04c29Smrg
158263d1a8abSmrg Adding a fix-it hint can fail: for example, attempts to insert content
158363d1a8abSmrg at the transition between two line maps may fail due to there being no
15840fc04c29Smrg location_t value to express the new location.
158563d1a8abSmrg
158663d1a8abSmrg Attempts to add a fix-it hint within a macro expansion will fail.
158763d1a8abSmrg
1588c7a68eb7Smrg There is only limited support for newline characters in fix-it hints:
1589c7a68eb7Smrg only hints with newlines which insert an entire new line are permitted,
1590c7a68eb7Smrg inserting at the start of a line, and finishing with a newline
1591c7a68eb7Smrg (with no interior newline characters). Other attempts to add
1592c7a68eb7Smrg fix-it hints containing newline characters will fail.
1593c7a68eb7Smrg Similarly, attempts to delete or replace a range *affecting* multiple
1594c7a68eb7Smrg lines will fail.
159563d1a8abSmrg
159663d1a8abSmrg The rich_location API handles these failures gracefully, so that
159763d1a8abSmrg diagnostics can attempt to add fix-it hints without each needing
159863d1a8abSmrg extensive checking.
159963d1a8abSmrg
160063d1a8abSmrg Fix-it hints within a rich_location are "atomic": if any hints can't
160163d1a8abSmrg be applied, none of them will be (tracked by the m_seen_impossible_fixit
160263d1a8abSmrg flag), and no fix-its hints will be displayed for that rich_location.
160363d1a8abSmrg This implies that diagnostic messages need to be worded in such a way
160463d1a8abSmrg that they make sense whether or not the fix-it hints are displayed,
160563d1a8abSmrg or that richloc.seen_impossible_fixit_p () should be checked before
160663d1a8abSmrg issuing the diagnostics. */
160763d1a8abSmrg
160863d1a8abSmrg class rich_location
160963d1a8abSmrg {
161063d1a8abSmrg public:
161163d1a8abSmrg /* Constructors. */
161263d1a8abSmrg
161363d1a8abSmrg /* Constructing from a location. */
16140fc04c29Smrg rich_location (line_maps *set, location_t loc,
16150fc04c29Smrg const range_label *label = NULL);
161663d1a8abSmrg
161763d1a8abSmrg /* Destructor. */
161863d1a8abSmrg ~rich_location ();
161963d1a8abSmrg
162063d1a8abSmrg /* Accessors. */
get_loc()16210fc04c29Smrg location_t get_loc () const { return get_loc (0); }
16220fc04c29Smrg location_t get_loc (unsigned int idx) const;
162363d1a8abSmrg
162463d1a8abSmrg void
16250fc04c29Smrg add_range (location_t loc,
16260fc04c29Smrg enum range_display_kind range_display_kind
16270fc04c29Smrg = SHOW_RANGE_WITHOUT_CARET,
16280fc04c29Smrg const range_label *label = NULL);
162963d1a8abSmrg
163063d1a8abSmrg void
16310fc04c29Smrg set_range (unsigned int idx, location_t loc,
16320fc04c29Smrg enum range_display_kind range_display_kind);
163363d1a8abSmrg
get_num_locations()163463d1a8abSmrg unsigned int get_num_locations () const { return m_ranges.count (); }
163563d1a8abSmrg
163663d1a8abSmrg const location_range *get_range (unsigned int idx) const;
163763d1a8abSmrg location_range *get_range (unsigned int idx);
163863d1a8abSmrg
163963d1a8abSmrg expanded_location get_expanded_location (unsigned int idx);
164063d1a8abSmrg
164163d1a8abSmrg void
164263d1a8abSmrg override_column (int column);
164363d1a8abSmrg
164463d1a8abSmrg /* Fix-it hints. */
164563d1a8abSmrg
164663d1a8abSmrg /* Methods for adding insertion fix-it hints. */
164763d1a8abSmrg
164863d1a8abSmrg /* Suggest inserting NEW_CONTENT immediately before the primary
164963d1a8abSmrg range's start. */
165063d1a8abSmrg void
165163d1a8abSmrg add_fixit_insert_before (const char *new_content);
165263d1a8abSmrg
165363d1a8abSmrg /* Suggest inserting NEW_CONTENT immediately before the start of WHERE. */
165463d1a8abSmrg void
16550fc04c29Smrg add_fixit_insert_before (location_t where,
165663d1a8abSmrg const char *new_content);
165763d1a8abSmrg
165863d1a8abSmrg /* Suggest inserting NEW_CONTENT immediately after the end of the primary
165963d1a8abSmrg range. */
166063d1a8abSmrg void
166163d1a8abSmrg add_fixit_insert_after (const char *new_content);
166263d1a8abSmrg
166363d1a8abSmrg /* Suggest inserting NEW_CONTENT immediately after the end of WHERE. */
166463d1a8abSmrg void
16650fc04c29Smrg add_fixit_insert_after (location_t where,
166663d1a8abSmrg const char *new_content);
166763d1a8abSmrg
166863d1a8abSmrg /* Methods for adding removal fix-it hints. */
166963d1a8abSmrg
167063d1a8abSmrg /* Suggest removing the content covered by range 0. */
167163d1a8abSmrg void
167263d1a8abSmrg add_fixit_remove ();
167363d1a8abSmrg
167463d1a8abSmrg /* Suggest removing the content covered between the start and finish
167563d1a8abSmrg of WHERE. */
167663d1a8abSmrg void
16770fc04c29Smrg add_fixit_remove (location_t where);
167863d1a8abSmrg
167963d1a8abSmrg /* Suggest removing the content covered by SRC_RANGE. */
168063d1a8abSmrg void
168163d1a8abSmrg add_fixit_remove (source_range src_range);
168263d1a8abSmrg
168363d1a8abSmrg /* Methods for adding "replace" fix-it hints. */
168463d1a8abSmrg
168563d1a8abSmrg /* Suggest replacing the content covered by range 0 with NEW_CONTENT. */
168663d1a8abSmrg void
168763d1a8abSmrg add_fixit_replace (const char *new_content);
168863d1a8abSmrg
168963d1a8abSmrg /* Suggest replacing the content between the start and finish of
169063d1a8abSmrg WHERE with NEW_CONTENT. */
169163d1a8abSmrg void
16920fc04c29Smrg add_fixit_replace (location_t where,
169363d1a8abSmrg const char *new_content);
169463d1a8abSmrg
169563d1a8abSmrg /* Suggest replacing the content covered by SRC_RANGE with
169663d1a8abSmrg NEW_CONTENT. */
169763d1a8abSmrg void
169863d1a8abSmrg add_fixit_replace (source_range src_range,
169963d1a8abSmrg const char *new_content);
170063d1a8abSmrg
get_num_fixit_hints()170163d1a8abSmrg unsigned int get_num_fixit_hints () const { return m_fixit_hints.count (); }
get_fixit_hint(int idx)170263d1a8abSmrg fixit_hint *get_fixit_hint (int idx) const { return m_fixit_hints[idx]; }
170363d1a8abSmrg fixit_hint *get_last_fixit_hint () const;
seen_impossible_fixit_p()170463d1a8abSmrg bool seen_impossible_fixit_p () const { return m_seen_impossible_fixit; }
170563d1a8abSmrg
1706c7a68eb7Smrg /* Set this if the fix-it hints are not suitable to be
1707c7a68eb7Smrg automatically applied.
1708c7a68eb7Smrg
1709c7a68eb7Smrg For example, if you are suggesting more than one
1710c7a68eb7Smrg mutually exclusive solution to a problem, then
1711c7a68eb7Smrg it doesn't make sense to apply all of the solutions;
1712c7a68eb7Smrg manual intervention is required.
1713c7a68eb7Smrg
1714c7a68eb7Smrg If set, then the fix-it hints in the rich_location will
1715c7a68eb7Smrg be printed, but will not be added to generated patches,
1716c7a68eb7Smrg or affect the modified version of the file. */
fixits_cannot_be_auto_applied()1717c7a68eb7Smrg void fixits_cannot_be_auto_applied ()
1718c7a68eb7Smrg {
1719c7a68eb7Smrg m_fixits_cannot_be_auto_applied = true;
1720c7a68eb7Smrg }
1721c7a68eb7Smrg
fixits_can_be_auto_applied_p()1722c7a68eb7Smrg bool fixits_can_be_auto_applied_p () const
1723c7a68eb7Smrg {
1724c7a68eb7Smrg return !m_fixits_cannot_be_auto_applied;
1725c7a68eb7Smrg }
1726c7a68eb7Smrg
1727*ec02198aSmrg /* An optional path through the code. */
get_path()1728*ec02198aSmrg const diagnostic_path *get_path () const { return m_path; }
set_path(const diagnostic_path * path)1729*ec02198aSmrg void set_path (const diagnostic_path *path) { m_path = path; }
1730*ec02198aSmrg
173163d1a8abSmrg private:
17320fc04c29Smrg bool reject_impossible_fixit (location_t where);
173363d1a8abSmrg void stop_supporting_fixits ();
17340fc04c29Smrg void maybe_add_fixit (location_t start,
17350fc04c29Smrg location_t next_loc,
1736c7a68eb7Smrg const char *new_content);
173763d1a8abSmrg
173863d1a8abSmrg public:
173963d1a8abSmrg static const int STATICALLY_ALLOCATED_RANGES = 3;
174063d1a8abSmrg
174163d1a8abSmrg protected:
174263d1a8abSmrg line_maps *m_line_table;
174363d1a8abSmrg semi_embedded_vec <location_range, STATICALLY_ALLOCATED_RANGES> m_ranges;
174463d1a8abSmrg
174563d1a8abSmrg int m_column_override;
174663d1a8abSmrg
174763d1a8abSmrg bool m_have_expanded_location;
174863d1a8abSmrg expanded_location m_expanded_location;
174963d1a8abSmrg
175063d1a8abSmrg static const int MAX_STATIC_FIXIT_HINTS = 2;
175163d1a8abSmrg semi_embedded_vec <fixit_hint *, MAX_STATIC_FIXIT_HINTS> m_fixit_hints;
175263d1a8abSmrg
175363d1a8abSmrg bool m_seen_impossible_fixit;
1754c7a68eb7Smrg bool m_fixits_cannot_be_auto_applied;
1755*ec02198aSmrg
1756*ec02198aSmrg const diagnostic_path *m_path;
175763d1a8abSmrg };
175863d1a8abSmrg
17590fc04c29Smrg /* A struct for the result of range_label::get_text: a NUL-terminated buffer
17600fc04c29Smrg of localized text, and a flag to determine if the caller should "free" the
17610fc04c29Smrg buffer. */
17620fc04c29Smrg
1763*ec02198aSmrg class label_text
17640fc04c29Smrg {
1765*ec02198aSmrg public:
label_text()17660fc04c29Smrg label_text ()
17670fc04c29Smrg : m_buffer (NULL), m_caller_owned (false)
17680fc04c29Smrg {}
17690fc04c29Smrg
maybe_free()17700fc04c29Smrg void maybe_free ()
17710fc04c29Smrg {
17720fc04c29Smrg if (m_caller_owned)
17730fc04c29Smrg free (m_buffer);
17740fc04c29Smrg }
17750fc04c29Smrg
1776*ec02198aSmrg /* Create a label_text instance that borrows BUFFER from a
1777*ec02198aSmrg longer-lived owner. */
borrow(const char * buffer)1778*ec02198aSmrg static label_text borrow (const char *buffer)
1779*ec02198aSmrg {
1780*ec02198aSmrg return label_text (const_cast <char *> (buffer), false);
1781*ec02198aSmrg }
1782*ec02198aSmrg
1783*ec02198aSmrg /* Create a label_text instance that takes ownership of BUFFER. */
take(char * buffer)1784*ec02198aSmrg static label_text take (char *buffer)
1785*ec02198aSmrg {
1786*ec02198aSmrg return label_text (buffer, true);
1787*ec02198aSmrg }
1788*ec02198aSmrg
1789*ec02198aSmrg /* Take ownership of the buffer, copying if necessary. */
take_or_copy()1790*ec02198aSmrg char *take_or_copy ()
1791*ec02198aSmrg {
1792*ec02198aSmrg if (m_caller_owned)
1793*ec02198aSmrg return m_buffer;
1794*ec02198aSmrg else
1795*ec02198aSmrg return xstrdup (m_buffer);
1796*ec02198aSmrg }
1797*ec02198aSmrg
17980fc04c29Smrg char *m_buffer;
17990fc04c29Smrg bool m_caller_owned;
1800*ec02198aSmrg
1801*ec02198aSmrg private:
label_text(char * buffer,bool owned)1802*ec02198aSmrg label_text (char *buffer, bool owned)
1803*ec02198aSmrg : m_buffer (buffer), m_caller_owned (owned)
1804*ec02198aSmrg {}
18050fc04c29Smrg };
18060fc04c29Smrg
18070fc04c29Smrg /* Abstract base class for labelling a range within a rich_location
18080fc04c29Smrg (e.g. for labelling expressions with their type).
18090fc04c29Smrg
18100fc04c29Smrg Generating the text could require non-trivial work, so this work
18110fc04c29Smrg is delayed (via the "get_text" virtual function) until the diagnostic
18120fc04c29Smrg printing code "knows" it needs it, thus avoiding doing it e.g. for
18130fc04c29Smrg warnings that are filtered by command-line flags. This virtual
18140fc04c29Smrg function also isolates libcpp and the diagnostics subsystem from
18150fc04c29Smrg the front-end and middle-end-specific code for generating the text
18160fc04c29Smrg for the labels.
18170fc04c29Smrg
18180fc04c29Smrg Like the rich_location instances they annotate, range_label instances
18190fc04c29Smrg are intended to be allocated on the stack when generating diagnostics,
18200fc04c29Smrg and to be short-lived. */
18210fc04c29Smrg
18220fc04c29Smrg class range_label
18230fc04c29Smrg {
18240fc04c29Smrg public:
~range_label()18250fc04c29Smrg virtual ~range_label () {}
18260fc04c29Smrg
18270fc04c29Smrg /* Get localized text for the label.
18280fc04c29Smrg The RANGE_IDX is provided, allowing for range_label instances to be
18290fc04c29Smrg shared by multiple ranges if need be (the "flyweight" design pattern). */
18300fc04c29Smrg virtual label_text get_text (unsigned range_idx) const = 0;
18310fc04c29Smrg };
18320fc04c29Smrg
1833c7a68eb7Smrg /* A fix-it hint: a suggested insertion, replacement, or deletion of text.
1834c7a68eb7Smrg We handle these three types of edit with one class, by representing
1835c7a68eb7Smrg them as replacement of a half-open range:
1836c7a68eb7Smrg [start, next_loc)
1837c7a68eb7Smrg Insertions have start == next_loc: "replace" the empty string at the
1838c7a68eb7Smrg start location with the new string.
1839c7a68eb7Smrg Deletions are replacement with the empty string.
1840c7a68eb7Smrg
1841c7a68eb7Smrg There is only limited support for newline characters in fix-it hints
1842c7a68eb7Smrg as noted above in the comment for class rich_location.
1843c7a68eb7Smrg A fixit_hint instance can have at most one newline character; if
1844c7a68eb7Smrg present, the newline character must be the final character of
1845c7a68eb7Smrg the content (preventing e.g. fix-its that split a pre-existing line). */
1846c7a68eb7Smrg
184763d1a8abSmrg class fixit_hint
184863d1a8abSmrg {
184963d1a8abSmrg public:
18500fc04c29Smrg fixit_hint (location_t start,
18510fc04c29Smrg location_t next_loc,
185263d1a8abSmrg const char *new_content);
~fixit_hint()1853c7a68eb7Smrg ~fixit_hint () { free (m_bytes); }
1854c7a68eb7Smrg
185563d1a8abSmrg bool affects_line_p (const char *file, int line) const;
get_start_loc()18560fc04c29Smrg location_t get_start_loc () const { return m_start; }
get_next_loc()18570fc04c29Smrg location_t get_next_loc () const { return m_next_loc; }
18580fc04c29Smrg bool maybe_append (location_t start,
18590fc04c29Smrg location_t next_loc,
186063d1a8abSmrg const char *new_content);
186163d1a8abSmrg
get_string()186263d1a8abSmrg const char *get_string () const { return m_bytes; }
get_length()186363d1a8abSmrg size_t get_length () const { return m_len; }
186463d1a8abSmrg
insertion_p()1865c7a68eb7Smrg bool insertion_p () const { return m_start == m_next_loc; }
186663d1a8abSmrg
1867c7a68eb7Smrg bool ends_with_newline_p () const;
186863d1a8abSmrg
186963d1a8abSmrg private:
1870c7a68eb7Smrg /* We don't use source_range here since, unlike most places,
1871c7a68eb7Smrg this is a half-open/half-closed range:
1872c7a68eb7Smrg [start, next_loc)
1873c7a68eb7Smrg so that we can support insertion via start == next_loc. */
18740fc04c29Smrg location_t m_start;
18750fc04c29Smrg location_t m_next_loc;
187663d1a8abSmrg char *m_bytes;
187763d1a8abSmrg size_t m_len;
187863d1a8abSmrg };
187963d1a8abSmrg
188063d1a8abSmrg
188163d1a8abSmrg /* This is enum is used by the function linemap_resolve_location
188263d1a8abSmrg below. The meaning of the values is explained in the comment of
188363d1a8abSmrg that function. */
188463d1a8abSmrg enum location_resolution_kind
188563d1a8abSmrg {
188663d1a8abSmrg LRK_MACRO_EXPANSION_POINT,
188763d1a8abSmrg LRK_SPELLING_LOCATION,
188863d1a8abSmrg LRK_MACRO_DEFINITION_LOCATION
188963d1a8abSmrg };
189063d1a8abSmrg
189163d1a8abSmrg /* Resolve a virtual location into either a spelling location, an
189263d1a8abSmrg expansion point location or a token argument replacement point
189363d1a8abSmrg location. Return the map that encodes the virtual location as well
189463d1a8abSmrg as the resolved location.
189563d1a8abSmrg
189663d1a8abSmrg If LOC is *NOT* the location of a token resulting from the
189763d1a8abSmrg expansion of a macro, then the parameter LRK (which stands for
189863d1a8abSmrg Location Resolution Kind) is ignored and the resulting location
189963d1a8abSmrg just equals the one given in argument.
190063d1a8abSmrg
190163d1a8abSmrg Now if LOC *IS* the location of a token resulting from the
190263d1a8abSmrg expansion of a macro, this is what happens.
190363d1a8abSmrg
190463d1a8abSmrg * If LRK is set to LRK_MACRO_EXPANSION_POINT
190563d1a8abSmrg -------------------------------
190663d1a8abSmrg
190763d1a8abSmrg The virtual location is resolved to the first macro expansion point
190863d1a8abSmrg that led to this macro expansion.
190963d1a8abSmrg
191063d1a8abSmrg * If LRK is set to LRK_SPELLING_LOCATION
191163d1a8abSmrg -------------------------------------
191263d1a8abSmrg
191363d1a8abSmrg The virtual location is resolved to the locus where the token has
191463d1a8abSmrg been spelled in the source. This can follow through all the macro
191563d1a8abSmrg expansions that led to the token.
191663d1a8abSmrg
191763d1a8abSmrg * If LRK is set to LRK_MACRO_DEFINITION_LOCATION
191863d1a8abSmrg --------------------------------------
191963d1a8abSmrg
192063d1a8abSmrg The virtual location is resolved to the locus of the token in the
192163d1a8abSmrg context of the macro definition.
192263d1a8abSmrg
192363d1a8abSmrg If LOC is the locus of a token that is an argument of a
192463d1a8abSmrg function-like macro [replacing a parameter in the replacement list
192563d1a8abSmrg of the macro] the virtual location is resolved to the locus of the
192663d1a8abSmrg parameter that is replaced, in the context of the definition of the
192763d1a8abSmrg macro.
192863d1a8abSmrg
192963d1a8abSmrg If LOC is the locus of a token that is not an argument of a
193063d1a8abSmrg function-like macro, then the function behaves as if LRK was set to
193163d1a8abSmrg LRK_SPELLING_LOCATION.
193263d1a8abSmrg
193363d1a8abSmrg If LOC_MAP is not NULL, *LOC_MAP is set to the map encoding the
193463d1a8abSmrg returned location. Note that if the returned location wasn't originally
193563d1a8abSmrg encoded by a map, the *MAP is set to NULL. This can happen if LOC
193663d1a8abSmrg resolves to a location reserved for the client code, like
193763d1a8abSmrg UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
193863d1a8abSmrg
1939*ec02198aSmrg location_t linemap_resolve_location (class line_maps *,
19400fc04c29Smrg location_t loc,
194163d1a8abSmrg enum location_resolution_kind lrk,
194263d1a8abSmrg const line_map_ordinary **loc_map);
194363d1a8abSmrg
194463d1a8abSmrg /* Suppose that LOC is the virtual location of a token coming from the
194563d1a8abSmrg expansion of a macro M. This function then steps up to get the
194663d1a8abSmrg location L of the point where M got expanded. If L is a spelling
194763d1a8abSmrg location inside a macro expansion M', then this function returns
194863d1a8abSmrg the point where M' was expanded. LOC_MAP is an output parameter.
194963d1a8abSmrg When non-NULL, *LOC_MAP is set to the map of the returned
195063d1a8abSmrg location. */
1951*ec02198aSmrg location_t linemap_unwind_toward_expansion (class line_maps *,
19520fc04c29Smrg location_t loc,
1953*ec02198aSmrg const line_map **loc_map);
195463d1a8abSmrg
195563d1a8abSmrg /* If LOC is the virtual location of a token coming from the expansion
195663d1a8abSmrg of a macro M and if its spelling location is reserved (e.g, a
195763d1a8abSmrg location for a built-in token), then this function unwinds (using
195863d1a8abSmrg linemap_unwind_toward_expansion) the location until a location that
195963d1a8abSmrg is not reserved and is not in a system header is reached. In other
196063d1a8abSmrg words, this unwinds the reserved location until a location that is
196163d1a8abSmrg in real source code is reached.
196263d1a8abSmrg
196363d1a8abSmrg Otherwise, if the spelling location for LOC is not reserved or if
196463d1a8abSmrg LOC doesn't come from the expansion of a macro, the function
196563d1a8abSmrg returns LOC as is and *MAP is not touched.
196663d1a8abSmrg
196763d1a8abSmrg *MAP is set to the map of the returned location if the later is
196863d1a8abSmrg different from LOC. */
1969*ec02198aSmrg location_t linemap_unwind_to_first_non_reserved_loc (class line_maps *,
19700fc04c29Smrg location_t loc,
1971*ec02198aSmrg const line_map **map);
197263d1a8abSmrg
197363d1a8abSmrg /* Expand source code location LOC and return a user readable source
197463d1a8abSmrg code location. LOC must be a spelling (non-virtual) location. If
197563d1a8abSmrg it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
197663d1a8abSmrg location is returned. */
1977*ec02198aSmrg expanded_location linemap_expand_location (class line_maps *,
1978*ec02198aSmrg const line_map *,
19790fc04c29Smrg location_t loc);
198063d1a8abSmrg
198163d1a8abSmrg /* Statistics about maps allocation and usage as returned by
198263d1a8abSmrg linemap_get_statistics. */
198363d1a8abSmrg struct linemap_stats
198463d1a8abSmrg {
198563d1a8abSmrg long num_ordinary_maps_allocated;
198663d1a8abSmrg long num_ordinary_maps_used;
198763d1a8abSmrg long ordinary_maps_allocated_size;
198863d1a8abSmrg long ordinary_maps_used_size;
198963d1a8abSmrg long num_expanded_macros;
199063d1a8abSmrg long num_macro_tokens;
199163d1a8abSmrg long num_macro_maps_used;
199263d1a8abSmrg long macro_maps_allocated_size;
199363d1a8abSmrg long macro_maps_used_size;
199463d1a8abSmrg long macro_maps_locations_size;
199563d1a8abSmrg long duplicated_macro_maps_locations_size;
199663d1a8abSmrg long adhoc_table_size;
199763d1a8abSmrg long adhoc_table_entries_used;
199863d1a8abSmrg };
199963d1a8abSmrg
200063d1a8abSmrg /* Return the highest location emitted for a given file for which
200163d1a8abSmrg there is a line map in SET. FILE_NAME is the file name to
200263d1a8abSmrg consider. If the function returns TRUE, *LOC is set to the highest
200363d1a8abSmrg location emitted for that file. */
2004*ec02198aSmrg bool linemap_get_file_highest_location (class line_maps * set,
200563d1a8abSmrg const char *file_name,
20060fc04c29Smrg location_t *loc);
200763d1a8abSmrg
200863d1a8abSmrg /* Compute and return statistics about the memory consumption of some
200963d1a8abSmrg parts of the line table SET. */
2010*ec02198aSmrg void linemap_get_statistics (line_maps *, struct linemap_stats *);
201163d1a8abSmrg
201263d1a8abSmrg /* Dump debugging information about source location LOC into the file
201363d1a8abSmrg stream STREAM. SET is the line map set LOC comes from. */
2014*ec02198aSmrg void linemap_dump_location (line_maps *, location_t, FILE *);
201563d1a8abSmrg
201663d1a8abSmrg /* Dump line map at index IX in line table SET to STREAM. If STREAM
201763d1a8abSmrg is NULL, use stderr. IS_MACRO is true if the caller wants to
201863d1a8abSmrg dump a macro map, false otherwise. */
2019*ec02198aSmrg void linemap_dump (FILE *, line_maps *, unsigned, bool);
202063d1a8abSmrg
202163d1a8abSmrg /* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
202263d1a8abSmrg NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
202363d1a8abSmrg specifies how many macro maps to dump. */
2024*ec02198aSmrg void line_table_dump (FILE *, line_maps *, unsigned int, unsigned int);
202563d1a8abSmrg
20260fc04c29Smrg /* An enum for distinguishing the various parts within a location_t. */
2027c7a68eb7Smrg
2028c7a68eb7Smrg enum location_aspect
2029c7a68eb7Smrg {
2030c7a68eb7Smrg LOCATION_ASPECT_CARET,
2031c7a68eb7Smrg LOCATION_ASPECT_START,
2032c7a68eb7Smrg LOCATION_ASPECT_FINISH
2033c7a68eb7Smrg };
2034c7a68eb7Smrg
20350fc04c29Smrg /* The rich_location class requires a way to expand location_t instances.
203663d1a8abSmrg We would directly use expand_location_to_spelling_point, which is
203763d1a8abSmrg implemented in gcc/input.c, but we also need to use it for rich_location
203863d1a8abSmrg within genmatch.c.
203963d1a8abSmrg Hence we require client code of libcpp to implement the following
204063d1a8abSmrg symbol. */
204163d1a8abSmrg extern expanded_location
20420fc04c29Smrg linemap_client_expand_location_to_spelling_point (location_t,
2043c7a68eb7Smrg enum location_aspect);
204463d1a8abSmrg
204563d1a8abSmrg #endif /* !LIBCPP_LINE_MAP_H */
2046