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