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