1169695Skan/* Map logical line numbers to (source file, line number) pairs.
2169695Skan   Copyright (C) 2001, 2003, 2004
3169695Skan   Free Software Foundation, Inc.
4169695Skan
5169695SkanThis program is free software; you can redistribute it and/or modify it
6169695Skanunder the terms of the GNU General Public License as published by the
7169695SkanFree Software Foundation; either version 2, or (at your option) any
8169695Skanlater version.
9169695Skan
10169695SkanThis program is distributed in the hope that it will be useful,
11169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
12169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13169695SkanGNU General Public License for more details.
14169695Skan
15169695SkanYou should have received a copy of the GNU General Public License
16169695Skanalong with this program; if not, write to the Free Software
17169695SkanFoundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18169695Skan
19169695Skan In other words, you are welcome to use, share and improve this program.
20169695Skan You are forbidden to forbid anyone else to use, share and improve
21169695Skan what you give them.   Help stamp out software-hoarding!  */
22169695Skan
23169695Skan#ifndef LIBCPP_LINE_MAP_H
24169695Skan#define LIBCPP_LINE_MAP_H
25169695Skan
26169695Skan/* Reason for adding a line change with add_line_map ().  LC_ENTER is
27169695Skan   when including a new file, e.g. a #include directive in C.
28169695Skan   LC_LEAVE is when reaching a file's end.  LC_RENAME is when a file
29169695Skan   name or line number changes for neither of the above reasons
30169695Skan   (e.g. a #line directive in C).  */
31169695Skanenum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
32169695Skan
33169695Skan/* A logical line/column number, i.e. an "index" into a line_map.  */
34169695Skan/* Long-term, we want to use this to replace struct location_s (in input.h),
35169695Skan   and effectively typedef source_location location_t.  */
36169695Skantypedef unsigned int source_location;
37169695Skan
38169695Skan/* Physical source file TO_FILE at line TO_LINE at column 0 is represented
39169695Skan   by the logical START_LOCATION.  TO_LINE+L at column C is represented by
40169695Skan   START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits),
41169695Skan   and the result_location is less than the next line_map's start_location.
42169695Skan   (The top line is line 1 and the leftmost column is column 1; line/column 0
43169695Skan   means "entire file/line" or "unknown line/column" or "not applicable".)
44169695Skan   INCLUDED_FROM is an index into the set that gives the line mapping
45169695Skan   at whose end the current one was included.  File(s) at the bottom
46169695Skan   of the include stack have this set to -1.  REASON is the reason for
47169695Skan   creation of this line map, SYSP is one for a system header, two for
48169695Skan   a C system header file that therefore needs to be extern "C"
49169695Skan   protected in C++, and zero otherwise.  */
50169695Skanstruct line_map
51169695Skan{
52169695Skan  const char *to_file;
53169695Skan  unsigned int to_line;
54169695Skan  source_location start_location;
55169695Skan  int included_from;
56169695Skan  ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
57169695Skan  /* The sysp field isn't really needed now that it's in cpp_buffer.  */
58169695Skan  unsigned char sysp;
59169695Skan  /* Number of the low-order source_location bits used for a column number.  */
60169695Skan  unsigned int column_bits : 8;
61169695Skan};
62169695Skan
63169695Skan/* A set of chronological line_map structures.  */
64169695Skanstruct line_maps
65169695Skan{
66169695Skan  struct line_map *maps;
67169695Skan  unsigned int allocated;
68169695Skan  unsigned int used;
69169695Skan
70169695Skan  unsigned int cache;
71169695Skan
72169695Skan  /* The most recently listed include stack, if any, starts with
73169695Skan     LAST_LISTED as the topmost including file.  -1 indicates nothing
74169695Skan     has been listed yet.  */
75169695Skan  int last_listed;
76169695Skan
77169695Skan  /* Depth of the include stack, including the current file.  */
78169695Skan  unsigned int depth;
79169695Skan
80169695Skan  /* If true, prints an include trace a la -H.  */
81169695Skan  bool trace_includes;
82169695Skan
83169695Skan  /* Highest source_location "given out".  */
84169695Skan  source_location highest_location;
85169695Skan
86169695Skan  /* Start of line of highest source_location "given out".  */
87169695Skan  source_location highest_line;
88169695Skan
89169695Skan  /* The maximum column number we can quickly allocate.  Higher numbers
90169695Skan     may require allocating a new line_map.  */
91169695Skan  unsigned int max_column_hint;
92169695Skan};
93169695Skan
94169695Skan/* Initialize a line map set.  */
95169695Skanextern void linemap_init (struct line_maps *);
96169695Skan
97169695Skan/* Free a line map set.  */
98169695Skanextern void linemap_free (struct line_maps *);
99169695Skan
100169695Skan/* Check for and warn about line_maps entered but not exited.  */
101169695Skan
102169695Skanextern void linemap_check_files_exited (struct line_maps *);
103169695Skan
104169695Skan/* Return a source_location for the start (i.e. column==0) of
105169695Skan   (physical) line TO_LINE in the current source file (as in the
106169695Skan   most recent linemap_add).   MAX_COLUMN_HINT is the highest column
107169695Skan   number we expect to use in this line (but it does not change
108169695Skan   the highest_location).  */
109169695Skan
110169695Skanextern source_location linemap_line_start
111169695Skan(struct line_maps *set, unsigned int to_line,  unsigned int max_column_hint);
112169695Skan
113169695Skan/* Add a mapping of logical source line to physical source file and
114169695Skan   line number.
115169695Skan
116169695Skan   The text pointed to by TO_FILE must have a lifetime
117169695Skan   at least as long as the final call to lookup_line ().  An empty
118169695Skan   TO_FILE means standard input.  If reason is LC_LEAVE, and
119169695Skan   TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
120169695Skan   natural values considering the file we are returning to.
121169695Skan
122169695Skan   A call to this function can relocate the previous set of
123169695Skan   maps, so any stored line_map pointers should not be used.  */
124169695Skanextern const struct line_map *linemap_add
125169695Skan  (struct line_maps *, enum lc_reason, unsigned int sysp,
126169695Skan   const char *to_file, unsigned int to_line);
127169695Skan
128169695Skan/* Given a logical line, returns the map from which the corresponding
129169695Skan   (source file, line) pair can be deduced.  */
130169695Skanextern const struct line_map *linemap_lookup
131169695Skan  (struct line_maps *, source_location);
132169695Skan
133169695Skan/* Print the file names and line numbers of the #include commands
134169695Skan   which led to the map MAP, if any, to stderr.  Nothing is output if
135169695Skan   the most recently listed stack is the same as the current one.  */
136169695Skanextern void linemap_print_containing_files (struct line_maps *,
137169695Skan					    const struct line_map *);
138169695Skan
139169695Skan/* Converts a map and a source_location to source line.  */
140169695Skan#define SOURCE_LINE(MAP, LINE) \
141169695Skan  ((((LINE) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line)
142169695Skan
143169695Skan#define SOURCE_COLUMN(MAP, LINE) \
144169695Skan  (((LINE) - (MAP)->start_location) & ((1 << (MAP)->column_bits) - 1))
145169695Skan
146169695Skan/* Returns the last source line within a map.  This is the (last) line
147169695Skan   of the #include, or other directive, that caused a map change.  */
148169695Skan#define LAST_SOURCE_LINE(MAP) \
149169695Skan  SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP))
150169695Skan#define LAST_SOURCE_LINE_LOCATION(MAP) \
151169695Skan  ((((MAP)[1].start_location - 1 - (MAP)->start_location) \
152169695Skan    & ~((1 << (MAP)->column_bits) - 1))			  \
153169695Skan   + (MAP)->start_location)
154169695Skan
155169695Skan/* Returns the map a given map was included from.  */
156169695Skan#define INCLUDED_FROM(SET, MAP) (&(SET)->maps[(MAP)->included_from])
157169695Skan
158169695Skan/* Nonzero if the map is at the bottom of the include stack.  */
159169695Skan#define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
160169695Skan
161169695Skan/* Set LOC to a source position that is the same line as the most recent
162169695Skan   linemap_line_start, but with the specified TO_COLUMN column number.  */
163169695Skan
164169695Skan#define LINEMAP_POSITION_FOR_COLUMN(LOC, SET, TO_COLUMN) { \
165169695Skan  unsigned int to_column = (TO_COLUMN); \
166169695Skan  struct line_maps *set = (SET); \
167169695Skan  if (__builtin_expect (to_column >= set->max_column_hint, 0)) \
168169695Skan    (LOC) = linemap_position_for_column (set, to_column); \
169169695Skan  else { \
170169695Skan    source_location r = set->highest_line; \
171169695Skan    r = r + to_column; \
172169695Skan    if (r >= set->highest_location) \
173169695Skan      set->highest_location = r; \
174169695Skan    (LOC) = r;			 \
175169695Skan  }}
176169695Skan
177169695Skan
178169695Skanextern source_location
179169695Skanlinemap_position_for_column (struct line_maps *set, unsigned int to_column);
180169695Skan#endif /* !LIBCPP_LINE_MAP_H  */
181