xref: /openbsd-src/gnu/gcc/libcpp/include/line-map.h (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
1*404b540aSrobert /* Map logical line numbers to (source file, line number) pairs.
2*404b540aSrobert    Copyright (C) 2001, 2003, 2004
3*404b540aSrobert    Free Software Foundation, Inc.
4*404b540aSrobert 
5*404b540aSrobert This program is free software; you can redistribute it and/or modify it
6*404b540aSrobert under the terms of the GNU General Public License as published by the
7*404b540aSrobert Free Software Foundation; either version 2, or (at your option) any
8*404b540aSrobert later version.
9*404b540aSrobert 
10*404b540aSrobert This program is distributed in the hope that it will be useful,
11*404b540aSrobert but WITHOUT ANY WARRANTY; without even the implied warranty of
12*404b540aSrobert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*404b540aSrobert GNU General Public License for more details.
14*404b540aSrobert 
15*404b540aSrobert You should have received a copy of the GNU General Public License
16*404b540aSrobert along with this program; if not, write to the Free Software
17*404b540aSrobert Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18*404b540aSrobert 
19*404b540aSrobert  In other words, you are welcome to use, share and improve this program.
20*404b540aSrobert  You are forbidden to forbid anyone else to use, share and improve
21*404b540aSrobert  what you give them.   Help stamp out software-hoarding!  */
22*404b540aSrobert 
23*404b540aSrobert #ifndef LIBCPP_LINE_MAP_H
24*404b540aSrobert #define LIBCPP_LINE_MAP_H
25*404b540aSrobert 
26*404b540aSrobert /* Reason for adding a line change with add_line_map ().  LC_ENTER is
27*404b540aSrobert    when including a new file, e.g. a #include directive in C.
28*404b540aSrobert    LC_LEAVE is when reaching a file's end.  LC_RENAME is when a file
29*404b540aSrobert    name or line number changes for neither of the above reasons
30*404b540aSrobert    (e.g. a #line directive in C).  */
31*404b540aSrobert enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
32*404b540aSrobert 
33*404b540aSrobert /* A logical line/column number, i.e. an "index" into a line_map.  */
34*404b540aSrobert /* Long-term, we want to use this to replace struct location_s (in input.h),
35*404b540aSrobert    and effectively typedef source_location location_t.  */
36*404b540aSrobert typedef unsigned int source_location;
37*404b540aSrobert 
38*404b540aSrobert /* Physical source file TO_FILE at line TO_LINE at column 0 is represented
39*404b540aSrobert    by the logical START_LOCATION.  TO_LINE+L at column C is represented by
40*404b540aSrobert    START_LOCATION+(L*(1<<column_bits))+C, as long as C<(1<<column_bits),
41*404b540aSrobert    and the result_location is less than the next line_map's start_location.
42*404b540aSrobert    (The top line is line 1 and the leftmost column is column 1; line/column 0
43*404b540aSrobert    means "entire file/line" or "unknown line/column" or "not applicable".)
44*404b540aSrobert    INCLUDED_FROM is an index into the set that gives the line mapping
45*404b540aSrobert    at whose end the current one was included.  File(s) at the bottom
46*404b540aSrobert    of the include stack have this set to -1.  REASON is the reason for
47*404b540aSrobert    creation of this line map, SYSP is one for a system header, two for
48*404b540aSrobert    a C system header file that therefore needs to be extern "C"
49*404b540aSrobert    protected in C++, and zero otherwise.  */
50*404b540aSrobert struct line_map
51*404b540aSrobert {
52*404b540aSrobert   const char *to_file;
53*404b540aSrobert   unsigned int to_line;
54*404b540aSrobert   source_location start_location;
55*404b540aSrobert   int included_from;
56*404b540aSrobert   ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
57*404b540aSrobert   /* The sysp field isn't really needed now that it's in cpp_buffer.  */
58*404b540aSrobert   unsigned char sysp;
59*404b540aSrobert   /* Number of the low-order source_location bits used for a column number.  */
60*404b540aSrobert   unsigned int column_bits : 8;
61*404b540aSrobert };
62*404b540aSrobert 
63*404b540aSrobert /* A set of chronological line_map structures.  */
64*404b540aSrobert struct line_maps
65*404b540aSrobert {
66*404b540aSrobert   struct line_map *maps;
67*404b540aSrobert   unsigned int allocated;
68*404b540aSrobert   unsigned int used;
69*404b540aSrobert 
70*404b540aSrobert   unsigned int cache;
71*404b540aSrobert 
72*404b540aSrobert   /* The most recently listed include stack, if any, starts with
73*404b540aSrobert      LAST_LISTED as the topmost including file.  -1 indicates nothing
74*404b540aSrobert      has been listed yet.  */
75*404b540aSrobert   int last_listed;
76*404b540aSrobert 
77*404b540aSrobert   /* Depth of the include stack, including the current file.  */
78*404b540aSrobert   unsigned int depth;
79*404b540aSrobert 
80*404b540aSrobert   /* If true, prints an include trace a la -H.  */
81*404b540aSrobert   bool trace_includes;
82*404b540aSrobert 
83*404b540aSrobert   /* Highest source_location "given out".  */
84*404b540aSrobert   source_location highest_location;
85*404b540aSrobert 
86*404b540aSrobert   /* Start of line of highest source_location "given out".  */
87*404b540aSrobert   source_location highest_line;
88*404b540aSrobert 
89*404b540aSrobert   /* The maximum column number we can quickly allocate.  Higher numbers
90*404b540aSrobert      may require allocating a new line_map.  */
91*404b540aSrobert   unsigned int max_column_hint;
92*404b540aSrobert };
93*404b540aSrobert 
94*404b540aSrobert /* Initialize a line map set.  */
95*404b540aSrobert extern void linemap_init (struct line_maps *);
96*404b540aSrobert 
97*404b540aSrobert /* Free a line map set.  */
98*404b540aSrobert extern void linemap_free (struct line_maps *);
99*404b540aSrobert 
100*404b540aSrobert /* Check for and warn about line_maps entered but not exited.  */
101*404b540aSrobert 
102*404b540aSrobert extern void linemap_check_files_exited (struct line_maps *);
103*404b540aSrobert 
104*404b540aSrobert /* Return a source_location for the start (i.e. column==0) of
105*404b540aSrobert    (physical) line TO_LINE in the current source file (as in the
106*404b540aSrobert    most recent linemap_add).   MAX_COLUMN_HINT is the highest column
107*404b540aSrobert    number we expect to use in this line (but it does not change
108*404b540aSrobert    the highest_location).  */
109*404b540aSrobert 
110*404b540aSrobert extern source_location linemap_line_start
111*404b540aSrobert (struct line_maps *set, unsigned int to_line,  unsigned int max_column_hint);
112*404b540aSrobert 
113*404b540aSrobert /* Add a mapping of logical source line to physical source file and
114*404b540aSrobert    line number.
115*404b540aSrobert 
116*404b540aSrobert    The text pointed to by TO_FILE must have a lifetime
117*404b540aSrobert    at least as long as the final call to lookup_line ().  An empty
118*404b540aSrobert    TO_FILE means standard input.  If reason is LC_LEAVE, and
119*404b540aSrobert    TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
120*404b540aSrobert    natural values considering the file we are returning to.
121*404b540aSrobert 
122*404b540aSrobert    A call to this function can relocate the previous set of
123*404b540aSrobert    maps, so any stored line_map pointers should not be used.  */
124*404b540aSrobert extern const struct line_map *linemap_add
125*404b540aSrobert   (struct line_maps *, enum lc_reason, unsigned int sysp,
126*404b540aSrobert    const char *to_file, unsigned int to_line);
127*404b540aSrobert 
128*404b540aSrobert /* Given a logical line, returns the map from which the corresponding
129*404b540aSrobert    (source file, line) pair can be deduced.  */
130*404b540aSrobert extern const struct line_map *linemap_lookup
131*404b540aSrobert   (struct line_maps *, source_location);
132*404b540aSrobert 
133*404b540aSrobert /* Print the file names and line numbers of the #include commands
134*404b540aSrobert    which led to the map MAP, if any, to stderr.  Nothing is output if
135*404b540aSrobert    the most recently listed stack is the same as the current one.  */
136*404b540aSrobert extern void linemap_print_containing_files (struct line_maps *,
137*404b540aSrobert 					    const struct line_map *);
138*404b540aSrobert 
139*404b540aSrobert /* Converts a map and a source_location to source line.  */
140*404b540aSrobert #define SOURCE_LINE(MAP, LINE) \
141*404b540aSrobert   ((((LINE) - (MAP)->start_location) >> (MAP)->column_bits) + (MAP)->to_line)
142*404b540aSrobert 
143*404b540aSrobert #define SOURCE_COLUMN(MAP, LINE) \
144*404b540aSrobert   (((LINE) - (MAP)->start_location) & ((1 << (MAP)->column_bits) - 1))
145*404b540aSrobert 
146*404b540aSrobert /* Returns the last source line within a map.  This is the (last) line
147*404b540aSrobert    of the #include, or other directive, that caused a map change.  */
148*404b540aSrobert #define LAST_SOURCE_LINE(MAP) \
149*404b540aSrobert   SOURCE_LINE (MAP, LAST_SOURCE_LINE_LOCATION (MAP))
150*404b540aSrobert #define LAST_SOURCE_LINE_LOCATION(MAP) \
151*404b540aSrobert   ((((MAP)[1].start_location - 1 - (MAP)->start_location) \
152*404b540aSrobert     & ~((1 << (MAP)->column_bits) - 1))			  \
153*404b540aSrobert    + (MAP)->start_location)
154*404b540aSrobert 
155*404b540aSrobert /* Returns the map a given map was included from.  */
156*404b540aSrobert #define INCLUDED_FROM(SET, MAP) (&(SET)->maps[(MAP)->included_from])
157*404b540aSrobert 
158*404b540aSrobert /* Nonzero if the map is at the bottom of the include stack.  */
159*404b540aSrobert #define MAIN_FILE_P(MAP) ((MAP)->included_from < 0)
160*404b540aSrobert 
161*404b540aSrobert /* Set LOC to a source position that is the same line as the most recent
162*404b540aSrobert    linemap_line_start, but with the specified TO_COLUMN column number.  */
163*404b540aSrobert 
164*404b540aSrobert #define LINEMAP_POSITION_FOR_COLUMN(LOC, SET, TO_COLUMN) { \
165*404b540aSrobert   unsigned int to_column = (TO_COLUMN); \
166*404b540aSrobert   struct line_maps *set = (SET); \
167*404b540aSrobert   if (__builtin_expect (to_column >= set->max_column_hint, 0)) \
168*404b540aSrobert     (LOC) = linemap_position_for_column (set, to_column); \
169*404b540aSrobert   else { \
170*404b540aSrobert     source_location r = set->highest_line; \
171*404b540aSrobert     r = r + to_column; \
172*404b540aSrobert     if (r >= set->highest_location) \
173*404b540aSrobert       set->highest_location = r; \
174*404b540aSrobert     (LOC) = r;			 \
175*404b540aSrobert   }}
176*404b540aSrobert 
177*404b540aSrobert 
178*404b540aSrobert extern source_location
179*404b540aSrobert linemap_position_for_column (struct line_maps *set, unsigned int to_column);
180*404b540aSrobert #endif /* !LIBCPP_LINE_MAP_H  */
181